同じホスト上のネットワーク化された Docker コンテナがパブリック URL を使用できるようにする nftables ルール

同じホスト上のネットワーク化された Docker コンテナがパブリック URL を使用できるようにする nftables ルール

私は走っています同じホスト上の2つのDockerコンテナ同じブリッジ ネットワークを Docker で使用しており、ほぼすべてのトラフィックを制限するように nftables を設定しています (以下のルール)。

私の唯一の問題は(私が知る限りでは)コンテナ間のトラフィックがブロックされるコンテナが他のコンテナによって提供されるサービスのパブリック URL

例えば、サービスAはパブリックDNSエントリを持つSMTPサーバーでありmail.acme.com、サービスBはWebサーバーにメールを送信するアプリです。このURLを使用するSMTP サーバーは外部からアクセスできるように構成されています (つまり、0.0.0.0:25:25docker compose のようなポート転送)。

この特定のケースでは、nftables の入力インターフェースは外部インターフェースではなく、コンテナが存在する Docker ネットワークのインターフェースです。トラフィックは を経由してルーティングされずFORWARD、Docker によって追加されたルールは適用されず、トラフィックは でドロップされますINPUT

Docker インターフェースから許可されたポートへのトラフィックを許可するための個別のルールを設定する必要はありません。

私は、サービスがそれぞれの URL を使用でき、Docker セットアップで使用されるポートとインターフェースに依存しないソリューションを探しています。これは nftables だけでも可能ですか?

これまでのところ、私が思いついた唯一のことは、入力インターフェースが外部インターフェースでない場合に から にジャンプすることですINPUTFORWARD、それはすべきではないように感じます。


私のルールは次のとおりですINPUT:

        chain INPUT {
                type filter hook input priority filter; policy drop;
                ct state vmap { invalid : drop, established : accept, related : accept }
                iifname "lo" accept
                iifname "externalif0" icmp type echo-request accept
                iifname "externalif0" icmpv6 type echo-request accept
        }

これはコンテナが別のコンテナにアクセスしようとするときに起こることです同じホスト上: (あまり関係ないと思われるトレース出力の一部を省略しました)

trace id 196c1ae6 ip filter trace_chain packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443 
trace id 196c1ae6 ip nat PREROUTING packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443 

trace id e7c2ca4b ip filter INPUT packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443 

そしてここに外部交通同じサービスに:

trace id 29f9da6c ip filter trace_chain packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443 
trace id 29f9da6c ip nat PREROUTING packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443 
trace id 29f9da6c ip nat DOCKER rule iifname != "dockerbr0" dport 443 dnat to <dockerip>:443 (verdict accept)

trace id 29f9da6c ip filter FORWARD packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> daddr <containerip> sport 36382 tcp dport 443 
trace id 29f9da6c ip filter DOCKER rule iifname != "dockerbr0" oifname "dockerbr0" daddr <containerip> tcp dport 443 accept (verdict accept)

trace id 29f9da6c ip nat POSTROUTING packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> ip daddr <containerip> sport 36382 tcp dport 443 

ホストにも:

iptables-legacy -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

関連情報