Iptables

Docker 容器作為網路網關ñotrespond我__ñ○噸r和sp○nd一世nGNot responding

  • October 21, 2020

我想設置一個 Wireguard Docker 容器作為網路網關。

我的設置如下所示:

Client (user-Virtual-Machine) | IP: 172.22.100.157  
Host (user-Virtual-Machine) | IP: 172.22.105.35  
Docker container (from linuxserver/wireguard) | IP: 172.16.238.10  

到目前為止我所做的:

客戶:

# Replace the default route with the hosts's IP
$ ip route replace default via 172.22.105.35

主持人:

$ sysctl net.ipv4.conf.all.forwarding true

# Define default route in a new routing table
$ ip route add default via 172.16.238.10 table 200
# Requests for the docker network via the docker interface IP
$ ip route add 172.16.238.0/24 via 172.16.238.1 table 200
# Lookup new routing table for all request coming into the interface eth0 (from Client Network)
$ ip rule add iif eth0 lookup 200

$ iptables -t nat -I POSTROUTING -o br-06b8cf6f4319 -j MASQUERADE
$ iptables -I FORWARD -i eth0 -o br-06b8cf6f4319 -j ACCEPT

容器:

  • 此 docker 映像中預設啟用 IP 轉發

$$ In the wireguard config file $$

PostUp = iptables -t nat -A POSTROUTING -o  %i -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o  %i -j MASQUERADE

當我嘗試從客戶端 ping Web 伺服器時會發生這種情況:

客戶:

root@user-Virtual-Machine:~# ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
^C
--- 1.1.1.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

主持人:

root@user-Virtual-Machine:/home/user/docker# tcpdump -i br-b1b1ac41a7f9 -n -v
tcpdump: listening on br-b1b1ac41a7f9, link-type EN10MB (Ethernet), capture size 262144 bytes
15:48:06.413006 IP (tos 0x0, ttl 63, id 35526, offset 0, flags [DF], proto ICMP (1), length 84)
   172.22.100.157 > 1.1.1.1: ICMP echo request, id 35, seq 1, length 64
15:48:06.413170 IP (tos 0x0, ttl 64, id 52489, offset 0, flags [none], proto UDP (17), length 156)
   172.16.238.10.46677 > 195.181.170.67.443: UDP, length 128
15:48:06.435470 IP (tos 0x0, ttl 53, id 20187, offset 0, flags [DF], proto UDP (17), length 144)
   195.181.170.67.443 > 172.16.238.10.46677: UDP, length 116
15:48:06.435656 IP (tos 0x0, ttl 64, id 52492, offset 0, flags [none], proto UDP (17), length 156)
   172.16.238.10.46677 > 195.181.170.67.443: UDP, length 128
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel

在 Whireshark

容器:

root@5f21c444a297:/# tcpdump -n -v
tcpdump: listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes
13:06:38.860868 IP (tos 0x0, ttl 62, id 35630, offset 0, flags [DF], proto ICMP (1), length 84)
   100.64.67.64 > 1.1.1.1: ICMP echo request, id 19, seq 1, length 64
13:06:38.885219 IP (tos 0x0, ttl 59, id 10501, offset 0, flags [none], proto ICMP (1), length 84)
   1.1.1.1 > 100.64.67.64: ICMP echo reply, id 19, seq 1, length 64
13:06:38.885256 IP (tos 0x0, ttl 58, id 10501, offset 0, flags [none], proto ICMP (1), length 84)
   1.1.1.1 > 172.22.100.157: ICMP echo reply, id 19, seq 1, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel

我想到了。謝謝@user1794469,您的評論讓我走上了正軌。

問題是 docker 容器內的介面 eth0 與客戶端不在同一個子網上,預設規則是查找wg-quick啟動 Wireguard 介面時創建的路由表“51820”。

因此,請求被成功轉發到 - 並通過 Wireguard 介面發送,但由於客戶端的 IP 不在容器已知的子網中,因此響應被視為屬於 WAN(網際網路)的任何其他數據包,並且也是通過 Wireguard 介面發送的。

請求:客戶*$$ eth0 $$->$$ eth0 $$*主持人

$$ NAT $$ $$ br-b1b1ac41a7f9 $$-> 容器*$$ eth0 $$* $$ NAT $$ $$ wg0 $$ -> … -> WAN

響應:WAN -> … ->$$ wg0 $$容器$$ wg0 $$-> … -> 一個 要解決此問題,您只需通過 docker 容器的網關(主機上橋接介面的 IP)添加到客戶端所在子網的路由:

$ ip route
default via <Gateway> dev eth0

$ ip route add <Client subnet> via <Gateway>

PostUp但是,將其添加到Wireguard 配置文件的部分會更方便。這可能看起來像這樣:

PostUp = iptables -t nat -A POSTROUTING -o  %i -j MASQUERADE && ip route add 172.22.100.0/24 via 172.16.238.1
PostDown = iptables -t nat -D POSTROUTING -o  %i -j MASQUERADE && ip route delete 172.22.100.0/24 via 172.16.238.1

引用自:https://unix.stackexchange.com/questions/615255