Docker Engine v28: デフォルトでコンテナネットワークを強化する

Docker は、ランタイムの複雑さを排除し、アプリ開発をシームレスにすることで、コンテナ化を簡素化します。Docker Engine v28では、コンテナがローカル ネットワークから意図せずにアクセスできないようにすることで、セキュリティをさらに一歩前進させています。このアップデートは、1つの脆弱性を修正するものではなく、コンテナを安全に保つためのセキュリティ強化を目的としています。 

どうされました。

デフォルトの Docker 「ブリッジ」ネットワークでコンテナを実行すると、Docker はシステムのファイアウォール ( iptables 経由) を使用して NAT (ネットワークアドレス変換) ルールを設定します。たとえば、次のコマンドは、ホストのポート 8080 からコンテナ内のポート 80 にトラフィックを転送します。 

docker run -d -p 8080:80 my-web-app

ただし、ホストの filter-FORWARD チェーンが許容され (つまり、デフォルトでは ACCEPT)、 net.ipv.ip_forward4 が有効になっている場合 、特定の条件下では未公開のポートにもリモートでアクセスできる可能性があります。

これは、Docker ホスト と同じ物理/リンクレイヤー ネットワーク上の ホストにのみ影響します。マルチテナント LAN 環境やその他の共有ローカル ネットワークでは、RFC1918 サブネット ( 192.168.x.x10.x.x.x など) で接続しているユーザーが、その IP アドレスを知っている (または推測している) 場合、未公開のコンテナ ポートにアクセスできる可能性があります。

影響を受けるのは誰ですか?

この動作は、28より前のバージョンの Docker を実行している Linux ユーザーにのみ影響します。0。iptablesで0。Docker Desktop は影響を受け ません

Docker を 1 台のマシンにインストールし、ファイアウォール設定を手動でカスタマイズせずにデフォルトを使用した場合は、アップグレードの影響を受けない可能性があります。ただし、次の場合は影響を受ける可能性があります。

  • ホストのFORWARDチェーンを意図的にACCEPTに設定し、LAN上の他のマシンからIPでコンテナにアクセスすることに依存しています。
  • コンテナを127.0.0.1または別のループバックインターフェイスにバインドしましたが、高度なホストネットワーキングトリックを使用して外部トラフィックをそれらにルーティングします。
  • サブネット、VLAN、またはその他のブロードキャストドメインから、ポートを明示的に公開 せずに(つまり、 p フラグなしで) コンテナに直接アクセスする必要がある 。

これらの例外のいずれかが当てはまる場合は、ネットワークをオプトアウトするか再構成しない限り、以前は直接 IP で到達可能だったコンテナがブロックされているように見えることがあります。

どのような影響がありますか?

この公開には、 同じローカル ネットワーク上 にいるか、コンテナーの RFC1918 IP 範囲へのルート レベルのアクセス権が必要でした。公共のインターネット上の マシンには影響しませんでした 。ただし、悪意のあるユーザーは、LAN設定または企業環境内で未公開のコンテナポートを検出し、それらに接続する可能性があります。 

たとえば、次のコマンドを使用して、コンテナのサブネットにカスタムルートを追加できます。

ip route add 172.17.0.0/16 via 192.168.0.10

そこから、 192.168.0.10 が許容範囲が広いファイアウォールを備えたDockerホストである場合、攻撃者はパケットを直接送信する可能性があります。 172.17.0.x(コンテナのIP)。

次のステップは何ですか?

影響を受けた場合は、次の 3 つの手順を実行することをお勧めします。

1。 Docker Engine にアップグレード 28。0

Docker エンジン 28.0 は、デフォルトで非公開ポートへのトラフィックをドロップするようになりました。 

この「デフォルトで安全」なアプローチは、コンテナがLAN上で予期せずアクセス可能になるのを防ぎます。ほとんどのユーザーは違いに気付かず、公開されたポートは通常どおり機能し (-p 8080:80)、公開されていないポートは意図したとおりにプライベートのままになります。

2。 以前の動作が必要かどうかを判断する(オプトアウト)

ポートを公開せずに LAN 経由でコンテナに接続する場合は、いくつかのオプションがあります。

オプション 1:Dockerの DROP ポリシーを無効にする
/etc/docker/daemon.json年には、以下を追加します。

{
  "ip-forward-no-drop": true
}

または、 --ip-forward-no-drop フラグを使用してDockerを実行することもできます。これにより、グローバルにオープンな FORWARD チェーンが維持されます。ただし、Docker は別のルールを使用して未公開ポートのトラフィックを引き続きドロップすることに注意してください。完全に保護されていない代替手段については、オプション 2 を参照してください。

オプション 2: "nat-unprotected" ネットワークを作成する

docker network create -d bridge \\
  -o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \\
  my_unprotected_net

3。 カスタムiptables管理を検討する

複雑なネットワーク設定の上級ユーザーは、必要なトラフィックを正確に許可するようにiptablesを手動で構成できます。ただし、このルートは、ファイアウォールルールの管理に慣れている場合にのみお勧めします。

技術的な詳細

以前のバージョンの Docker Engine では、Docker が寛容な Docker FORWARD チェーンに依存していたため、次の場合にデフォルトのブリッジ ネットワーク上のコンテナに到達できました。

  1. net.ipv4.ip_forward が有効になっていました (まだ有効になっていない場合は、多くの場合、Docker によって自動的に有効になります)。
  2. システム全体の FORWARD チェーンは ACCEPT に設定されました。
  3. 同じ LAN (または接続されたサブネット) 上の別のマシンが、トラフィックをコンテナの IP アドレスにルーティングしました。

