SagerNet / sing-box

The universal proxy platform
https://sing-box.sagernet.org/
Other
18.52k stars 2.22k forks source link

prefer_ipv4不起作用 #932

Closed chowyuan1314 closed 11 months ago

chowyuan1314 commented 11 months ago

操作系统

Windows

系统版本

Windows11

安装类型

sing-box 原始命令行程序

如果您使用图形客户端程序,请提供该程序版本。

No response

版本

sing-box version 1.5.0-rc.5

Environment: go1.21.1 windows/amd64 Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_ech,with_utls,with_reality_server,with_clash_api Revision: 8311cf112d5d8d211f6b13f2d6e71e27f0e4629a CGO: disabled

描述

重开#929

重现方式

详见#929

日志

详见#929

dyhkwong commented 11 months ago

prefer 控制的是 sing-box dns 自身的行为,浏览器等自己有 prefer 机制的软件拿到 A 和 AAAA 记录后如何 prefer 是软件自己的选择。除非返回空 AAAA 记录,你无法阻止软件 prefer IPv6 进行连接。

chowyuan1314 commented 11 months ago

如果是这样的话,那么只使用tun模式的话,似乎没办法根据是否有ipv6网络来自动适配了,只能把tun.inet6_address删除?我发现在iOS上只使用tun模式的话,像微信、头条只要检测到有ipv6地址,就会强制使用ipv6来连接,但实际可能外部网络并没有ipv6,仅仅是tun分配了ipv6地址,这也会导致头条、微信无法连接。

nekohasekai commented 11 months ago

请转而使用 fake-ip。如果要在普通 tun 透明代理下实现 prefer IPv4,需要三大更改:

  1. 建立代理连接前不得完成原始连接握手(流量探测无法使用,并且增加 1 RTT 的延迟)
  2. 需要 tun 在 IPv6 连接失败后返回 ICMP unreadable (只有 gVisor stack 可能实现)
  3. 需要代理协议支持(目前只有 socks 的响应规定了不支持 IPv6 的错误代码)
Odyssey-2061 commented 4 months ago

如果是这样的话,那么只使用tun模式的话,似乎没办法根据是否有ipv6网络来自动适配了,只能把tun.inet6_address删除?我发现在iOS上只使用tun模式的话,像微信、头条只要检测到有ipv6地址,就会强制使用ipv6来连接,但实际可能外部网络并没有ipv6,仅仅是tun分配了ipv6地址,这也会导致头条、微信无法连接。

我遇到了类似的问题,只设置了tun.inet4_address没设置tun.inet6_address,但微信依然坚持连接ipv6,导致无法连接。 暂时可用的解决方法: tun里增加 "sniff_override_destination": true字段,这样的话微信虽然依旧请求ipv6访问,但至少可以正常用了

hackenfu commented 3 months ago

如果是这样的话,那么只使用tun模式的话,似乎没办法根据是否有ipv6网络来自动适配了,只能把tun.inet6_address删除?我发现在iOS上只使用tun模式的话,像微信、头条只要检测到有ipv6地址,就会强制使用ipv6来连接,但实际可能外部网络并没有ipv6,仅仅是tun分配了ipv6地址,这也会导致头条、微信无法连接。

我遇到了类似的问题,只设置了tun.inet4_address没设置tun.inet6_address,但微信依然坚持连接ipv6,导致无法连接。 暂时可用的解决方法: tun里增加 "sniff_override_destination": true字段,这样的话微信虽然依旧请求ipv6访问,但至少可以正常用了

按照https://github.com/SagerNet/sing-box/issues/1410 说的,经过测试,删除inet6_address;把dns.strategy改成ipv4_only就会正常, 的确起作用了

xyseer commented 3 months ago

However it's still a big problem. I suppose that in tun make sing-box announce an interface with viable ipv6. Most of Chinese app, like Wechat, would prefer ipv6. Then the ipv6 requests were sent into sing-box route and finally routed to direct outbound. Now if your network does not support ipv6, they will fail and return no response until timeout. I believe that blames to the tun part of sing-box. Maybe we need a detecting action before initializing a tun interface.

可是这还是个大问题。我推测tun中的inet6_address使得sing-box声明了一个具有ipv6能力的网络接口。绝大多数的中国软件,比如微信,会优先ipv6。然后请求会以ipv6的形式发到sing-box然后路由到直连出口,如果此时你的网络不支持ipv6,就会失败最后超时。我觉得这是sing-box tun部分的锅。或许我们在启动tun网卡之前需要一个检测动作。

Odyssey-2061 commented 3 months ago

However it's still a big problem. I suppose that in tun make sing-box announce an interface with viable ipv6. Most of Chinese app, like Wechat, would prefer ipv6. Then the ipv6 requests were sent into sing-box route and finally routed to direct outbound. Now if your network does not support ipv6, they will fail and return no response until timeout. I believe that blames to the tun part of sing-box. Maybe we need a detecting action before initializing a tun interface.

