本帖最后由 Komeiji小五 于 2026-8-30 02:43 编辑
省流——快速解决方案
- # 写入脚本
- cat > /usr/local/bin/fix-ts-dns.sh << 'EOF'
- #!/bin/bash
- while true; do
- if ! iptables -C ts-input -s 100.100.2.0/24 -i eth0 -j ACCEPT 2>/dev/null; then
- iptables -I ts-input 1 -s 100.100.2.0/24 -i eth0 -j ACCEPT
- fi
- sleep 30
- done
- EOF
- #添加权限
- chmod +x /usr/local/bin/fix-ts-dns.sh
- # 写入 systemd 服务
- cat > /etc/systemd/system/fix-ts-dns.service << 'EOF'
- [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
- EOF
- #运行
- systemctl daemon-reload
- systemctl enable --now fix-ts-dns.service
复制代码
问题现象在阿里云 ECS(VPC 网络)上安装并启动 Tailscale 后,服务器出现”失联”:SSH 能连但 curl、apt update 全部超时,ping 外网 IP 却通。
原理
RFC 6598 与 CGNAT100.64.0.0/10 是 RFC 6598 保留的运营商级 NAT(CGNAT)地址段,ISP 用于大规模 NAT 时避免与内网冲突。
冲突根源Tailscale:启动后在 iptables 的 ts-input 链插入一条规则: 含义:源地址落在 CGNAT 段、但不从 tailscale0 虚拟网卡进入的流量,全部丢弃。这是合规范的防御策略。 - -A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP
复制代码
阿里云:VPC 内网将 100.100.2.0/24 网段用作内部服务地址,包括:
- DNS 服务器:100.100.2.136、100.100.2.138
- 镜像源:100.100.2.158(mirrors.cloud.aliyuncs.com)
100.100.x.x 正好落在 100.64.0.0/10 范围内,阿里云内网服务的所有回复数据包都被 Tailscale 防火墙误杀。
为什么 ping 外网 IP 通但 curl 不通ping 8.8.8.8 是 ICMP 协议,源 IP 是公网地址,不在 100.64.0.0/10 范围内,不被拦截。 而 curl / apt 需要先做 DNS 解析 —— 阿里云 DNS 回复的 UDP 包源地址是 100.100.2.136,被 Tailscale 丢弃,DNS 超时导致整个请求失败。
踩坑过程:为什么 DNS 白名单不够查了一些资料后,第一版方案是只放行两台 DNS 服务器的 IP: - iptables -I ts-input 1 -s 100.100.2.136/32 -j ACCEPT
- iptables -I ts-input 1 -s 100.100.2.138/32 -j ACCEPT
复制代码
结果如下: - # DNS 解析恢复了
- $ dig @100.100.2.136 mirrors.cloud.aliyuncs.com +short
- 100.100.2.158
- # 但实际下载仍超时
- $ curl -I http://mirrors.cloud.aliyuncs.com
- curl: (28) Connection timed out
- # 路由正常,走 eth0,不是 tailscale0
- $ ip route get 100.100.2.158
- 100.100.2.158 via 172.16.79.253 dev eth0
复制代码
只救了 DNS 解析,但镜像源返回的 TCP 数据包(HTTP 80/443)同样来自 100.100.2.0/24 网段,照样被 ts-input 的 DROP 规则丢掉。只放行 DNS IP 不够,镜像源一样被卡。
最终方案:子网白名单 + systemd 守护将白名单从两个精确 IP 扩展到整个 /24 子网,一次性放通阿里云 VPC 内网所有服务(DNS + 镜像源 + OSS + RDS 内网地址等),同时 Tailscale 防火墙对其他 CGNAT 流量仍然有效,安全无损。
第 1 步:创建守护脚本/usr/local/bin/fix-ts-dns.sh - #!/bin/bash
- while true; do
- if ! iptables -C ts-input -s 100.100.2.0/24 -i eth0 -j ACCEPT 2>/dev/null; then
- iptables -I ts-input 1 -s 100.100.2.0/24 -i eth0 -j ACCEPT
- fi
- sleep 30
- done
复制代码
如果网卡名不是 eth0(极少数机型),先执行 ip addr 确认后替换。 脚本每 30 秒检查 ts-input 链顶部是否存在白名单规则,不存在就自动插入。即使 tailscaled 重启或更新后删除规则,最多 30 秒就能自动修复。 限定 -i eth0 确保仅放行从 VPC 内网网卡进入的 100.100.2.0/24 流量。如果某台 Tailscale 节点恰好也分配了该网段的 IP,其从其他接口进入的流量不受影响,仍走 Tailscale 原有的安全策略。
第 2 步:创建 systemd 服务/etc/systemd/system/fix-ts-dns.service - [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
复制代码
依赖 tailscaled.service,确保 Tailscale 先启动、脚本后启动。Restart=always 保证脚本异常退出后自动拉起。
第 3 步:部署
- chmod +x /usr/local/bin/fix-ts-dns.sh
- systemctl daemon-reload
- systemctl enable --now fix-ts-dns.service
复制代码 第 4 步:验证
- # DNS 解析
- $ dig @100.100.2.136 mirrors.cloud.aliyuncs.com +short
- 100.100.2.158
- # 外网连通
- $ curl -I http://mirrors.cloud.aliyuncs.com
- HTTP/1.1 200 OK
- # 镜像源可用
- $ apt update
- Hit:1 http://mirrors.cloud.aliyuncs.com/ubuntu jammy InRelease
- ...
- # Tailscale 功能正常
- $ tailscale status
- # 节点列表正常显示
- # 规则持久化测试 — 重启 Tailscale 后确认规则自动恢复
- $ systemctl restart tailscaled
- $ sleep 35
- $ iptables -S ts-input | head -1
- -A ts-input -s 100.100.2.0/24 -i eth0 -j ACCEPT
复制代码
为什么这个方案是安全的- 仅放行 100.100.2.0/24(阿里云 VPC 内网段),其余 100.64.0.0/10 范围内的流量仍被 Tailscale 拦截
- 限定 -i eth0,即使某台 Tailscale 节点恰好分配了该网段 IP,其从非 VPC 网卡进入的流量不会被白名单误放行
- 未关闭 Tailscale 防火墙(--netfilter-mode=off),子网路由和 exit-node 功能保留
- 未改用公共 DNS,阿里云内网域名(OSS、RDS 等)解析不受影响,不产生额外公网流量费用
- systemd 守护机制保证重启不丢失规则
|