SSTエンジニアブログ

SSTのエンジニアによるWebセキュリティの技術を中心としたエンジニアブログです。

docker-compose.yml で bridge network を使うときはバックエンドサービスでport map未指定でもOK

こんにちは、SSTでWeb脆弱性診断用のツール(スキャンツール)開発をしている坂本(Twitter, GitHub)です。

Docker Compose を使うときのメモです。

例としてシンプルな web + db 構成を考えます。 docker 公式のサンプル1としてこんな docker-compose.yml が掲載されています。

services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

こちらをそのまま参考にすると、postgres サービスの ports まで docker ホスト側で公開(port map) されます。 もしノートPCをカフェの公共WiFiに接続した状態で、Docker Desktop で上記の docker-compose.yml を起動するとどうなるでしょうか? docker 公式ドキュメントの Networking overview | Docker Documentation にあるとおり、port map されたホスト側のポートが firewall でも公開されてしまいます。2 結果として公共WiFi に接続されている悪意のあるコンピュータから、開発環境のバックエンドサービスに接続可能となってしまうリスクが発生します。

結論としては、外部に公開する必要のないポートについては port map を設定する必要はありません。

  • docker-compose.yml ではデフォルトで bridge network を作成してその中で各サービスごとのコンテナを起動します。3
  • bridge network では port map しなくとも、コンテナ間で接続可能です。

上に挙げた例だと、もし db サービスの postgres にホスト側から接続する必要が無いのであれば、 ports 設定は削除しても問題ありません。

pgAdminなどバックエンドサービスの管理ツールを使いたいなど、ホスト側から接続する必要があるなら ports 設定でホスト側に port map します。 ただしその場合、docker-compose.yml を起動する環境によっては先述の通りセキュリティ上のリスクが発生する点を意識しておく必要があります。 対処としては docker 公式ドキュメントでも書かれている通り、 daemon.jsonip key で 127.0.0.1 を設定しておくと良いでしょう。 これにより万が一 port map したポートが firewall 上で公開されてしまったとしても、外部(= loopback 以外) からの接続は受け付けない状態となります。

以上、docker-compose.yml で bridge network を使うときはバックエンドサービスでport map指定する必要は無かったというメモの共有でした。

検証環境:

  • CentOS Stream 8
    • Docker Engine Community Version 23系
  • Amazon Linux 2
    • Docker Engine Version 20系

  1. Networking in Compose | Docker Documentation
  2. ここで参照している docker 公式ドキュメントにおいて、厳密には firewall の設定変更までは言及されていません。しかし Dockerのポートマッピングのデフォルト設定は危ない - JUNのブログ では Mac において実際に firewall の設定変更までされた事例が報告されています。 Linux + Docker Desktop だとどうなるか、Windows + Docker Desktop だとどうなるかさらなる検証が必要だと思われますが、一般開発者の観点としてはとりあえず「firewallの設定も変更されうる」と考えて対処しておくに越したことは無いでしょう。
  3. 本記事の執筆時点では公式ドキュメント上にこれが明記されている箇所を見つけられていません。しかし筆者個人の検証(v20-23系) と、他者の記事などをググってみた範囲として、現時点ではデフォルトが bridge network driver を使うようになっているようです。