headscale系列:Tailscale 4via6 在 Windows 子网路由上的 ICMP 行为说明
Tailscale 4via6 在 Windows 子网路由上的 ICMP 行为说明
(为什么能用“合成 IPv6”访问 Web,却 ping -6 不通)
1. 场景与现象
拓扑:
A、B 两台 Windows 电脑安装 Tailscale;B 同时作为子网路由器(Subnet Router)。
C 是 OpenWrt 设备,挂在 B 所在现场的内网。配置:已开启 4via6,B 宣告(advertise)一个 IPv6 子网,并在 Headscale/后台审批通过。
现象:
- 从 A 能用 “合成的 IPv6 地址” 打开 C 的 Web 服务(HTTP/HTTPS 正常)。
- 但从 A 执行
ping -6 <C-的IPv6>不通。抓包能看到 Echo Request 发出,但收不到回包;在 B 上用 Wireshark 看,没有 ICMP 包进入。
2. 关键概念:4via6 与“合成 IPv6”
Tailscale 的 4via6 会把内网 IPv4 目标编码进一个保留的 ULA 段(如 fd7a:115c:a1e0::/48),形成合成 IPv6 地址:
例:c0a8:0601 对应 192.168.6.1,于是会看到类似fd7a:115c:a1e0:b1a0:7:c0a8:0601 这样的目的地址。
- 对 TCP/UDP 流量:Tailscale 会把发往这些“合成 IPv6”的包转换并送到真实的 IPv4 终端,所以浏览器/SSH/Modbus-TCP 等能正常工作。
- 对 ICMPv6:在 Windows 客户端 上,当前路径不会把 ICMPv6 Echo 转成 ICMPv4 Echo,因此
ping -6不会得到回应——包也不会被转发到 B 或 C。
3. 根因(简洁版)
Windows + 4via6 的协议支持面:
只对 TCP/UDP 做 IPv6→IPv4 转换;ICMPv6 不在转换范围内,所以ping -6失败,而 Web 正常。Windows 子网路由对“原生 IPv6 子网”的转发能力有限:
即便 B 宣告了 IPv6 子网,Windows 作为子网路由在 IPv6 转发与邻居发现处理上并不如 Linux 完整稳定,导致跨站点的 ICMPv6 转发经常不可用。换成 Linux/OpenWrt 当子网路由后,同样配置下
ping -6通常即可恢复正常。
4. 结论一句话
在 Windows 子网路由 + 4via6 的组合中,HTTP/UDP 能走,但
ICMPv6不会被转换/转发,所以ping -6不通是预期行为;Linux 子网路由可以正常转发 ICMPv6。
5. 可选解决/替代方案
方案 A(最省事):用 IPv4 做连通性检查
- 改用
ping 192.168.6.x(ICMPv4),或Test-NetConnection 192.168.6.x -Port 80/22验证端口。 - 适合“只想知道在线与否”的场景;无需改动现场。
方案 B(推荐):把 子网路由器 换成 Linux/OpenWrt
在 B 侧放一台小 Linux/OpenWrt 盒子(可以是现有 OpenWrt 路由或小主机/容器)作为 Tailscale 子网路由:
1 | # 1) 开启 IPv6 转发 |
完成后,从 A 直接 ping -6 <C 的**原生** IPv6>,ICMPv6 会被正常转发;B 上能抓到往返的 ICMPv6。
方案 C(最干净):让 C 直接加入 Tailnet
在 OpenWrt 上安装 Tailscale,让 C 成为独立节点(拥有自己的 fd7a:... 节点地址):
1 | opkg update |
A 直接 ping -6 <C 的 Tailscale IPv6>,端到端走 Tailscale,绕开子网路由的限制。
方案 D(保留 Windows,但想要 ping -6)
在 B 侧增加小型 Linux NAT64/CLAT(例如 Jool EAMT),专门把发往 fd7a:115c:a1e0::/96 的 ICMPv6⇄ICMPv4 做转换;并在 B/网关上加静态路由把该前缀指向这台转换器。
该方案能打通
ping -6,但复杂度与维护成本较高,一般不如方案 B/C。
6. 快速排障自检
能开 Web,
ping -6不通:90% 是 ICMPv6 未转换/未转发的已知限制。在 A 执行:
ping 192.168.6.x(C 的 IPv4):若可达,证明 4via6 通路正常,只是 ICMPv6 不支持。route print -6或Get-NetRoute -AddressFamily IPv6:若看到目的合成地址不断触发 Neighbor Solicitation 而无回应,这是主机把目标当“链路内”,但 Tailscale 不会为其应答/转发 ICMPv6 的典型表现。
在 B 抓包(Tailscale/Wintun 接口):若看不到来自 A 的 ICMPv6,则说明包没被交给子网路由(仍印证“Windows 不处理 ICMPv6 转换”)。
7. 常见问答
- 为什么浏览器能打开?
因为 TCP(和大多数 UDP)会被 4via6 转换并转发到 IPv4 终端;ICMPv6 不在这个转换面里。 - UDP 是否也能走?
能(取决于具体协议/端口与策略),多数 UDP 通过 4via6 没问题;问题集中在 ICMPv6。 - 以后 Windows 会支持吗?
以当前版本看没有现成开关可启用。若对 ICMPv6 必须要,建议按方案 B/C 处理。
推荐落地选型
- 想保留 Windows 当子网路由:接受“不能
ping -6”,用 IPv4 ping/端口探测替代。 - 需要完整 IPv6(含
ping -6):把子网路由迁到 Linux/OpenWrt;或让终端设备直接跑 Tailscale。