You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ZeroTier路由环境下CentOS 7 VPS中Docker部署的dnsmasq容器无法外部访问

ZeroTier路由环境下CentOS 7 VPS中Docker部署的dnsmasq容器无法外部访问

我之前在ZeroTier路由到本地的场景下踩过dnsmasq的坑,太懂这种明明配置看起来和其他服务一样,就是访问不了的抓狂感!咱们一步步来排查解决:

1. 先补全SNAT规则(最可能的核心问题)

你现在只加了PREROUTING的DNAT规则,把ZeroTier过来的流量转去127.0.0.1,但返回的数据包源地址是127.0.0.1,ZeroTier客户端收到后会直接丢弃——因为它请求的是VPS的ZeroTier IP,结果返回包的源是本地回环地址,完全不匹配。

解决办法是加一条POSTROUTING的SNAT规则,把从回环接口发向ZeroTier子网的流量,源地址改成VPS的ZeroTier接口IP:

# 先获取你的ZeroTier接口IP
ZT_IP=$(ip addr show ztyxa6sxte | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)
# 替换成你的ZeroTier子网,比如常见的192.168.192.0/24
ZT_SUBNET="192.168.192.0/24"
# 加SNAT规则
sudo iptables -t nat -A POSTROUTING -o lo -d $ZT_SUBNET -j SNAT --to-source $ZT_IP

2. 调整iptables规则的顺序,避免被Docker规则覆盖

Docker会自动往iptables里塞一堆规则,如果你用-A追加PREROUTING规则,很大概率排在Docker规则后面,导致流量还没走到你的规则就被Docker的链处理了。改成用-I把规则插入到最前面:

sudo iptables -t nat -I PREROUTING -i ztyxa6sxte -j DNAT --to-destination 127.0.0.1

3. 检查Firewalld是否在搞事情

CentOS7默认开的firewalld经常偷偷拦截转发流量,先临时关了测试下:

sudo systemctl stop firewalld

如果关了之后能访问了,那给ZeroTier接口加个信任区规则,再重新开firewalld:

sudo firewall-cmd --add-interface=ztyxa6sxte --zone=trusted --permanent
sudo firewall-cmd --reload
sudo systemctl start firewalld

4. 确认容器内部的dnsmasq确实在监听所有接口

虽然你Docker端口绑的是127.0.0.1,但容器内部的dnsmasq如果只监听自身回环地址的话,主机转进去的流量也接不到。进容器看看:

docker exec -it dns netstat -tulpn | grep 53

如果输出里只有127.0.0.1:53,那去你的/etc/dnsmasq/dnsmasq.conf里加一行:

listen-address=0.0.0.0

然后重启容器:docker restart dns

最后测试

先测webUI:用ZeroTier客户端机器访问http://<VPS的ZT IP>:5380,如果能进登录界面,说明转发没问题;再测DNS:用dig @<VPS的ZT IP> example.com或者nslookup example.com <VPS的ZT IP>,看能不能返回解析结果。

对了,这些iptables规则重启后会消失,要是想永久保存,记得装iptables-services,然后保存规则:

sudo yum install -y iptables-services
sudo systemctl stop firewalld
sudo systemctl enable iptables
sudo service iptables save

备注:内容来源于stack exchange,提问作者Nikita Melnikov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 11:28:17