我想设置一个 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 转发
[在wireguard配置文件中]
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
容器:
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
答案1
我想到了。谢谢@user1794469,你的评论让我走上了正轨。
问题是 docker 容器内的接口 eth0 与客户端和默认不在同一子网中规则是查找wg-quick
启动Wireguard接口时创建的路由表“51820”。
因此,请求已成功转发到 - 并通过 Wireguard 接口发送,但由于客户端的 IP 不在容器已知的子网中,因此响应被视为属于 WAN(互联网)的任何其他数据包,并且也通过 Wireguard 接口发送。
请求:客户[eth0]->[eth0]主持人[br-b1b1ac41a7f9]-> 集装箱[eth0][网络地址转换][工作组0] -> ... -> WAN
响应:WAN -> ... ->[工作组0]容器[工作组0]-> ... -> 广域网
您只需通过 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
另一种方法是在主机上设置 NAT 伪装:
$ iptables -t nat -I POSTROUTING -o <container_bridge_interface> -j MASQUERADE
在这个例子中:
$ iptables -t nat -I POSTROUTING -o br-b1b1ac41a7f9 -j MASQUERADE