Dockerコンテナはiptablesを使用してプロキシを使用します。

Dockerコンテナはiptablesを使用してプロキシを使用します。

2つのVPSがあり、最初のマシン(代理人これから)エージェントと2番目のマシン(橋脚これから)はドッカーホストです。 Dockerコンテナ自体の内部で生成されたすべてのトラフィックを次にリダイレクトしたいと思います。代理人、公開されていません橋脚マシンパブリックIP。

VPS間の接続はインターネットを介して行われるため、ローカル接続がないため、VPS間にトンネルが作成されます。IPトンネル次のように:

存在する代理人:

ip tunnel add tun10 mode ipip remote x.x.x.x local y.y.y.y dev eth0
ip addr add 192.168.10.1/24 peer 192.168.10.2 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

存在する橋脚:

ip tunnel add tun10 mode ipip remote y.y.y.y local x.x.x.x dev eth0
ip addr add 192.168.10.2/24 peer 192.168.10.1 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

PS:そこにいるのか分からないIPトンネル本番で使用できます。それは別の質問です。とにかく使いたい意図です。リブレスワンまたはオープンVPNVPS間のトンネルとして機能します。

次に、以下のように、両方のVPSのiptablesにSNATルールといくつかのルーティングルールを追加します。

存在する代理人:

iptables -t nat -A POSTROUTING -s 192.168.10.2/32 -j SNAT --to-source y.y.y.y

存在する橋脚:

iptables -t nat -A POSTROUTING -s 172.27.10.0/24 -j SNAT --to-source 192.168.10.2
ip route add default via 192.168.10.1 dev tun10 table rt2
ip rule add from 192.168.10.2 table rt2

最後に、ドッカーネットワークを作成し、次のようにテストコンテナを接続します。

docker network create --attachable --opt com.docker.network.bridge.name=br-test --opt com.docker.network.bridge.enable_ip_masquerade=false --subnet=172.27.10.0/24 testnet
docker run --network testnet alpine:latest /bin/sh

残念ながら、これらのどれも成功しませんでした。もしそうなら、問題はデバッグ方法です。これは正しいアプローチですか?プロキシ経由でどのようにリダイレクトしますか?

理論のいくつかの言葉:172.27.10.0/24サブネットのトラフィックがiptables SNATルールに達し、送信元IPが192.168.10.2に変わります。ルーティングルールはトンネルであるtun10デバイスを介してルーティングされます。そして、別のiptables SNATルールに達し、IPをyyyyに変更した後、ついにターゲットに到達します。

ベストアンサー1

DockerマシンのパブリックIPが公開されないように、Dockerコンテナ内で生成されたすべてのトラフィックをプロキシ経由でリダイレクトしたいと思います。

これが必要な場合は、2つのDockerインスタンス間でNATは必要ありません。

proxyインスタンスで転送を有効にする必要があります(たとえば、sysctlを介して)。

パブリックIPが次のproxy場合見えるinside の場合、SNAT inside (内部ではない)proxyに対応するパブリック IP のみを使用する必要があります。これを仮面舞踏会ともいいます。これは標準設定のGoogle検索「masquerade」です。proxydock

パブリックIPが次のproxy場合見えないホスト(または上記の他のホスト)がNATを実行するため、デュアルproxyNATを避け、ホストを他のコンテナのように見せる必要があります。詳細は、ホストでネットワークがどのように設定されているかによって異なりますが(言わない)、デフォルトでは、トンネルの終わりはホストのコンテナと同じサブネットにIPを持つ必要があります。ip addrproxydockdockproxy

トンネルはipip暗号化されません。転送が完全に信頼できるネットワーク内で行われない限り(他のパブリックIPアドレスが必要なように見えるため、そうでない可能性がある)、このトンネルを使用しないでください。したがって、OpenVPN次の選択肢を使用または設定するのは簡単です。ディンクLibreswan設定するのはそれほど簡単ではありません。

編集する

ステップバイステップ:

1)トンネルが正しく機能していることを確認してください。登ってproxyみてくださいping 192.168.10.2。登ってdockみてくださいping 192.168.10.1tcpdumpアクセスできるすべての中間ネットワークインターフェイスをデバッグします。 ipip-tunnelが機能しない場合は、別のトンネルを使用して機能させるようにしてください。

2)すべてのiptablesルールを削除しますdock。トンネルを通過するデフォルトルートを設定します。ip route get 8.8.8.8パスが機能しているかどうかをテストします。

3)eth0proxyパブリック IP があると仮定し、すべてのiptablesルールを削除してから、次を実行します。

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o tun10 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -o eth0 -i tun10 -j ACCEPT

eth0これは、「パケットを転送し、パブリックIPアドレスを送信元アドレスとして使用して転送されたすべてのパケットを偽装し、接続が追跡します。eth0パケットtun10は常に転送される可能性がありますeth0。になります。」を意味します。eth0tun10dock

ping 8.8.8.8で実行し、同時にdock実行してテストします。パケットが転送され、ソースが書き換えられることがわかります。tcpdumptun10eth0proxy

4)すべてがうまくいけば永久にします。ファイルを編集または/etc/sysctl.conf編集して、起動スクリプトを使用してルールを追加するか、ディストリビューションによって提供されるパッケージを使用してルールを保存します。/etc/sysctl.dnet.ipv4.ip_forward = 1iptables

おすすめ記事