---
title: "IPv6 代理不生效：双栈网络下 IPv4 与 IPv6 出口不一致的原因与排查"
description: "IPv6 代理不生效多半是代理只接管了 IPv4、IPv6 仍在直连。本文讲 Happy Eyeballs、TUN 路由和 AAAA 解析等成因，给出 /ip 与 curl -4/-6 的确认步骤和四种处理办法的取舍。"
url: https://cdnping.org/blog/ipv6-dual-stack-proxy-mismatch
language: zh-CN
published: 2026-10-17
category: "排障指南"
tags: ["IPv6","双栈","代理","网络排障","Happy Eyeballs"]
source: cdnping.org
license: Free to quote and summarize with a link to the url above.
---
# 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 与环境检测](/ip)，重点看三块：

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

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

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

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

```bash
# 强制 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 的行为一致 |

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

```bash
# 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](/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。

```bash
# 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

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

```bash
# 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](/ip) 页面的 IPv4 / IPv6 卡片与多出口检测没有出现分叉
- [ ] DNS 泄漏检测结果符合预期
- [ ] 在 [首页测速](/) 跑一次，对比改动前后各 API 的“首次连接”耗时，确认没有引入额外延迟

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