VPNでいくつかのパケットをルーティングするためにDockerコンテナにプロキシサーバーを設定しようとしています(一部のサイトはVPNのIPに応答せず、国はロックされています)。この目的のために、Dockerコンテナインタフェースとの間で送受信されるパケットにタグを付けてみました。
私のPCの物理ネットワークインターフェイスbr-43cb854b8af8
名はですenp3s0
。標準のdockerブリッジインターフェイスもあり、docker0
ネットワークは172.17.0.0/16なので、iptablesルールに含まれていますが、使用されていません。
PC起動時のrawテーブルとmangleテーブルは空で、
フィルタテーブル:
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -o br-43cb854b8af8 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-43cb854b8af8 -j DOCKER
-A FORWARD -i br-43cb854b8af8 ! -o br-43cb854b8af8 -j ACCEPT
-A FORWARD -i br-43cb854b8af8 -o br-43cb854b8af8 -j ACCEPT
-A DOCKER -d 172.18.0.2/32 ! -i br-43cb854b8af8 -o br-43cb854b8af8 -p tcp -m tcp --dport 3128 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-43cb854b8af8 ! -o br-43cb854b8af8 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-43cb854b8af8 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
NATテーブル:
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o br-43cb854b8af8 -j MASQUERADE
-A POSTROUTING -s 172.18.0.2/32 -d 172.18.0.2/32 -p tcp -m tcp --dport 3128 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER -i br-43cb854b8af8 -j RETURN
-A DOCKER ! -i br-43cb854b8af8 -p tcp -m tcp --dport 3128 -j DNAT --to-destination 172.18.0.2:3128
問題は私が追加した場合
iptables -t mangle -A PREROUTING -i br-43cb854b8af8 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i enp3s0 -s 172.18.0.0/16 -j MARK --set-mark 1
プロキシサーバーから発信されたパケットを表示するために、2番目のルールはどのパケットにも適用されませんが、最初のルールは適用され、masquerading throughenp3s0
も適用されます。つまり、パケットは正常に動作しますが、
iptables -t mangle -A PREROUTING -i enp3s0 -s 172.18.0.0/16 -j MARK --set-mark 1
何らかの理由でルールは適用されません。 VPNがオンになっていないか、デフォルトのIPルーティングまたはルール以外のルールが適用されていません。
答え1
まず、質問のコメントで答えたように、-iはパケットがインターフェイスで受信されたことを意味するため、2番目のルールは適用されませんenp3s0
。したがって、プロキシから発信されるすべてのパケットを表示するには、最初のルールで十分です。着信パケットに対して同じ操作を実行するには、以下を追加する必要があります。
iptables -t mangle -A FORWARD -i enp3s0 -d 172.18.0.0/16 -j MARK --set-mark 1
これで、着信および発信するすべてのパケットにbr-43cb854b8af8
タグが付けられ(ブラウザからプロキシに送信されるパケット)、これは時間ごとに設定されたパスです。
最初のコマンドセットは次のとおりです。
ip rule add to 172.18.0.0/16 pref 100 table 1
ip rule add fwmark 0x0001 pref 101 table 1
ip route add table 1 to 172.18.0.0/16 dev br-43cb854b8af8
ブラウザからの着信トラフィックとプロキシからDockerネットワークへの直接着信トラフィックを許可します。 VPNが独自のルールも設定し、上記のルールがパケットに適用されない場合にのみこれらのルールを確認しようとするため、prefオプションが使用されます。
2番目のコマンドセットは次のとおりです。
ip rule add fwmark 0x0001 pref 102 table main
パケットにタグが付けられていてDockerのネットワークに行かない場合(つまり、Dockerのネットワークから出るという意味)、VPNルールをバイパスし、VPNが不要な標準パスに移動するように設定します。
最終スクリプト
#!/bin/sh
iptables -t mangle -A PREROUTING -i br-43cb854b8af8 -j MARK --set-mark 1
iptables -t mangle -A FORWARD -i enp3s0 -d 172.18.0.0/16 -j MARK --set-mark 1
ip rule add to 172.18.0.0/16 pref 100 table 1
ip rule add fwmark 0x0001 pref 101 table 1
ip route add table 1 to 172.18.0.0/16 dev br-43cb854b8af8
ip rule add fwmark 0x0001 pref 102 table main
ip route flush cache