Tailscale 子网路由劫持本地流量排查与修复
发生了什么
Windows 开了 Tailscale 之后,打不开光猫(192.168.1.1)了。关掉 Tailscale 立马就好。
网络长这样
| |
为什么会这样
看 Windows 路由表,同一个网段有两条路由:
Windows 选路由只看跃点数,谁小信谁。Tailscale 的跃点 5 远低于物理网卡的 276,于是所有 192.168.1.x 的流量都被塞进了 Tailscale 隧道——绕一大圈再回来,当然不通。
删掉那条路由就能恢复:
| |
根因
iStoreOS 向 Headscale 宣告了 192.168.1.0/24 子网路由,本意是让远程节点能访问家里设备。但 Tailscale 无差别推送给所有节点——包括 Windows 这台自己就在 192.168.1.0/24 里的机器。它不会判断"这台设备就在这个网段里,不需要推"。
插曲:防火墙改坏了 Tailscale
排查过程中还发现所有 Tailscale 节点都 ping 不通 iStoreOS(100.80.0.1)。SSH 上去一看:
| |
原因是之前改过防火墙规则,nftables 重载时破坏了 tailscale 的集成,导致接口虽然创建了但 IPv4 地址没绑上。控制面还活着(UDP 打洞在),但 IP 层残了。
修很简单,重启就好:
| |
完整时间线
| 阶段 | 子网路由 | 能访问光猫吗 | Tailscale 互通 |
|---|---|---|---|
| 最初 | Tailscale 劫持(跃点 5) | ❌ 绕隧道了 | ✅ |
| 改防火墙后 | 消失了(接口没 IPv4) | ✅ 意外恢复 | ❌ 全挂 |
| 重启 tailscale | 重新推送 | ❌ 又劫持了 | ✅ |
| 修好之后 | 还在推送,但被压制 | ✅ 本地优先 | ✅ |
怎么修
推荐:调高 Tailscale 接口跃点(一行命令)
原理很简单:Tailscale 推送的路由继承接口的跃点数。把接口跃点从 5 拉到 1000,自然抢不过物理网卡的 276。同网段走本地,远程走隧道,互不干扰。
好处: 不绑定具体网段,换网段换 IP 都不需要改。一条命令永久生效。
备选:iStoreOS 用 NAT 代替子网路由
不宣告子网路由,远程节点访问 LAN 时由 iStoreOS 做 SNAT。好处是零路由劫持,代价是 LAN 设备只能看到请求来自 192.168.1.3,看不到原始 Tailscale IP。
不推荐:写死永久路由
| |
绑定了网段和 IP,哪天换了就得手动改,不够灵活。
为什么 ZeroTier 没这问题
ZeroTier 的虚拟网卡在 Windows 上自动跃点是 ~1000,Tailscale 的 TUN 驱动是 ~5。这是驱动模型决定的,不是配置问题。ZeroTier 用虚拟以太网适配器,Windows 认为它"慢";Tailscale 用 TUN 隧道,Windows 认为它"快"。Tailscale 官方目前不给 Windows 调接口跃点的参数。
以后注意
- 改防火墙后顺手检查一下
ip addr show tailscale0 | grep inet,确认 IPv4 地址还在 - 地址丢了就重启:
/etc/init.d/tailscale restart - 新设备接入时看一眼路由表,Linux 上 Tailscale 路由在独立表 52 里(
ip route show table 52),主表看不到
关联问题
这个问题修好后,还发现了一个衍生问题:Windows 关掉 Tailscale 后,ping 不通同网段的 100.80.0.2(dbroot)。 那是 rp_filter 非对称路由导致的,详见 Tailscale 非对称路由导致 LAN 设备无法访问同网段 Tailscale 节点 。