免责声明:从stackoverflow转发:https ://stackoverflow.com/questions/67917278/site2site-wireguard-with-docker-routing-problems
我试图让两个容器在两个 RPI 上运行,充当网络 1 和网络 2 之间的站点到站点 VPN。
通过下面的设置,我可以从容器内相互ping通:
- 从 docker 容器 1 我可以 ping 一个地址 192.168.1.1
- 从 docker 容器 2 我可以 ping 地址 192.168.10.1
但是,如果我尝试从 System1 主机 (192.168.10.100) ping 192.168.1.1,则会出现错误(请参见下图以可视化我正在尝试执行的操作)。
我知道我必须在 system1 主机 (192.168.10.100) 上添加一个静态路由,以通过 wireguard 容器 (172.17.0.5) 引导 192.168.1.0/24 的流量,因此我运行:
$i p route add 192.168.1.0/24 via 172.17.0.5
$ ip route
default via 192.168.10.1 dev eth0 proto dhcp src 192.168.10.100 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-e19a4f1b7646 proto kernel scope link src 172.18.0.1 linkdown
172.19.0.0/16 dev br-19684dacea29 proto kernel scope link src 172.19.0.1
172.20.0.0/16 dev br-446863cf7cef proto kernel scope link src 172.20.0.1
172.21.0.0/16 dev br-6800ed9b4dd6 proto kernel scope link src 172.21.0.1 linkdown
172.22.0.0/16 dev br-8f8f439a7a28 proto kernel scope link src 172.22.0.1 linkdown
192.168.1.0/24 via 172.17.0.5 dev docker0
192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.100
192.168.10.1 dev eth0 proto dhcp scope link src 192.168.10.100 metric 100
但是对 192.168.1.1 的 ping 仍然失败。
通过在容器 2 上运行 tcpdump,我看到一些数据包确实到达了容器:
root@936de7c0d7eb:/# tcpdump -n -i any
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10:11:19.885845 IP [publicIPsystem1].56200 > 172.17.0.6.56100: UDP, length 128
10:11:30.440764 IP 172.17.0.6.56100 > [publicIPsystem1].56200: UDP, length 32
10:11:35.480625 ARP, Request who-has 172.17.0.1 tell 172.17.0.6, length 28
10:11:35.480755 ARP, Reply 172.17.0.1 is-at 02:42:24:e5:ac:38, length 28
所以我想这不是系统 1 上的路由问题。
谁能告诉我如何进一步诊断?
编辑1:
我做了以下测试:
- 在容器 2 上运行“tcpdump -ni any”
- 从系统 1(从主机系统)发送 ping 'ping -c 1 192.168.1.1。
在容器 2 上,tcpdump 记录以下内容:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
15:04:47.495066 IP [publicIPsystem1].56200 > 172.17.0.3.56100: UDP, length 128
15:04:58.120761 IP 172.17.0.3.56100 > [publicIPsystem1].56200: UDP, length 32
- 从容器(在容器内)发送 ping 'ping -c 1 192.168.1.1 。
在容器 2 上,tcpdump 记录以下内容:
# tcpdump -ni any
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
15:05:48.120717 IP [publicIPsystem1].56200 > 172.17.0.3.56100: UDP, length 128
15:05:48.120871 IP 10.13.18.2 > 192.168.1.1: ICMP echo request, id 747, seq 1, length 64
15:05:48.120963 IP 172.17.0.3 > 192.168.1.1: ICMP echo request, id 747, seq 1, length 64
15:05:48.121955 IP 192.168.1.1 > 172.17.0.3: ICMP echo reply, id 747, seq 1, length 64
15:05:48.122054 IP 192.168.1.1 > 10.13.18.2: ICMP echo reply, id 747, seq 1, length 64
15:05:48.122246 IP 172.17.0.3.56100 > [publicIPsystem1].56200: UDP, length 128
15:05:53.160617 ARP, Request who-has 172.17.0.1 tell 172.17.0.3, length 28
15:05:53.160636 ARP, Request who-has 172.17.0.3 tell 172.17.0.1, length 28
15:05:53.160745 ARP, Reply 172.17.0.3 is-at 02:42:ac:11:00:03, length 28
15:05:53.160738 ARP, Reply 172.17.0.1 is-at 02:42:24:e5:ac:38, length 28
15:05:58.672032 IP [publicIPsystem1].56200 > 172.17.0.3.56100: UDP, length 32
所以,似乎数据包的处理方式与容器 2 不同,具体取决于我目前缺少的东西。这可能是 iptables 问题吗?
站点 1 | 站点 2 | |
---|---|---|
网络 1 IP 范围 | 192.168.10.0/24 | 192.168.1.0/24 |
主机系统地址 | 192.168.10.100 | 192.168.1.100 |
桥 docker0 范围 | 172.17.0.0/16 | 172.17.0.0/16 |
容器地址 | 172.17.0.5 | 172.17.0.6 |
系统 1 - wg0.conf
[Interface]
Address = 10.13.18.2
PrivateKey = *privatekey*
ListenPort = 56200
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = *publickey*
Endpoint = *system2address*:56100
AllowedIPs = 10.13.18.1/32 , 192.168.1.0/24
系统 2 - wg0.conf
[Interface]
Address = 10.13.18.1
ListenPort = 56100
PrivateKey = *privatekey*
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# peer_casaleuven
PublicKey = *publickey*
AllowedIPs = 10.13.18.2/32 , 192.168.10.0/24
Endpoint = *system1address*:56200
这看起来像一个路由问题。
这条路线没有提示首选源地址。因此,主机自然会选择最接近的匹配地址:172.17.0.1,因为它是docker0上的主地址。172.17.0.1 不在对等方的 WireGuard 的 AllowedIPs 列表中(也不必如此),因此会被 WireGuard 拒绝。如果它没有被拒绝,那么由于两个独立的 LAN 使用相同的 IP 地址块,对等点无论如何都会出现路由问题。
尝试这个
系统一
系统 2
请注意,在此调整之前,这应该不会影响其余的 LAN,只会影响两个 Docker 主机系统。