IPv6 代理不生效:双栈网络下 IPv4 与 IPv6 出口不一致的原因与排查

博客 / 排障指南

IPv6 代理不生效:双栈网络下 IPv4 与 IPv6 出口不一致的原因与排查

网络同时有 IPv4 和 IPv6(双栈)时,常见的“IPv6 代理不生效”其实是代理客户端只接管了 IPv4:访问支持 IPv6 的网站,系统优先走 IPv6 直连,流量根本没进代理。确认方法是分别看 IPv4 和 IPv6 的出口地址是否一致;处理上要么让代理客户端也接管 IPv6,要么让本机少用或不用 IPv6。下面按原因、确认、处理的顺序说明。

为什么双栈网络下代理会“失效”

Happy Eyeballs:系统默认偏向 IPv6

现代操作系统和浏览器在连接一个域名时,会同时查询 A(IPv4)和 AAAA(IPv6)记录。按照 Happy Eyeballs 算法(RFC 8305,前身是 RFC 6555),客户端会优先尝试 IPv6,只有在 IPv6 连接在很短时间内(RFC 8305 建议的默认值是 250 毫秒左右)没有建立起来时,才转去尝试 IPv4。

所以只要本机有可用的 IPv6 地址和默认路由,目标站点又有 AAAA 记录,连接大多会走 IPv6。国内不少家庭宽带和移动网络已经默认下发 IPv6 地址,很多机器一直处在双栈状态,只是平时没注意到。

哪些代理接管方式会漏掉 IPv6

代理是否受双栈影响,取决于它在哪一层接管流量。

接管方式双栈下的表现原因
系统代理 / 应用内 HTTP、SOCKS5 代理通常不受影响应用把域名直接交给代理,由代理端解析和连接,本机不发起 IPv6 连接
不读系统代理的程序(部分命令行工具、SDK)完全绕过代理,IPv4 和 IPv6 都直连程序根本没走代理,与 IPv6 无关,但常被误判为 IPv6 问题
TUN / 虚拟网卡模式,只配置了 IPv4 路由IPv4 走代理,IPv6 直连虚拟网卡只接管 0.0.0.0/0,IPv6 默认路由仍指向物理网卡
代理客户端的 DNS 放行了 AAAA 记录部分站点走 IPv6 直连解析得到真实 IPv6 地址,而规则或路由没覆盖 IPv6
网关 / 软路由透明代理只处理 IPv4局域网内所有设备都可能出现 IPv6 直连防火墙规则只写了 iptables,没有写 ip6tables 或对应的 nftables 规则

最常见的现象:浏览器打开某个支持 IPv6 的站点,显示的地区与代理节点不一致;换一个只有 IPv4 的站点又正常;同一个页面刷新几次,结果时好时坏。最后这种情况是 Happy Eyeballs 在起作用:IPv6 偶尔慢一点,连接就回落到 IPv4。

还有一种情况不算故障:同一台机器访问不同服务时,出口不同。对于需要稳定出口的场景(例如调试 API 的地区路由、对比延迟),这会让测量结果无法复现。

怎么确认是 IPv6 绕过了代理

在浏览器里:用 /ip 对照 IPv4、IPv6 与多出口

打开 cdnping 的 IP 与环境检测,重点看三块:

  1. IPv4 / IPv6 检测:页面会分别给出 IPv4 和 IPv6 的出口情况。如果两者的地理位置、ASN 明显不同,例如 IPv4 显示为代理节点所在地的机房网段,IPv6 显示为本地运营商,基本可以确定是代理只接管了 IPv4。
  2. 多出口检测:页面会读取 Claude、ChatGPT、Grok 等站点的 Cloudflare trace,看访问不同站点时实际使用的出口。如果有的站点显示代理出口,有的显示本地出口,说明流量在不同路径之间分叉了。
  3. 大陆分流检测与 DNS 泄漏:分流规则和 DNS 配置也会造成出口不一致,可以顺带排除。DNS 泄漏的原理和判断方法见 DNS 泄漏与 WebRTC 泄漏。

如果要把检测结果发给同事或贴到 issue 里,可以在 /ip 生成带水印的结果图;生成前先打开隐藏 IP,图里就不会出现你的出口地址。页面上的浏览器指纹在本地计算,不会上传。

在终端里:用 curl -4 / -6 对照出口

浏览器之外的程序(命令行工具、SDK、IDE 插件)不一定和浏览器走同一条路,需要在终端里单独测一遍。Cloudflare 的 trace 接口会返回它看到的客户端 IP,适合做对照:

# 强制 IPv4
curl -4 -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

# 强制 IPv6
curl -6 -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

# 不加参数,看系统默认选了哪一个
curl -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

结果怎么读:

现象判断
-6 报错 “Couldn't connect” 或无路由本机没有可用 IPv6,问题不在这里
-4 显示代理出口,-6 显示本地运营商地址代理只接管了 IPv4,属于本文讨论的情况
-4、-6 都显示本地地址该程序没有走代理,先检查环境变量 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 或改用 TUN 模式
-4、-6 都显示代理出口,且地区一致双栈都已接管,出口不一致要从分流规则或 DNS 查起
不加参数时的 ip= 是 IPv6 地址默认连接走了 IPv6,与 Happy Eyeballs 的行为一致

再补两条查看本机状态的命令:

# Linux:是否有全局 IPv6 地址和 IPv6 默认路由
ip -6 addr show scope global
ip -6 route show default

