web-dev-qa-db-ja.com

Dockerコンテナーがホストトンネルインターフェース上のOpenVPNクライアントに接続することを許可する

私は次の設定をしています:

  • Dockerサービスを実行しているCentOSホスト
  • ユーザー定義のドッカーブリッジネットワーク
  • そのユーザー定義のブリッジネットワークに接続された2つのDockerコンテナー
  • OpenVPNインストール(現在ホスト上で実行されています。Dockerコンテナーでも実行できます)
  • OpenVPNに接続されている一部のクライアント

Docker bridgeネットワークのdockerコンテナーがtun0ネットワークのopenvpnクライアントと通信できるようにするにはどうすればよいですか?

Docker1(10.10.0.3)とvpn(172.19.0.x範囲)に接続されたクライアントとの間のTCPベースの通信を透過的に行えるようにしたいと思います。

Docker(networking/iptables/...)側とHost(iptables?)で何をセットアップする必要がありますか?

11
ddewaele

環境

私はカイル・マンナの非常に優れたDockerコンテナーを使用しています( https://github.com/kylemanna/docker-openvpn )。私はいわゆる「パラノイア」ドキュメントを使用してOpenVPNサーバーをセットアップしていますが、私の見解では、これは標準的な方法であり、パラノイアな方法ではないはずです。

構成

選択したDockerコンテナーとVPNクライアント間の双方向接続を許可するには、VPNクライアントからのアクセスを許可するコンテナーを接続するDockerネットワークを作成する必要があります。 VPNサーバーは、これらのコンテナーの1つになります。

VPNサーバーには、client-to-clienttopology subnetdev tun0(またはその他のtunデバイス)およびPush "route <docker net IP> <docker net mask>"が構成されている必要があります。

VPNサーバーのホストは、1つのサブネットから別のサブネットへのIPパケットの転送をサポートするように構成する必要があります。つまり、sysctl ip_forwardを1に設定し(Dockerをインストールしている場合はそうなります)、tunデバイスからのパケットがiptables FORWARDチェーンを通過できるようにし、適切なルーティングを設定します。これは、次のコマンドで要約できます。

$ Sudo sysctl -w net.ipv4.ip_forward=1
$ Sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ Sudo ip route add 192.168.255.0/24 via <IP address of OpenVPN server container>

とにかく、サーバーをセットアップするために使用したオプションは次のとおりです。

$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://<FQDN> -N -d -c -p "route <docker net IP> <docker net range>" -e "topology subnet"

これにより、次のようなサーバー構成ファイルが生成されます。

server 192.168.255.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/vpn.example.com.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.example.com.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun

proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log

user nobody
group nogroup
client-to-client

### Push Configurations Below
Push "dhcp-option DNS 8.8.8.8"
Push "route 172.20.20.0 255.255.255.0"

### Extra Configurations Below
topology subnet

具体例

具体的な例を見てみましょう。この例では、ホストvpn.example.com上のDocker内の上記のOpenVPNサーバーを実行します。このコンテナーは、Dockerネットワークdocker-net-vpnに接続されています。コマンドは次のとおりです(この例では、サーバー上でサーバー構成を直接生成し、CA生成をスキップします。代わりに、上記のプロジェクトの偏執的なドキュメントに従ってください)。

$ docker network create --attachable=true --driver=bridge --subnet=172.20.20.0/24 --gateway=172.20.20.1 docker-net-vpn
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://vpn.example.com -N -d -c -p "route 172.20.20.0 255.255.255.0" -e "topology subnet"
$ docker run --detach --name openvpn -v $PWD/files/openvpn:/etc/openvpn --net=docker-net-vpn --ip=172.20.20.2 -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn:2.4
$ Sudo sysctl -w net.ipv4.ip_forward=1
$ Sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ Sudo ip route add 192.168.255.0/24 via 172.20.20.2

最初のコマンドは、新しいサブネットを定義する専用の新しいDockerネットワークを作成します。 OpenVPNサーバーをこのネットワークに接続します。

2つ目は、1つ目のコマンドで定義されたものと同じサブネットを使用してOpenVPN構成を作成します。

3番目はOpenVPNサーバーを作成します。新しく作成されたDockerネットワークに接続され、修正IPを使用します。

4番目と5番目のコマンドは、IP転送を構成します。

最後のコマンドは、OpenVPNコンテナーの固定IPを介してVPNクライアント構成への新しいルートを追加します。

私は試していませんが、iptablesのFORWARDルールを制限することは可能でしょう。 Dockerネットワークの作成により、新しいブリッジデバイスが作成されました。このブリッジの名前はbr-<ID>で、IDはDockerネットワークIDの最初の12文字です。このIDはdocker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12で取得できます。したがって、次のコマンドはおそらくより制限的です(セキュリティが優れているため)が、トラフィックをルーティングできるようにする必要があります。

$ NET_VPN_BRIDGE="br-$(docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12)"
$ Sudo iptables -A FORWARD -i tun+ -o ${NET_VPN_BRIDGE} -j ACCEPT
7
Huygens