树莓派4上Docker部署的WireGuard无法从局域网外部连接
WireGuard Docker容器外网无法连接(UDP 51820端口不通)排查
树莓派4全新安装Raspbian系统,通过Docker部署Portainer,并用wg-easy搭建WireGuard VPN服务器。路由器已转发UDP 51820端口(Portainer的9000端口已验证可外网访问),但WireGuard无法从局域网外连接,且51820端口检测为关闭状态。
收集的系统信息
网络路由信息
pi@raspberrypi:~ $ ip route default via 192.168.100.1 dev eth0 proto dhcp src 192.168.100.3 metric 100 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 172.18.0.0/16 dev br-4911ad3199ee proto kernel scope link src 172.18.0.1 192.168.100.0/24 dev eth0 proto kernel scope link src 192.168.100.3 metric 100
iptables过滤表(-L -v)输出
sudo iptables -L -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 196K 48M DOCKER-USER all -- any any anywhere anywhere 196K 48M DOCKER-ISOLATION-STAGE-1 all -- any any anywhere anywhere 23135 20M ACCEPT all -- any docker0 anywhere anywhere ctstate RELATED,ESTABLISHED 159 8284 DOCKER all -- any docker0 anywhere anywhere 18618 9665K ACCEPT all -- docker0 !docker0 anywhere anywhere 0 0 ACCEPT all -- docker0 docker0 anywhere anywhere 170K 31M ACCEPT all -- any br-4911ad3199ee anywhere anywhere ctstate RELATED,ESTABLISHED 6041 362K DOCKER all -- any br-4911ad3199ee anywhere anywhere 14320 5318K ACCEPT all -- br-4911ad3199ee !br-4911ad3199ee anywhere anywhere 6025 362K ACCEPT all -- br-4911ad3199ee br-4911ad3199ee anywhere anywhere Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain DOCKER (2 references) pkts bytes target prot opt in out source destination 4 176 ACCEPT tcp -- !br-4911ad3199ee br-4911ad3199ee anywhere 172.18.0.2 tcp dpt:2016 12 576 ACCEPT tcp -- !br-4911ad3199ee br-4911ad3199ee anywhere 172.18.0.2 tcp dpt:2015 51 2668 ACCEPT tcp -- !docker0 docker0 anywhere 172.17.0.3 tcp dpt:9000 0 0 ACCEPT tcp -- !br-4911ad3199ee br-4911ad3199ee anywhere 172.18.0.4 tcp dpt:https 0 0 ACCEPT tcp -- !br-4911ad3199ee br-4911ad3199ee anywhere 172.18.0.4 tcp dpt:http 18 936 ACCEPT tcp -- !docker0 docker0 anywhere 172.17.0.2 tcp dpt:51821 0 0 ACCEPT udp -- !docker0 docker0 anywhere 172.17.0.2 udp dpt:51820 Chain DOCKER-ISOLATION-STAGE-1 (1 references) pkts bytes target prot opt in out source destination 18618 9665K DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 anywhere anywhere 14320 5318K DOCKER-ISOLATION-STAGE-2 all -- br-4911ad3199ee !br-4911ad3199ee anywhere anywhere 234K 70M RETURN all -- any any anywhere anywhere Chain DOCKER-ISOLATION-STAGE-2 (2 references) pkts bytes target prot opt in out source destination 0 0 DROP all -- any docker0 anywhere anywhere 0 0 DROP all -- any br-4911ad3199ee anywhere anywhere 33363 18M RETURN all -- any any anywhere anywhere Chain DOCKER-USER (1 references) pkts bytes target prot opt in out source destination 234K 70M RETURN all -- any any anywhere anywhere
注:TCP 51821端口有数据包(局域网内可正常访问WireGuard控制面板),但UDP 51820端口数据包为0
iptables NAT表(-L -v -t nat)输出
pi@raspberrypi:~ $ sudo iptables -L -v -t nat Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 23948 1932K DOCKER all -- any any anywhere anywhere ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DOCKER all -- any any anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 135 9290 MASQUERADE all -- any !docker0 172.17.0.0/16 anywhere 233 15196 MASQUERADE all -- any !br-4911ad3199ee 172.18.0.0/16 anywhere 0 0 MASQUERADE tcp -- any any 172.18.0.2 172.18.0.2 tcp dpt:2016 0 0 MASQUERADE tcp -- any any 172.18.0.2 172.18.0.2 tcp dpt:2015 0 0 MASQUERADE tcp -- any any 172.17.0.3 172.17.0.3 tcp dpt:9000 0 0 MASQUERADE tcp -- any any 172.18.0.4 172.18.0.4 tcp dpt:https 0 0 MASQUERADE tcp -- any any 172.18.0.4 172.18.0.4 tcp dpt:http 0 0 MASQUERADE tcp -- any any 172.17.0.2 172.17.0.2 tcp dpt:51821 0 0 MASQUERADE udp -- any any 172.17.0.2 172.17.0.2 udp dpt:51820 Chain DOCKER (2 references) pkts bytes target prot opt in out source destination 0 0 RETURN all -- docker0 any anywhere anywhere 0 0 RETURN all -- br-4911ad3199ee any anywhere anywhere 4 176 DNAT tcp -- !br-4911ad3199ee any anywhere anywhere tcp dpt:2016 to:172.18.0.2:2016 11 528 DNAT tcp -- !br-4911ad3199ee any anywhere anywhere tcp dpt:2015 to:172.18.0.2:2015 51 2668 DNAT tcp -- !docker0 any anywhere anywhere tcp dpt:9000 to:172.17.0.3:9000 0 0 DNAT tcp -- !br-4911ad3199ee any anywhere anywhere tcp dpt:20443 to:172.18.0.4:443 0 0 DNAT tcp -- !br-4911ad3199ee any anywhere anywhere tcp dpt:20080 to:172.18.0.4:80 17 884 DNAT tcp -- !docker0 any anywhere anywhere tcp dpt:51821 to:172.17.0.2:51821 0 0 DNAT udp -- !docker0 any anywhere anywhere udp dpt:51820 to:172.17.0.2:51820
WireGuard配置文件(wg0.conf)
# Server [Interface] PrivateKey = ____________ Address = 10.8.0.1/24 ListenPort = 51820 PreUp = PostUp = iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -A INPUT -p udp -m udp --dport 51820 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; PreDown = PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -D INPUT -p udp -m udp --dport 51820 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; # Client: ____________ [Peer] PublicKey = ___________ PresharedKey = _____________ AllowedIPs = 10.8.0.2/32
其他配置
已开启IPv4转发:
net.ipv4.ip_forward = 1
排查步骤
验证路由器端口转发规则
- 确认规则协议为UDP,目标IP是树莓派局域网IP(192.168.100.3),内外端口均为51820
- 重启路由器,确保规则生效
测试树莓派本地UDP连通性
- 在树莓派上执行
nc -ul 51820监听UDP端口 - 从外网设备执行
nc -u <你的公网IP> 51820发送测试数据 - 若树莓派无接收,说明数据包未到达设备;若有接收,问题出在Docker转发环节
- 在树莓派上执行
检查Docker容器端口映射
- 执行
docker ps查看wg-easy容器的端口映射,确认包含0.0.0.0:51820->51820/udp - 若缺失UDP映射,停止容器后重新启动,添加
-p 51820:51820/udp参数
- 执行
验证容器内WireGuard状态
- 进入容器:
docker exec -it <wg-easy容器ID> bash - 检查服务状态:
wg show wg0,确认监听端口为51820 - 在容器内执行
nc -ul 51820,从树莓派本地执行nc -u 172.17.0.2 51820发送数据,验证容器是否能接收
- 进入容器:
调整iptables规则优先级
- 手动在DOCKER-USER链添加允许规则:
sudo iptables -I DOCKER-USER -p udp --dport 51820 -j ACCEPT - 添加后重新测试外网连接
- 手动在DOCKER-USER链添加允许规则:
确认公网IP类型
- 执行
curl ifconfig.me获取公网IP,对比路由器WAN口IP - 若两者不一致,说明是运营商CGNAT,需联系运营商获取公网IP或使用穿透服务
- 执行
内容的提问来源于stack exchange,提问作者Kenny
相关产品推荐
相关产品推荐

