帶有 docker 的 site2site 線衛:路由問題
免責聲明:從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 - 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
這看起來像一個路由問題。
192.168.1.0/24 via 172.17.0.5 dev docker0
這條路線沒有提示首選源地址。因此,主機自然會選擇最接近的匹配地址:172.17.0.1,因為它是docker0上的主地址。172.17.0.1 不在對等方的 WireGuard 的 AllowedIPs 列表中(也不必如此),因此會被 WireGuard 拒絕。如果它沒有被拒絕,那麼由於兩個獨立的 LAN 使用相同的 IP 地址塊,對等點無論如何都會出現路由問題。
試試這個
- 系統一
ip route replace 192.168.1.0/24 via 172.17.0.5 dev docker0 src 192.168.10.100
- 系統 2
ip route replace 192.168.10.0/24 via 172.17.0.6 dev docker0 src 192.168.1.100
請注意,在此調整之前,這應該不會影響其餘的 LAN,只會影響兩個 Docker 主機系統。