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

树莓派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

排查步骤

  1. 验证路由器端口转发规则

    • 确认规则协议为UDP,目标IP是树莓派局域网IP(192.168.100.3),内外端口均为51820
    • 重启路由器,确保规则生效
  2. 测试树莓派本地UDP连通性

    • 在树莓派上执行nc -ul 51820监听UDP端口
    • 从外网设备执行nc -u <你的公网IP> 51820发送测试数据
    • 若树莓派无接收,说明数据包未到达设备;若有接收,问题出在Docker转发环节
  3. 检查Docker容器端口映射

    • 执行docker ps查看wg-easy容器的端口映射,确认包含0.0.0.0:51820->51820/udp
    • 若缺失UDP映射,停止容器后重新启动,添加-p 51820:51820/udp参数
  4. 验证容器内WireGuard状态

    • 进入容器:docker exec -it <wg-easy容器ID> bash
    • 检查服务状态:wg show wg0,确认监听端口为51820
    • 在容器内执行nc -ul 51820,从树莓派本地执行nc -u 172.17.0.2 51820发送数据,验证容器是否能接收
  5. 调整iptables规则优先级

    • 手动在DOCKER-USER链添加允许规则:
      sudo iptables -I DOCKER-USER -p udp --dport 51820 -j ACCEPT
      
    • 添加后重新测试外网连接
  6. 确认公网IP类型

    • 执行curl ifconfig.me获取公网IP,对比路由器WAN口IP
    • 若两者不一致,说明是运营商CGNAT,需联系运营商获取公网IP或使用穿透服务

内容的提问来源于stack exchange,提问作者Kenny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:30:55