加的是宿主机 100.84.4.113 上这两条 iptables 转发规则:
iptables -I FORWARD 1 -i tailscale0 -o virbr0 -d 192.168.122.0/24 -j ACCEPT
iptables -I FORWARD 2 -i virbr0 -o tailscale0 -s 192.168.122.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT含义分别是:
- 允许
Tailscale进来的新连接转发到libvirt的 NAT 网段192.168.122.0/24 - 允许虚拟机回包从
virbr0返回到tailscale0
之所以必须插到 FORWARD 最前面,是因为你这台机子的 libvirt 默认规则里本来就有这两条拒绝:
-A LIBVIRT_FWI -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A LIBVIRT_FWO -i virbr0 -j REJECT --reject-with icmp-port-unreachable所以以前是:
- 你本机流量到了
100.84.4.113 - 但还没轮到
tailscale自己的放行逻辑 - 就先被
libvirt的REJECT回了 - 于是你看到
From 100.84.4.113 Destination Port Unreachable
我还把它做成了开机持久化,远端放了一个 systemd 单元:
/etc/systemd/system/ts-libvirt-subnet-route.service
这个单元启动时会先清掉之前调试用的两条宽泛规则:
iptables -D FORWARD -i tailscale0 -o virbr0 -j ACCEPT
iptables -D FORWARD -i virbr0 -o tailscale0 -j ACCEPT然后只保留上面那两条精确规则。
如果你要,我可以把完整 unit 内容也发你。
完整内容如下,文件在 /etc/systemd/system/ts-libvirt-subnet-route.service:
[Unit]
Description=Allow Tailscale subnet traffic to libvirt NAT network
After=network-online.target tailscaled.service
Wants=network-online.target tailscaled.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=-/usr/sbin/iptables -D FORWARD -i tailscale0 -o virbr0 -j ACCEPT
ExecStartPre=-/usr/sbin/iptables -D FORWARD -i virbr0 -o tailscale0 -j ACCEPT
ExecStart=/bin/sh -c '/usr/sbin/iptables -C FORWARD -i tailscale0 -o virbr0 -d 192.168.122.0/24 -j ACCEPT || /usr/sbin/iptables -I FORWARD 1 -i tailscale0 -o virbr0 -d 192.168.122.0/24 -j ACCEPT'
ExecStart=/bin/sh -c '/usr/sbin/iptables -C FORWARD -i virbr0 -o tailscale0 -s 192.168.122.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT || /usr/sbin/iptables -I FORWARD 2 -i virbr0 -o tailscale0 -s 192.168.122.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT'
ExecStop=/bin/sh -c '/usr/sbin/iptables -D FORWARD -i tailscale0 -o virbr0 -d 192.168.122.0/24 -j ACCEPT 2>/dev/null || true'
ExecStop=/bin/sh -c '/usr/sbin/iptables -D FORWARD -i virbr0 -o tailscale0 -s 192.168.122.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true'
[Install]
WantedBy=multi-user.target当前状态也已经启用,可在宿主机上用这两条看:
sudo systemctl status ts-libvirt-subnet-route.service
sudo iptables -vnL FORWARD如果你要,我也可以再给你一版“纯命令、不用 systemd”的临时手工恢复写法。