Docker 28.0、各コンテナの内部IPへの未承諾の受信トラフィックは、そのポートが明示的に公開されていない限り(-p または --publish)、明示的にドロップされるようになりました。これは、Docker ホスト自体からのローカル接続には影響しませんが、未公開ポートへのリモート LAN 接続はブロックされます。

攻撃: 実例

同じ RFC1918 サブネット上に 2 つのホストがあるとします。

  • 攻撃者10.0.0.2
  • DockerHost10.0.0.3

DockerHost は IP 172.17.0.2 でコンテナを実行し、Docker のファイアウォール ポリシーは事実上 "ACCEPT" です。この状況では、攻撃者は次のコマンドを実行する可能性があります。

ip route add 172.17.0.2/32 via 10.0.0.3
nc 172.17.0.2 3306

MySQL がコンテナのポート 3306 でリッスンしていた場合 (未公開)、Docker はそのトラフィックを転送する可能性があります。コンテナは 10.0.0.2 からの接続を認識し、Docker のネットワーク スタックだけでは認証は適用されません。 

Docker Engine 28の軽減策 .0

未公開のポートにドロップルールを適用することで、Docker 28は .0 では、上記のシナリオがデフォルトで防止されるようになりました。

1。 未公開ポートのデフォルトのドロップ

コンテナ IP へのローカル トラフィックが、明示的に公開されていない限り破棄されるようにします。

2。 FORWARDポリシーの的を絞った調整

もともと、Docker が IP 転送を有効にする必要がある場合、デフォルトで DROP に設定されていました。現在、Dockerは必要な場合にのみそれを適用し、同じロジックをIPv6に拡張します。オプトアウトは、 --ip-forward-no-drop または設定ファイルで行うことができます。

3。 未公開のポートは非公開のまま

コンテナはホスト自体からアクセスできますが、LAN上の他のデバイスからはアクセスできません(意図的に「nat-unprotected」を選択しない限り)。

この変更を今行う理由

一部のユーザーは、何年もの間、ローカルネットワークの露出について懸念を表明してきました( #14041 #22054などの問題を参照)。しかし、それ以来、多くの変化がありました。

  • Docker はよりシンプルで、ユースケースは多くの場合、シングルノードのセットアップを中心に展開され、一般的な開発/テストワークフローによって余分な露出が軽減されました。
  • エコシステムの進化:オーバーレイネットワーク、マルチホストオーケストレーション、高度なルーティングが主流になりました。突然、かつては特殊なセットアップに追いやられていたシナリオが一般的になりました。
  • セキュリティへの期待: Docker は、複雑な環境における重要なワークロードを支えています。誰もがより安全なデフォルトの恩恵を受けますが、それが古い仮定を調整することを意味する場合でも。

これらの変更を Docker Engine 28.0、私たちは今日のベストプラクティスに沿っています: 明示的なユーザーの意図なしに何も公開しないでください。これは、ユーザーがロックダウンしたい場合に、ユーザーが自分でファイアウォールを設定することに頼ることからのシフトです。

下位互換性と今後の道筋

これらの変更は、ローカル LAN からの直接コンテナ IP アクセスに依存しているユーザーにとっては下位互換性 がありません 。大半の人にとって、新しいデフォルトは、一般的な docker run -p シナリオを壊すことなく、コンテナをより安全にロックダウンします。

それでも、 28にアップグレードすることを強くお勧めします。0。1 以降で、以下のメリットを享受できます。

  • より安全なデフォルト: 未公開のポートは、公開するか明示的にオプトアウトしない限り、非公開のままです。
  • より明確な境界: 公開ポートと未公開ポートが iptables ルールによって明確に適用されるようになりました。
  • 管理の容易化:ユーザーは、iptablesの専門家にならなくても、新しいデフォルトを採用できます。

クイックアップグレードチェックリスト

アップグレードする前に、最新リリースで成功するための設定を確実にするために、次の推奨チェックリストを確認してください。

  1. 現在のファイアウォール設定を調べる

    iptables -L -nip6tables -L -nを実行します。FORWARD チェーンにACCEPTが表示され、マルチサブネットまたは直接コンテナアクセスのためにそれに依存している場合は、それに応じて計画してください。
  2. 制御された環境でのテスト

    Dockerエンジン 28スピンアップします。ステージング環境で0 します。以前に直接アクセスしたコンテナへのアクセスを試みます。次に、どの接続がまだ機能し、どの接続がブロックされているかを確認します。
  3. オプトアウトを決定する

    以前の動作が必要な場合は、 "ip-forward-no-drop": true を設定するか、「nat-unprotected」ネットワークを使用してください。それ以外の場合は、強化されたセキュリティの既定値をお楽しみください。
  4. ログとメトリクスの監視

    予期しない接続エラーやサービスのダウンタイムに注意してください。何かが壊れた場合は、変更をロールバックする前に、Docker の新しいドロップ ルールが原因であるかどうかを確認します。

結論

Docker Engine 28のデフォルトのネットワークルールを強化することで、.0、ローカルネットワーク上での偶発的なコンテナの露出を減らしています。ほとんどのユーザーは中断することなく続行でき、追加の安心感を楽しむことができます。ただし、古い動作に依存している場合は、オプトアウトするか、これらのルールを回避する特殊なネットワークを作成できます。

アップグレードする準備はできましたか?公式のインストールとアップグレードの手順に従って、Docker Engine 28を入手してください。今すぐシステムに0してください。

コミュニティからのフィードバックに感謝し、アップグレード後に質問がある場合や驚いたことに遭遇した場合は、連絡することをお勧めします。 GitHub の問題コミュニティフォーラム、または通常のサポートチャネルで見つけることができます。

さらに詳しく