Tailscale 子网路由劫持本地流量排查与修复

温馨提醒
Windows 开了 Tailscale 后打不开光猫?子网路由跃点数太低,抢了物理网卡的道。一行命令把接口跃点拉高,问题解决。

发生了什么

Windows 开了 Tailscale 之后,打不开光猫(192.168.1.1)了。关掉 Tailscale 立马就好。

网络长这样

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
192.168.1.0/24 物理局域网
├── 192.168.1.1  光猫(主路由)
├── 192.168.1.3  iStoreOS(旁路由,跑着 Tailscale)
├── 192.168.1.10 Windows 电脑
└── 其他设备

iStoreOS 宣告了 192.168.1.0/24 子网路由
  → 让远程 Tailscale 节点能访问家里局域网

100.80.0.0/24 Tailscale 虚拟网
├── 100.80.0.1  iStoreOS
├── 100.80.0.6  Windows
└── 100.80.0.2/3/4/5/7 远程节点

为什么会这样

看 Windows 路由表,同一个网段有两条路由:

1
2
192.168.1.0/24 → 100.100.100.100 → tailscale    跃点 5    ← Tailscale 推的
192.168.1.0/24 → 物理网卡直连                     跃点 276  ← 系统自带的

Windows 选路由只看跃点数,谁小信谁。Tailscale 的跃点 5 远低于物理网卡的 276,于是所有 192.168.1.x 的流量都被塞进了 Tailscale 隧道——绕一大圈再回来,当然不通。

删掉那条路由就能恢复:

1
route DELETE 192.168.1.0

根因

iStoreOS 向 Headscale 宣告了 192.168.1.0/24 子网路由,本意是让远程节点能访问家里设备。但 Tailscale 无差别推送给所有节点——包括 Windows 这台自己就在 192.168.1.0/24 里的机器。它不会判断"这台设备就在这个网段里,不需要推"。

插曲:防火墙改坏了 Tailscale

排查过程中还发现所有 Tailscale 节点都 ping 不通 iStoreOS(100.80.0.1)。SSH 上去一看:

1
tailscale0 接口没有 IPv4 地址!

原因是之前改过防火墙规则,nftables 重载时破坏了 tailscale 的集成,导致接口虽然创建了但 IPv4 地址没绑上。控制面还活着(UDP 打洞在),但 IP 层残了。

修很简单,重启就好:

1
/etc/init.d/tailscale restart

完整时间线

阶段子网路由能访问光猫吗Tailscale 互通
最初Tailscale 劫持(跃点 5)❌ 绕隧道了
改防火墙后消失了(接口没 IPv4)✅ 意外恢复❌ 全挂
重启 tailscale重新推送❌ 又劫持了
修好之后还在推送,但被压制✅ 本地优先

怎么修

推荐:调高 Tailscale 接口跃点(一行命令)

1
2
3
4
# 管理员 PowerShell
netsh interface ipv4 set interface "Tailscale" metric=1000
tailscale down
tailscale up

原理很简单:Tailscale 推送的路由继承接口的跃点数。把接口跃点从 5 拉到 1000,自然抢不过物理网卡的 276。同网段走本地,远程走隧道,互不干扰。

好处: 不绑定具体网段,换网段换 IP 都不需要改。一条命令永久生效。

备选:iStoreOS 用 NAT 代替子网路由

不宣告子网路由,远程节点访问 LAN 时由 iStoreOS 做 SNAT。好处是零路由劫持,代价是 LAN 设备只能看到请求来自 192.168.1.3,看不到原始 Tailscale IP。

不推荐:写死永久路由

1
route ADD -p 192.168.1.0 MASK 255.255.255.0 192.168.1.10 METRIC 1

绑定了网段和 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 节点