ワークステーションに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
ルートは次のようになります(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
コンテナからテストpingを送信すると、いくつかの既存のmasqルールが表示され、最初のルールのパケットカウンターが増加します。
[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
最後に、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
編集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
コンテナーを分離するために--icc=false
フラグを使用してDockerデーモンを実行していることに注目してください。
私はpython iptablesエントリをインストールするipsecをラップするプログラムを作成して、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 }"
。このdefaultRouteInterfaceを呼び出しますSudo 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}"
@ChristopherBrichfordの答えに基づいて、私は数式を以下のコマンドにまで煮詰めました。これは、関係するさまざまな可動部分についての私の限られた理解に基づいています。
Sudo iptables -j SNAT -t nat -I POSTROUTING 1 \
-o $(ip route show | grep -e "^default" | awk -- "{ print \$5 }") \
-d $(ip route list table 220 | grep -o '^[0-9.]*/[0-9]*') \
-s $(ip route show | grep -e ":space:dev:space:docker" | awk -- "{ print \$1 }") \
--to-source $(ifconfig | grep -o 'P-t-P:[^ ]*' | cut -d: -f2)
より使いやすく、更新されたバージョンは 要点として利用可能 です。