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

无法实现物理Linux服务器与另一物理服务器上Docker容器的双向IP转发

无法实现物理Linux服务器与另一物理服务器上Docker容器的双向IP转发

场景与拓扑

我有三台服务器:

  • 物理服务器A、B:处于同一物理子网
  • 虚拟服务器C:运行在B上的WireGuard Docker容器,通过bridge网络驱动连接到B

网络参数明细

设备网卡/网络IP地址
服务器Aeth110.0.0.2
服务器Beth1
br-XXX(Docker网桥)
10.0.0.1
10.10.10.1
服务器Cwg0
eth0
10.0.1.1
10.10.10.2

子网划分:

  • 10.0.0.0/24:A和B的物理子网
  • 10.10.10.0/16:B的Docker网桥子网
  • 10.0.1.0/24:WireGuard容器C的专属子网

目标

通过服务器B做路由器,不使用NAT的前提下实现双向连通:

  • 服务器A(10.0.0.2)能ping通服务器C(10.0.1.1)
  • 服务器C(10.0.1.1)能ping通服务器A(10.0.0.2)

当前问题与已做配置

  • 现状:B可以ping通A和C,C能ping通B,但A、C之间无法互相ping通,tcpdump甚至抓不到ICMP包
  • 已完成的配置:
    • 所有设备防火墙允许10.0.0.0/24、10.0.1.0/24的所有ICMP/TCP/UDP流量,以及全量出站流量
    • 服务器A已添加路由:10.0.1.0/24 via 10.0.0.1 dev eth1
    • 所有服务器已开启IPv4转发(sysctl net.ipv4.ip_forward=1)

排查与解决方案

从你的情况来看,核心问题大概率出在Docker网桥的默认转发限制和容器C的回程路由缺失上,我帮你梳理下分步解决步骤:

1. 给容器C添加回程路由

容器C目前只知晓自己的WireGuard子网和Docker网桥子网,完全不知道10.0.0.0/24物理子网的存在,所以收到A的ping请求后,根本不知道该把回复发给谁。你需要在C内添加一条路由:

# 直接在容器C中执行
ip route add 10.0.0.0/24 via 10.10.10.1 dev eth0

如果是用Docker Compose部署,想要让这条路由持久化,修改docker-compose.yml即可:

services:
  wireguard:
    # 你的原有配置(镜像、端口等)
    cap_add:
      - NET_ADMIN  # 必须添加该权限才能修改路由
    command: sh -c "ip route add 10.0.0.0/24 via 10.10.10.1 dev eth0 && wg-quick up wg0"

2. 放开Docker网桥的iptables转发限制

Docker默认会给bridge网络添加iptables规则拦截跨网流量,就算你开启了系统的IPv4转发,也可能被Docker的规则拦住。先在B上查看Docker的USER链规则:

iptables -L DOCKER-USER -n

如果看不到允许10.0.0.0/24与10.10.10.0/16之间转发的规则,手动添加:

# 允许物理子网到Docker网桥的流量
iptables -A DOCKER-USER -s 10.0.0.0/24 -d 10.10.10.0/16 -j ACCEPT
# 允许Docker网桥到物理子网的流量
iptables -A DOCKER-USER -s 10.10.10.0/16 -d 10.0.0.0/24 -j ACCEPT
# 保存规则避免重启失效(不同系统命令有差异)
# Debian/Ubuntu 用这条
netfilter-persistent save
# RHEL/CentOS 用这条
iptables-save > /etc/sysconfig/iptables

3. 确认服务器B的路由表

虽然B能ping通两边,但还是要确认它的路由表知晓10.0.1.0/24子网的存在。在B上执行:

ip route show

应该能看到类似10.0.1.0/24 via 10.10.10.2 dev br-XXX的路由(br-XXX是你的Docker网桥名称)。如果没有,手动添加:

ip route add 10.0.1.0/24 via 10.10.10.2 dev br-XXX

4. 抓包验证流量走向

完成以上配置后,你可以在三个节点同时开启tcpdump抓ICMP包,定位流量卡滞的环节:

  • 在A上:tcpdump -i eth1 icmp
  • 在B上:开两个终端,分别执行tcpdump -i eth1 icmp 和 tcpdump -i br-XXX icmp
  • 在C上:开两个终端,分别执行tcpdump -i eth0 icmp 和 tcpdump -i wg0 icmp

然后从A ping C,正常流程应该是:

  1. A发送请求到B的10.0.0.1
  2. B转发请求到C的10.10.10.2
  3. C收到后,将回复发给B的10.10.10.1
  4. B再转发回复到A的10.0.0.2

哪一步没有流量,就针对性排查该节点的防火墙或路由配置即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 09:13:01