返回

tailscale 和 aliyun 打架记录

无力。

问题描述

在 VPS 上直接 Ping 百度,提示无法解析域名。

1
2
ping pan.baidu.com
ping: pan.baidu.com: Name or service not known

起初我以为是 VPS 负载过高导致 DNS 响应慢,尝试修改 /etc/resolv.conf 但无效。直到我检查了 resolvectl status,发现了问题的端倪。

线索查找

线索 1:阿里云的内网 DNS 阿里云 ECS 默认通过 DHCP 下发的 DNS 服务器地址是保留地址:

1
2
3
4
Link 2 (eth0)
Current DNS Server: 100.100.2.136
       DNS Servers: 100.100.2.136
                    100.100.2.138

线索 2:Tailscale 的路由网段 Tailscale 默认使用的 Carrier Grade NAT (CGNAT) 网段是 100.64.0.0/10。 这意味着 Tailscale 会接管 100.64.0.0100.127.255.255 之间的所有流量。

结论

IP 地址“撞车” 阿里云的 DNS IP 100.100.2.136 恰好落在了 Tailscale 的管辖范围内(100.100100.64 ~ 100.127 之间)。

故障逻辑链:

  1. ping 的时候,系统试图请求 DNS 解析 -> 目标 IP 100.100.2.136
  2. 查路由表 -> 发现该 IP 匹配 Tailscale 的网卡 (tailscale0) 路由规则。
  3. 路由劫持 -> 数据包没有走 eth0 去阿里云网关,而是被发进了 Tailscale 的虚拟隧道。
  4. 黑洞 -> Tailscale 隧道对面并没有这个 DNS 服务器,数据包有去无回。
  5. ping超时 -> Systemd-resolved 等不到回应,报 i/o timeout

解决方案 Part - 1(已放弃)

既然内网 DNS 会撞车,解决思路就是放弃阿里云内网 DNS,强制走公网 DNS

由于 Linux 的 DNS 机制复杂,直接改 /etc/resolv.conf 会被重启覆盖。最优雅的解法是配置 systemd-resolved 的全局覆盖。

操作步骤:

修改配置文件

1
sudo nano /etc/systemd/resolved.conf

设置全局公网 DNS: 在 [Resolve] 区域添加配置。这里使用了阿里云公网 DNS (223.5.5.5) 和 Cloudflare (1.1.1.1)。 关键点是 Domains=~.,这代表“全局优先”,强制所有域名解析都优先使用这里的 DNS,而不是网卡接口特定的 DNS。

1
2
3
4
[Resolve]
DNS=223.5.5.5 1.1.1.1
#FallbackDNS=
Domains=~.

重启服务生效

1
sudo systemctl restart systemd-resolved

验证状态

1
resolvectl status

此时可以看到 Global 的 DNS 已经生效,且优先级高于 Link 2 (eth0)

1
2
3
Global
     DNS Servers: 223.5.5.5 1.1.1.1
      DNS Domain: ~.

验证结果:

  • ping pan.baidu.com -> 通了! (解析到了公网 IP)
  • Tailscale 连接 -> 正常 (依然可以通过 IP 访问内网机器,虽然丢掉了 magicdns 功能,并且无法使用阿里云内网服务)
  • Immich ML -> 正常

解决方案 Part - 2

互联网搜索,发现已经有很多参考: link

方案 一句话描述 优点 缺点 适用场景
① 手动删除 DROP 规则 iptables -D ts-input ... 立即生效 每次重启 Tailscale 会恢复 临时调试
② 顶部插入白名单规则 iptables -I ts-input ... 允许 100.100.2.136 对业务无感 规则可能被 Tailscale 覆盖 单台机器、不频繁重启
③ 脚本轮询维护 cron 每分钟检查并修复 自动化 系统复杂度增加 多台机器、能写脚本
④ 改走公共 DNS /etc/resolv.conf 换成 8.8.8.8、1.1.1.1 根治冲突 无法解析阿里云内网域名,OSS、RDS 内网地址失效 不使用阿里云内网产品
⑤ 关闭 Tailscale 防火墙 tailscale up --netfilter-mode=off 不碰 iptables 失去子网路由、exit-node 等高级功能 仅做点对点互联

我选择方案 3,约等于没有缺点。

edit : /usr/local/bin/fix-ts-dns.sh

1
2
3
4
5
6
7
#!/bin/bash
while true; do
  if ! iptables -C ts-input -s 100.100.2.136/32 -j ACCEPT 2>/dev/null; then
    iptables -I ts-input 1 -s 100.100.2.136/32 -j ACCEPT
  fi
  sleep 30
done

edit: /etc/systemd/system/fix-ts-dns.service

1
2
3
4
5
6
7
8
9
[Unit]
Description=Keep Aliyun DNS whitelist in Tailscale chain
After=tailscaled.service
[Service]
Type=simple
ExecStart=/usr/local/bin/fix-ts-dns.sh
Restart=always
[Install]
WantedBy=multi-user.target

这次故障是典型的云厂商内网规划与 Overlay 网络地址冲突。在使用 Tailscale、ZeroTier 等虚拟组网工具时,如果云厂商使用了 100.64.0.0/10 范围内的保留地址作为基础服务(如 DNS、NTP、元数据服务器),就会发生这种“流量黑洞”。

避坑指南: 在阿里云、腾讯云等环境部署 Tailscale 时,务必检查宿主机的 DNS 地址。如果发现是 100.x.y.z 开头,立刻手动指定公网 DNS,防止路由冲突。

Licensed under CC BY-NC-SA 4.0
长夜如此温柔,我该用什么把你留住


© Licensed Under CC BY-NC-SA 4.0


蜀ICP备2024113293号