web-dev-qa-db-ja.com

DockerコンテナがホストでIPSEC VPNを使用できるようにする

ワークステーションに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デーモンを実行していることに注目してください。

3
Robin

私はpython iptablesエントリをインストールするipsecをラップするプログラムを作成して、DockerコンテナーがVPNトンネルと通信できるようにしました:

https://github.com/cbrichford/docker-ipsec

代わりに:ipsec up

あなたがします:docker-ipsec up

このスクリプトは、最新のDockerネットワーキング機能で使用するために多少の作業が必要になる場合がありますが、古いデフォルトのdocker0ブリッジで動作しました。

スクリプトを使用してiptablesを編集したくない場合は、iptablesコマンドを次のように作成します。

  1. VPN内のホストの仮想IPアドレスを見つけます。これをvirtualIPと呼びます。
  2. VPNのIPアドレスのCIDRブロックを見つけます。 VPNのIPアドレスが常に10.10.X.Xの形式である場合、CIDRブロックは10.10.0.0/16になります。これをvpnSubnetと呼びます
  3. デフォルトのルートインターフェイスを見つけます。これは「eth0」のようなものになります。これは私がそれを見つけるために使用するコマンドです:Sudo ip route show | grep -e "^default" | awk -- "{ print \$5 }"。このdefaultRouteInterfaceを呼び出します
  4. VPNへのアクセスを許可するdockerネットワークのCIDRブロックを見つけます。私はそれを見つけるためにこのコマンド: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)

より使いやすく、更新されたバージョンは 要点として利用可能 です。

0
CodeMedic