背景
家里一条中国移动浙江杭州宽带出现了一个很奇怪的 IPv6 问题:
- 国内 IPv6 网站的 TCP/443 正常;
- 海外 IPv6 地址可以 ping 通;
- 但是海外 IPv6 的 TCP 连接不通,包括 HTTPS 443 和自有海外服务器的 SSH 22;
- 同样是中国移动 IPv6,另一条宽带的海外 IPv6 TCP 又是正常的。
这类问题很容易被误判成 DNS、MTU、光猫防火墙、OpenWrt 配置错误。实际排查下来,问题更像是移动出口或中间链路按源 IPv6 前缀分流后,部分前缀的海外 TCP 路径异常。
为了避免暴露家庭网络的完整地址,下面只保留网段级别信息,具体主机地址和接口 IID 均已脱敏。
当前网络结构
网络结构大致如下:
|
|
当时拿到的主要 IPv6 网段如下:
| 位置 | 网段 |
|---|---|
| 光猫到路由器侧 | 2409:8a28:6e9:69a0::/64 |
| ImmortalWrt LAN / 手机侧 | 2409:8a28:6e9:69a1::/64 |
| 所在上级块 | 2409:8a28:6e9::/48 |
| 另一个能通的移动宽带所在块 | 2409:8a28:824::/48 |
可以看到,两个宽带虽然都属于中国移动 2409:8a28::/32 附近的地址,但从 /40 开始就已经不同:
|
|
这意味着它们在移动内部可能已经走不同地址池、BRAS、城域网出口或海外出口策略。
先排除本地配置问题
在 ImmortalWrt 上固定同一个源地址测试,结果如下:
| 目标 | 协议 | 结果 |
|---|---|---|
| 国内百度 IPv6 | TCP/443 | 成功 |
| 国内腾讯 IPv6 | TCP/443 | TCP/TLS 成功 |
| Cloudflare IPv6 | TCP/443 | 超时 |
| 1.1.1.1 的 IPv6 | TCP/443 | 超时 |
| Debian / kernel.org / IANA | TCP/443 | 超时 |
| 自有海外服务器 | TCP/22 | 超时 |
| Cloudflare / 自有海外服务器 | ICMPv6 | 正常 |
这个结果说明:
- IPv6 地址、路由、RA/DHCPv6 基本不是问题,因为国内 IPv6 TCP 能通;
- 不是海外 IPv6 完全不通,因为 ICMPv6 能通;
- 问题集中在海外方向的 TCP。
光猫 WAN 口抓包
为了确认包有没有从本地发出去,我在光猫上放了一个静态编译的 tcpdump,直接抓光猫 PPP WAN 接口。
抓包结果显示,从 ImmortalWrt 发往自有海外服务器 TCP/22 的 SYN 已经从光猫 WAN 口发出:
|
|
同时在海外服务器网卡上抓包,完全收不到这些 SYN:
|
|
这一步基本可以排除光猫和 OpenWrt 没有把包发出去的问题。包已经离开家庭网络,但没有到达海外服务器。
同一个源地址反复验证
为了避免不同源地址造成误判,后续测试固定使用同一个 LAN 侧源地址所在网段:
|
|
结果依然是:
- 国内 IPv6 TCP 正常;
- 海外 IPv6 ICMPv6 正常;
- 海外 IPv6 TCP 超时;
- 光猫 WAN 能看到 SYN 发出;
- 海外服务器收不到 SYN。
这说明问题不是 DNS,也不是随机某次连接失败。
伪源前缀探测
后面做了一个更关键的验证:在 ImmortalWrt 上临时加一些未分配给本线路的 IPv6 源地址,只对自有海外服务器发极少量测试包,同时远端 tcpdump 观察是否能收到。
注意:这种方式只能判断“带这个源前缀的包是否能穿过移动出口到远端”,不能代表这个地址真的能正常使用。因为这个地址并没有分配给本线路,回包不会正确回到本线路。
测试现象:
| 伪源网段 | ICMPv6 到远端 | TCP SYN 到远端 |
|---|---|---|
2409:8a28:6e9:69a2::/64 附近 |
到达 | 未到 |
2409:8a28:6e9:69b0::/64 附近 |
到达 | 未到 |
2409:8a28:824:a90::/64 附近 |
到达 | 到达 |
这说明移动链路并没有对源地址做非常严格的入口校验,至少伪源 ICMPv6 可以到远端;同时也说明,海外 TCP 是否到达和源 IPv6 前缀强相关。
前缀抽样结果
随后对 2409:8a28::/32 内的一些前缀做了低速抽样。所有测试都只打自有海外服务器的 TCP/22,远端以 tcpdump 判断 SYN 是否到达。
/40 粗扫
每个 /40 取一个代表地址,结果只有这两个代表点到达:
|
|
异常线路所在的 2409:8a28:600::/40 代表点未到。
不过代表点失败不等于整个 /40 都失败,所以继续细扫。
/44 细扫
2409:8a28:600::/40 内:
| /44 | 结果 |
|---|---|
2409:8a28:610::/44 |
到达 |
2409:8a28:620::/44 |
到达 |
2409:8a28:630::/44 |
到达 |
2409:8a28:640::/44 |
到达 |
2409:8a28:660::/44 |
到达 |
2409:8a28:670::/44 |
到达 |
2409:8a28:680::/44 |
到达 |
2409:8a28:690::/44 |
到达 |
2409:8a28:600::/44 |
未到 |
2409:8a28:650::/44 |
未到 |
2409:8a28:6a0::/44 |
未到 |
2409:8a28:6b0::/44 |
未到 |
2409:8a28:6c0::/44 |
未到 |
2409:8a28:6d0::/44 |
未到 |
2409:8a28:6e0::/44 |
未到 |
2409:8a28:6f0::/44 |
未到 |
异常线路所在的 2409:8a28:6e9::/48 落在 2409:8a28:6e0::/44 内。
2409:8a28:800::/40 内:
| /44 | 结果 |
|---|---|
2409:8a28:800::/44 |
到达 |
2409:8a28:810::/44 |
到达 |
2409:8a28:820::/44 |
到达 |
2409:8a28:830::/44 |
到达 |
2409:8a28:840::/44 |
到达 |
2409:8a28:870::/44 |
到达 |
2409:8a28:880::/44 |
到达 |
2409:8a28:8b0::/44 |
到达 |
2409:8a28:8c0::/44 |
到达 |
2409:8a28:8d0::/44 |
到达 |
2409:8a28:8e0::/44 |
到达 |
2409:8a28:8f0::/44 |
到达 |
2409:8a28:850::/44 |
未到 |
2409:8a28:860::/44 |
未到 |
2409:8a28:890::/44 |
未到 |
2409:8a28:8a0::/44 |
未到 |
另一个正常宽带所在的 2409:8a28:824::/48 落在 2409:8a28:820::/44 内,测试结果为到达。
2409:8a28:c00::/40 内:
| /44 | 结果 |
|---|---|
2409:8a28:c00::/44 |
到达 |
2409:8a28:c10::/44 |
到达 |
2409:8a28:c20::/44 |
到达 |
2409:8a28:c30::/44 |
到达 |
2409:8a28:c40::/44 |
到达 |
2409:8a28:c50::/44 |
到达 |
2409:8a28:c60::/44 |
到达 |
2409:8a28:c70::/44 |
到达 |
2409:8a28:c80::/44 |
到达 |
2409:8a28:cb0::/44 |
到达 |
2409:8a28:cc0::/44 |
到达 |
2409:8a28:cd0::/44 |
到达 |
2409:8a28:ce0::/44 |
到达 |
2409:8a28:c90::/44 |
未到 |
2409:8a28:ca0::/44 |
未到 |
2409:8a28:cf0::/44 |
未到 |
2409:8a28:6e0::/44 继续细分
因为异常线路落在 6e0::/44 内,所以继续细分到 /48。
结果:
| /48 | 结果 |
|---|---|
2409:8a28:6e1::/48 |
到达 |
2409:8a28:6e0::/48 |
未到 |
2409:8a28:6e2::/48 |
未到 |
2409:8a28:6e3::/48 |
未到 |
2409:8a28:6e4::/48 |
未到 |
2409:8a28:6e5::/48 |
未到 |
2409:8a28:6e6::/48 |
未到 |
2409:8a28:6e7::/48 |
未到 |
2409:8a28:6e8::/48 |
未到 |
2409:8a28:6e9::/48 |
未到 |
2409:8a28:6ea::/48 |
未到 |
2409:8a28:6eb::/48 |
未到 |
2409:8a28:6ec::/48 |
未到 |
2409:8a28:6ed::/48 |
未到 |
2409:8a28:6ee::/48 |
未到 |
2409:8a28:6ef::/48 |
未到 |
这里可以看到,6e0::/44 内部也是混合的。6e1::/48 能到,6e9::/48 不能到。
2409:8a28:6e9::/48 继续细分
异常线路所在的 2409:8a28:6e9::/48 继续细分到 /52,16 个代表点全部未到:
|
|
异常线路的 LAN 前缀落在 2409:8a28:6e9:6000::/52 内。
2409:8a28:6e1::/48 对比
作为对照,对能到的 2409:8a28:6e1::/48 也细分到 /52。16 个代表点全部到达。
这说明异常不是整个 2409:8a28:6e0::/44 的简单统一策略,而是更细粒度的源前缀分流或出口路径差异。
前缀结果汇总表
下面把主要探测结果合并成一张表。这里的“到达”表示伪源 TCP SYN 能在自有海外服务器 tcpdump 中看到;“未到”表示远端没有抓到对应 SYN。
| 前缀 | 粒度 | 结果 | 备注 |
|---|---|---|---|
2409:8a28:000::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:100::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:200::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:300::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:400::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:500::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:600::/40 |
/40 代表点 | 未到 | 但内部 /44 存在混合 |
2409:8a28:700::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:800::/40 |
/40 代表点 | 到达 | 另一个正常宽带落在此范围附近 |
2409:8a28:900::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:a00::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:b00::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:c00::/40 |
/40 代表点 | 到达 | 内部 /44 也存在混合 |
2409:8a28:d00::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:e00::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:f00::/40 |
/40 代表点 | 未到 | 粗扫代表点 |
2409:8a28:600::/44、650::/44、6a0::/44 - 6f0::/44 |
/44 代表点 | 未到 | 异常线路所在的 6e0::/44 在此组 |
2409:8a28:610::/44 - 640::/44、660::/44 - 690::/44 |
/44 代表点 | 到达 | 同一 /40 内存在可达段 |
2409:8a28:800::/44 - 840::/44、870::/44、880::/44、8b0::/44 - 8f0::/44 |
/44 代表点 | 到达 | 824::/48 落在 820::/44 |
2409:8a28:850::/44、860::/44、890::/44、8a0::/44 |
/44 代表点 | 未到 | 800::/40 内的未到段 |
2409:8a28:c00::/44 - c80::/44、cb0::/44 - ce0::/44 |
/44 代表点 | 到达 | c00::/40 内多数可达 |
2409:8a28:c90::/44、ca0::/44、cf0::/44 |
/44 代表点 | 未到 | c00::/40 内的未到段 |
2409:8a28:6e1::/48 |
/48 代表点 | 到达 | 继续细分到 /52 后 16 个代表点均到达 |
2409:8a28:6e0::/48、6e2::/48 - 6ef::/48 |
/48 代表点 | 未到 | 6e0::/44 内大多数 /48 未到 |
2409:8a28:6e9::/48 |
/52 代表点 | 未到 | 16 个 /52 代表点全部未到 |
2409:8a28:6e9:6000::/52 |
/52 代表点 | 未到 | 异常线路 LAN 前缀所在范围 |
2409:8a28:6e1::/48 |
/52 代表点 | 到达 | 16 个 /52 代表点全部到达,作为对照 |
结论
这次排查得到的结论是:
- 本地光猫和 ImmortalWrt 已经把海外 TCP SYN 发出;
- 国内 IPv6 TCP 正常,海外 IPv6 ICMPv6 正常;
- 海外 IPv6 TCP SYN 在离开本地后、到达远端前丢失;
- 丢失与源 IPv6 前缀强相关;
- 异常线路所在的
2409:8a28:6e9::/48按/52抽样全部未到; - 对照的
2409:8a28:6e1::/48按/52抽样全部到达; - 另一个正常宽带所在的
2409:8a28:824::/48也落在抽样显示正常的区域。
因此,这个问题不太像 DNS、MTU、光猫防火墙或 OpenWrt 配置错误,更像是中国移动浙江杭州这条线路当前拿到的 IPv6 源前缀被分配到了有问题的海外 TCP 出口路径,或者对应源前缀在中间链路上被策略性丢弃。
后续处理建议
如果遇到类似问题,可以按这个顺序排查:
- 固定同一个源 IPv6 地址测试国内和海外 TCP;
- 同时测试 ICMPv6,区分“IPv6 全不通”和“只有 TCP 不通”;
- 在光猫或主路由 WAN 口抓包,确认 SYN 是否已离开本地;
- 在自有海外服务器抓包,确认 SYN 是否到达远端;
- 如果有另一条宽带或另一段 IPv6 前缀,可以用同一目标做对照;
- 向运营商报障时,重点描述“国内 IPv6 TCP 正常、海外 IPv6 ICMP 正常、海外 IPv6 TCP SYN 从本地发出但远端收不到”,不要只说“IPv6 不通”。
如果运营商无法处理,临时绕过方案通常只有:
- 重拨尝试获取不同 IPv6 前缀;
- 使用另一条出口正常的宽带;
- 对海外流量走隧道或代理;
- 暂时关闭客户端对海外目标的 IPv6 优先级。
这类问题的本质不在家庭网络内部,而在运营商 IPv6 出口路径和源前缀策略上。

说些什么吧!