可是这还是个大问题。我推测tun中的inet6_address使得sing-box声明了一个具有ipv6能力的网络接口。绝大多数的中国软件,比如微信,会优先ipv6。然后请求会以ipv6的形式发到sing-box然后路由到直连出口,如果此时你的网络不支持ipv6,就会失败最后超时。我觉得这是sing-box tun部分的锅。或许我们在启动tun网卡之前需要一个检测动作。

my temporary solution: "sniff_override_destination": true Then WeChat will successfully have internet despite still sends ipv6 request.

xyseer commented 3 months ago

However it's still a big problem. I suppose that in tun make sing-box announce an interface with viable ipv6. Most of Chinese app, like Wechat, would prefer ipv6. Then the ipv6 requests were sent into sing-box route and finally routed to direct outbound. Now if your network does not support ipv6, they will fail and return no response until timeout. I believe that blames to the tun part of sing-box. Maybe we need a detecting action before initializing a tun interface. 可是这还是个大问题。我推测tun中的inet6_address使得sing-box声明了一个具有ipv6能力的网络接口。绝大多数的中国软件,比如微信,会优先ipv6。然后请求会以ipv6的形式发到sing-box然后路由到直连出口,如果此时你的网络不支持ipv6,就会失败最后超时。我觉得这是sing-box tun部分的锅。或许我们在启动tun网卡之前需要一个检测动作。

my temporary solution: "sniff_override_destination": true Then WeChat will successfully have internet despite still sends ipv6 request.

Yeah, it works. However, as you said, it's a temporary solution. Do hope there would be a official solution.

是的,这确实有用。 不过,正如你所提到的,这是一个临时解决方法。希望有一个官方的解决方案。

dyhkwong commented 1 month ago

我觉得这是sing-box tun部分的锅。或许我们在启动tun网卡之前需要一个检测动作。

据我所知其他软件也并没有解决这个问题(或者说不将此视为问题),如果有哪个软件通过非 fake ip 的方式解决了请指出并描述。 假设真的去检测网络环境,难道你想去监听网络环境变化,然后每次网络环境变化(比如由支持 ipv6 变成不支持)都去重开吗?

willsilicon commented 1 month ago

我觉得这是sing-box tun部分的锅。或许我们在启动tun网卡之前需要一个检测动作。

据我所知其他软件也并没有解决这个问题(或者说不将此视为问题),如果有哪个软件通过非 fake ip 的方式解决了请指出并描述。

假设真的去检测网络环境,难道你想去监听网络环境变化,然后每次网络环境变化(比如由支持 ipv6 变成不支持)都去重开吗?

我的情况是期望连接节点时prefer_ipv6能够起作用,小火箭是支持prefer_ipv6的,通过: ipv6 = true prefer-ipv6 = true 这两项配置,下面这项关闭时就是prefer_ipv4,当网络环境切换到没有ipv6的环境时,需要断开节点重连,我觉得这是可以接受的,而且您说的是从程序员的角度来看的,但是从产品的角度讲,目前prefer_ipv6是并不支持的。每次连接一个节点时做多一次的检测也是可以接受的,这比修改配置文件或者切换配置文件好多了,我是需要每天从公司到家切换一次,一般人每天切换网络的次数并不多,一般就是某些wifi不支持v6。

dyhkwong commented 1 month ago

我的情况是期望连接节点时prefer_ipv6能够起作用

TUN 是否有 IPv6 地址 与 应用对 IPv6 的偏好 是两回事,不要混为一谈。TUN 有否 IPv6 地址不意味着应用就会 prefer ipv4/v6。建议先去了解 DNS 的工作流程。

willsilicon commented 1 month ago

我的情况是期望连接节点时prefer_ipv6能够起作用

TUN 是否有 IPv6 地址 与 应用对 IPv6 的偏好 是两回事。TUN 有否 IPv6 地址不意味着应用就会 prefer ipv4/v6。建议先去了解 DNS 的工作流程。你能接受不代表不会弄坏其他人的配置。

明白你的意思,但是从普通用户角度,不会去考虑那么多,只是简单想要他字面看到的意思。只是建议,不喜勿喷。

xyseer commented 1 month ago

据我所知其他软件也并没有解决这个问题(或者说不将此视为问题),如果有哪个软件通过非 fake ip 的方式解决了请指出并描述。 假设真的去检测网络环境,难道你想去监听网络环境变化,然后每次网络环境变化(比如由支持 ipv6 变成不支持)都去重开吗?

感谢您的回复!

据我所知,目前其他产品也没有类似功能,现在绝大多数工具还没有做到完美的双栈支持。正如您所说,我确实希望可以根据网络环境重开sing-box以确保按照当前环境正常工作。因为sing-box的移动端很好用,在移动设备这一场景下,我认为根据网络环境变化重启sing-box是一件可以接受的事。且从文档说明来看,这项功能并不会影响sing-box现有的dns策略和其他route策略,只是希望在tun启动前尝试一下出口网卡是否存在ipv6即可。

willsilicon commented 1 month ago

据我所知其他软件也并没有解决这个问题(或者说不将此视为问题),如果有哪个软件通过非 fake ip 的方式解决了请指出并描述。 假设真的去检测网络环境,难道你想去监听网络环境变化,然后每次网络环境变化(比如由支持 ipv6 变成不支持)都去重开吗?