# macOS:查看各网卡的 IPv6 地址和 IPv6 路由表
ifconfig | grep inet6
netstat -rn -f inet6 | head -20

Windows 可以在 PowerShell 里执行 Get-NetIPAddress -AddressFamily IPv6 和 Get-NetRoute -AddressFamily IPv6 -DestinationPrefix ::/0。

如果你在排查调用 AI 接口的程序,可以把上面的 trace 地址换成目标 API 的域名,用 curl -4 -o /dev/null -w '%{remote_ip} %{time_connect}\n' 和 -6 各跑一次,看实际连上的地址和建连耗时。AGI Plan 是 cdnping 的商业合作方,用 AGI Plan 的读者可以用同样的方法对 agiplan.dev 做对照,再到 /status/agiplan 看 cdnping 镜像展示的 AGI Plan 可用率。

怎么修:四种处理办法与取舍

确认是代理只接管了 IPv4 之后,按下面的顺序考虑。一般先改代理客户端,影响范围最小;改系统和网关的影响依次变大。

办法一:在代理客户端里开启 IPv6 支持

多数支持 TUN 模式的客户端都有 IPv6 相关开关,名称通常是“IPv6”“启用 IPv6 路由”或在配置文件中给虚拟网卡加一个 IPv6 地址段。开启后,虚拟网卡会同时接管 ::/0,IPv6 流量也进入代理。

  • 优点:本机网络保持完整,国内直连的站点仍然可以用 IPv6,不影响局域网内其他设备。
  • 前提:代理链路本身要能处理 IPv6 目标。如果远端不支持 IPv6,常见做法是在客户端 DNS 中只返回 A 记录(不少客户端有“禁用 AAAA”或“仅 IPv4 解析”选项),让应用只发起 IPv4 连接。
  • 注意:开启后要重新跑一遍上面的 curl -6 对照,确认 IPv6 出口确实变了。

办法二:让系统优先使用 IPv4

不关掉 IPv6,只调整地址选择的优先级。这样遇到同时有 A 和 AAAA 记录的域名时,系统会先试 IPv4。

# Linux(glibc):在 /etc/gai.conf 中加入一行
precedence ::ffff:0:0/96  100

Windows 可以通过修改前缀策略实现,例如以管理员身份执行 netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 60 4。macOS 没有同样简便的系统级开关。

  • 优点:改动小,IPv6 仍然可用。
  • 局限:只影响走系统解析器的程序;浏览器内置的 DNS-over-HTTPS、自带解析器的程序不一定遵守。只有 AAAA 记录的站点仍会走 IPv6 直连。

办法三:关闭系统 IPv6

效果最确定,副作用也最大。

# Linux 临时关闭(重启后恢复)
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

# macOS 关闭 Wi-Fi 网卡的 IPv6(服务名以 networksetup -listallnetworkservices 为准)
sudo networksetup -setv6off Wi-Fi
# 恢复
sudo networksetup -setv6automatic Wi-Fi

Windows 可以在网卡属性中取消勾选“Internet 协议版本 6 (TCP/IPv6)”,或在 PowerShell 中使用 Disable-NetAdapterBinding -Name "以太网" -ComponentID ms_tcpip6。

  • 优点:不再有 IPv6 直连的可能,出口行为最好预测。
  • 代价:失去 IPv6 带来的直连路径,部分国内服务或运营商网络在 IPv6 下的表现可能更好;某些系统组件依赖 IPv6 环回或链路本地地址,全局关闭后可能出现难以定位的问题。微软的官方文档也不建议完全禁用 IPv6,推荐用前缀策略让 IPv4 优先。
  • 建议:先用临时方式验证效果,确认问题解决后再决定是否持久化。

办法四:在网关或软路由上处理

如果局域网里的设备都受影响,问题多半出在网关的透明代理只写了 IPv4 规则。可以在网关上补齐 IPv6 的转发规则,或者在网关上关闭 IPv6 下发(不发 RA、不开 DHCPv6)。后者等于对整个局域网执行“办法三”,取舍相同。

四种办法对照

办法影响范围IPv6 是否保留适合谁
客户端开启 IPv6本机保留客户端和远端都支持 IPv6
系统优先 IPv4本机,仅系统解析器保留想少改动、先缓解问题
关闭系统 IPv6本机不保留需要出口完全可预测
网关处理整个局域网视做法而定多台设备同时出问题

以上办法只用于让本机的网络行为和你的配置一致,方便排障和测量,不涉及绕过任何服务的地区限制。使用境外服务时请遵守其服务条款和当地法律法规。

改完之后逐项检查

  • curl -4 和 curl -6 的 trace 结果符合你的预期(一致,或 -6 已不可用)
  • 不加参数的 curl 出口与浏览器一致
  • /ip 页面的 IPv4 / IPv6 卡片与多出口检测没有出现分叉
  • DNS 泄漏检测结果符合预期
  • 在 首页测速 跑一次,对比改动前后各 API 的“首次连接”耗时,确认没有引入额外延迟

如果检测之后出口已经一致,但某个 AI 服务仍然打不开,问题可能不在本地网络。可以去 /down 看对应服务有没有其他用户报告,或在 /status 查看 cdnping 从 Cloudflare 边缘每 5 分钟一次的探测结果,再决定是继续排查本地,还是等待服务恢复。分流相关的概念可以接着读 分流(Split Tunneling)是什么。

相关文章

继续阅读