Rob*_*bin 3 vpn route iptables docker
我的工作站上有 Docker 和 IPSEC VPN 隧道,但容器无法访问 VPN 后面的主机。有什么我可以做的,例如使用 IPTables 或允许访问的路由吗?[注意:我目前正在 libvirt 托管的 VM 中运行这些测试,然后 libvirt 网桥的地址为 192.168.122.1]
我的网络设置如下所示:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:0f:f2:bb brd ff:ff:ff:ff:ff:ff
inet 192.168.122.87/24 brd 192.168.122.255 scope global dynamic ens3
valid_lft 3490sec preferred_lft 3490sec
inet6 fe80::5054:ff:fe0f:f2bb/64 scope link
valid_lft forever preferred_lft forever
3: tap0: <BROADCAST,UP,LOWER_UP> mtu 1380 qdisc pfifo_fast state UNKNOWN qlen 500
link/ether d6:2b:f6:24:c5:1c brd ff:ff:ff:ff:ff:ff
inet 172.20.1.29/24 brd 172.20.1.255 scope global tap0
valid_lft forever preferred_lft forever
inet6 fe80::d42b:f6ff:fe24:c51c/64 scope link
valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:24:7f:6a:1a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:24ff:fe7f:6a1a/64 scope link
valid_lft forever preferred_lft forever
Run Code Online (Sandbox Code Playgroud)
我的路由看起来像这样(VPN 端点 IP 混淆了):
default via 192.168.122.1 dev ens3 proto static metric 100
10.0.0.0/8 via 172.20.1.29 dev tap0 proto static
10.11.12.13 via 192.168.122.1 dev ens3 proto static
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.20.1.0/24 dev tap0 proto kernel scope link src 172.20.1.29
192.168.122.0/24 dev ens3 proto kernel scope link src 192.168.122.87 metric 100
Run Code Online (Sandbox Code Playgroud)
我可以看到一些现有的 masq 规则,当我从容器发送测试 ping 时,第一个规则上的数据包计数器会增加:
[robin@rhel72 ~]$ sudo iptables -t nat -L -n -v --line-numbers | sed -n '/^Chain POSTROUTING /,/^$/ p'
Chain POSTROUTING (policy ACCEPT 4 packets, 534 bytes)
num pkts bytes target prot opt in out source destination
1 63 4290 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
2 473 30282 POSTROUTING_direct all -- * * 0.0.0.0/0 0.0.0.0/0
3 473 30282 POSTROUTING_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
4 473 30282 POSTROUTING_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
Run Code Online (Sandbox Code Playgroud)
最后,当我ping -c1
从容器内部运行 tcpdump 连接时,我可以看到看起来像部分响应的内容:
[robin@rhel72 ~]$ sudo tcpdump -i any -n 'icmp'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
09:55:01.919214 IP 172.17.0.2 > 10.60.1.201: ICMP echo request, id 27, seq 1, length 64
09:55:01.919214 IP 172.17.0.2 > 10.60.1.201: ICMP echo request, id 27, seq 1, length 64
09:55:01.940613 IP 10.60.1.201 > 172.20.1.29: ICMP echo reply, id 27, seq 1, length 64
Run Code Online (Sandbox Code Playgroud)
编辑 1
Docker 容器内的路由表是:
[root@451c1c9c708c /]# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
Run Code Online (Sandbox Code Playgroud)
值得注意的是,我正在运行 Docker 守护进程,使用该--icc=false
标志来隔离容器。
我编写了一个 python 程序来包装 ipsec,它安装 iptables 条目以允许 docker 容器与 VPN 隧道通信:
https://github.com/cbrichford/docker-ipsec
而不是做:
ipsec up
你做:
docker-ipsec up
此脚本可能需要一些工作才能与最新的 docker 网络功能一起使用,但与旧的默认docker0
网桥一起使用。
如果你不想使用我的脚本来编辑 iptables,这里是你构造 iptables 命令的方法:
sudo ip route show | grep -e "^default" | awk -- "{ print \$5 }"
. 调用这个 defaultRouteInterfacesudo ip route show | grep -e "[[:space:]]dev[[:space:]]docker" | awk -- "{ print \$1 }"
。调用此 dockerSubnet。您需要运行的 iptables 命令是:
sudo \
iptables \
-j SNAT \
-t nat \
-I POSTROUTING 1 \
-o ${defaultRouteInterface} \
-d "${vpnSubnet}" \
-s "${dockerSubnet}" \
--to-source "${virtualIP}"
归档时间: |
|
查看次数: |
7687 次 |
最近记录: |