感谢您的回复!

据我所知,目前其他产品也没有类似功能,现在绝大多数工具还没有做到完美的双栈支持。正如您所说,我确实希望可以根据网络环境重开sing-box以确保按照当前环境正常工作。因为sing-box的移动端很好用,在移动设备这一场景下,我认为根据网络环境变化重启sing-box是一件可以接受的事。且从文档说明来看,这项功能并不会影响sing-box现有的dns策略和其他route策略,只是希望在tun启动前尝试一下出口网卡是否存在ipv6即可。

看我前面的回复,小火箭支持

alan16742 commented 1 week ago

遇见了相似的情况,连接到了一个过于老久的只有ipv4的路由器设备,使用配置无法加载网络,下面的配置可以使用 https://clash2sfa.xmdhs.com 生成。尽管使用了上面的 "sniff_override_destination": true, 但是还是存在问题比如抖音和百度走的是国外网站。最后还是直接删除了"address": ["172.18.0.1/30", "fdfe:dcba:9876::1/126"],的ipv6才得以解决。虽然ipv6的设备一定会普及,但是ipv4的消失需要的时间还是太长了,希望能像上面一样加入检测设备是否支持ipv6来决定是否启用tun的ipv6模式。

配置信息 ```json { "log": {}, "dns": { "servers": [ { "tag": "remote", "address": "https://8.8.8.8/dns-query", "detour": "select", "strategy": "prefer_ipv4", "client_subnet": "110.242.68.66" }, { "tag": "query", "address": "https://dns.alidns.com/dns-query", "address_resolver": "local", "address_strategy": "prefer_ipv4", "detour": "direct", "strategy": "prefer_ipv4" }, { "tag": "local", "address": "local", "detour": "direct" }, { "address": "rcode://success", "tag": "block" } ], "rules": [ { "outbound": "any", "server": "query" }, { "disable_cache": true, "rule_set": ["AdGuardSDNSFilter", "chrome-doh"], "server": "block" }, { "clash_mode": "direct", "server": "local" }, { "clash_mode": "global", "server": "remote" }, { "rule_set": "geosite-cn", "server": "local" } ] }, "inbounds": [ { "type": "tun", "address": ["172.18.0.1/30", "fdfe:dcba:9876::1/126"], "auto_route": true, "mtu": 9000, "sniff": true, "strict_route": true } ], "outbounds": [ { "tag": "select", "type": "selector", "default": "urltest", "outbounds": [ "urltest", "HKAuto", "AsiaAuto", "Asia", "America", "Others" ] }, { "tag": "Asia", "type": "selector", "outbounds": [ "include: 🇭🇰|HK|hk|香港|港|HongKong|🇹🇼|TW|tw|台湾|臺灣|台|Taiwan|🇸🇬|SG|sg|新加坡|狮|🇯🇵|JP|jp|日本|日" ] }, { "tag": "America", "type": "selector", "outbounds": ["include: 🇺🇸|US|us|美国|美"] }, { "tag": "Others", "type": "selector", "outbounds": [ "exclude: 🇭🇰|HK|hk|香港|香|🇹🇼|TW|tw|台湾|台|🇸🇬|SG|sg|新加坡|狮|🇯🇵|JP|jp|日本|日|🇺🇸|US|us|美国|美" ] }, { "tag": "HKAuto", "type": "urltest", "outbounds": ["include: 🇭🇰|HK|hk|香港|港|HongKong"] }, { "tag": "AsiaAuto", "type": "urltest", "outbounds": [ "include: 🇭🇰|HK|hk|香港|港|HongKong|🇹🇼|TW|tw|台湾|臺灣|台|Taiwan|🇸🇬|SG|sg|新加坡|狮|🇯🇵|JP|jp|日本|日" ] }, { "tag": "urltest", "type": "urltest", "outbounds": ["exclude: 需要包含所有"] } ], "route": { "rules": [ { "port": 53, "outbound": "dns-out" }, { "ip_is_private": true, "outbound": "direct" }, { "clash_mode": "direct", "outbound": "direct" }, { "clash_mode": "global", "outbound": "select" }, { "rule_set": "geoip-cn", "outbound": "direct" } ], "auto_detect_interface": true, "rule_set": [ { "tag": "geoip-cn", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs" }, { "tag": "geosite-cn", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/xmdhs/sing-geosite/rule-set-Loyalsoldier/geosite-geolocation-cn.srs" }, { "tag": "AdGuardSDNSFilter", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/xmdhs/sing-box-ruleset/rule-set/AdGuardSDNSFilter.srs" }, { "tag": "chrome-doh", "type": "remote", "format": "source", "url": "https://gist.githubusercontent.com/xmdhs/71fc5ff6ef29f5ecaf2c52b8de5c3172/raw/chrome-doh.json" } ] }, "experimental": { "cache_file": { "enabled": true }, "clash_api": { "external_controller": "127.0.0.1:9090", "secret": "" } } } ```