ブログ

マルチテナントホスティングのためのDockerコンテナ強化:ステップバイステップ分離ガイド

マルチテナント環境でDockerコンテナをロックダウンする方法を学びます。非rootユーザー、不要なケーパビリティの削除、読み取り専用ファイルシステム、ネットワーク分離などの実用的なセキュリティ対策を紹介します。

概要

マルチテナントのDockerホスティングプラットフォームを運用するには、テナント同士の干渉やホストへの脱出を防ぐため、強固なコンテナ分離が求められます。このガイドでは、今すぐ適用できる具体的なステップバイステップの強化プロセスを提供します。非rootユーザーの設定、不要なLinuxケーパビリティの削除、ファイルシステムの読み取り専用マウント、cgroupsによるリソース制限の適用、ネットワークのセグメント化、seccompやAppArmorプロファイルの適用について学びます。また、最大限のセキュリティを確保するために、コンテナを仮想マシンで補強するタイミングについても説明します。最後には、一般的なコンテナ脱出ベクトルを体系的に排除し、マルチテナントインフラを真に分離された状態に保つためのチェックリストを入手できます。

マルチテナントコンテナの現実的な問題

Dockerコンテナはホストカーネルを共有するため、分離が誤って設定されると、あるテナントが理論上、別のテナントのデータにアクセスしたり、すべてのCPUを消費したり、ホストに脱出したりする可能性があります。ホスティングプロバイダーとしては、コンテナのパフォーマンス利点を犠牲にすることなく、強固な境界が必要です。多くのチームは、開発用に設計されたデフォルトのDocker設定から始めますが、これは本番のマルチテナントには適していません。良いニュースは、体系的な強化チェックリストを使えば、Dockerの速度を維持しながら、各コンテナをVMに近いレベルの分離にロックダウンできることです。

この記事では、各強化ステップを実例と注意点とともに説明します。最後には、安全なマルチテナントコンテナをデプロイするための再現可能なプロセスを身につけることができます。

ステップ1: コンテナを非rootユーザーで実行する

デフォルトでは、Dockerコンテナはrootで実行されます。コンテナが侵害されると、攻撃者はコンテナ内でroot権限を取得し、コンテナ脱出を試みる可能性があります。まず、Dockerfile内に専用ユーザーを作成し、そのユーザーに切り替えます:

FROM ubuntu:22.04
RUN useradd -m appuser
USER appuser

注意: 一部のプロセス(例:1024未満のポートへのバインド)はrootが必要です。そのような場合は、--cap-addフラグを使用して必要なケーパビリティのみを付与し(例:--cap-add=NET_BIND_SERVICE)、プロセスは非rootユーザーで実行します。

基礎的な分離の詳細については、Dockerで真のマルチテナント分離を実現するガイドをご覧ください。

ステップ2: すべてのLinuxケーパビリティを削除し、必要なものだけを追加する

Linuxケーパビリティは、root権限を小さな単位に分割します。Dockerコンテナにはデフォルトのケーパビリティセットがありますが、マルチテナントホスティングには許可が多すぎます。すべてを削除し、アプリケーションに必要なものだけを追加します:

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE my-app

避けるべき一般的なケーパビリティ:SYS_ADMIN(コンテナ脱出)、NET_RAW(パケットスニッフィング)、SYS_PTRACE(プロセスデバッグ)。docker run--security-opt no-new-privilegesを指定して、setuidバイナリによる権限昇格を防ぎます。

ステップ3: ルートファイルシステムを読み取り専用でマウントする

攻撃者はしばしばコンテナのファイルシステムに悪意のあるスクリプトを書き込みます。ルートファイルシステムを読み取り専用にすることで、それを防ぎます:

docker run --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m my-app

--tmpfsは、/tmp/var/runなどのディレクトリに対して一時的な書き込み可能マウントを作成します。noexecフラグは、そのマウントからの実行を防ぎます。このアプローチにより、攻撃者は書き込み可能なディレクトリを経由することを強いられ、それを監視できます。

ステップ4: cgroupsでリソース制限を適用する

無制限のコンテナは、ホストのメモリやCPUを枯渇させることでDoS攻撃を実行する可能性があります。Dockerのランタイム制約を使用します:

docker run --memory=512m --memory-swap=512m --cpus=0.5 --pids-limit=100 my-app
  • --memory--memory-swapはハードリミットを設定します(スワップなし)。
  • --cpusはCPUを制限します。
  • --pids-limitはプロセス数を制限してフォーク爆弾を防ぎます。

注意: リソース制限はcgroupsによって強制されますが、ネットワーク経由のデータ流出は防げません。ネットワーク分離(次のステップ)と組み合わせてください。

ステップ5: Dockerカスタムネットワークでネットワークをセグメント化する

デフォルトでは、Dockerコンテナはブリッジネットワークを共有します。マルチテナント設定では、各テナントのネットワークスタックを分離する必要があります。テナントごとに専用のネットワークを作成します:

docker network create tenant-alpha --internal
docker run --network tenant-alpha my-app

--internalフラグを使用して外部インターネットアクセスをブロックし、-pで必要なポートのみを公開します。より高度なネットワークセグメンテーションについては、Docker分離によるWebアプリのセキュリティ確保を参照してください。

注意: 内部ネットワークはテナント間の直接コンテナ間通信を防ぎますが、ホストネットワークを使用するとDNS漏洩が発生する可能性があります。ブリッジまたはオーバーレイネットワークに固執してください。

ステップ6: SeccompとAppArmorプロファイルを適用する

Seccompはシステムコールをフィルタリングし、AppArmor(またはSELinux)は強制アクセス制御を適用します。Dockerは、特定のフラグを持つcloneなどの危険なシステムコールをブロックするデフォルトのseccompプロファイルを提供します。より厳格な分離のために、カスタムプロファイルを作成します:

docker run --security-opt seccomp=./custom.json --security-opt apparmor=docker-default my-app

docker run --rm -it --security-opt seccomp=unconfined my-app strace -c -S timeでベースプロファイルを生成し、その後絞り込むことができます。注意: 過度に制限的なプロファイルは正当な機能を壊す可能性があります。ステージングで十分にテストしてください。

ステップ7: 仮想マシンによるハイブリッド分離を検討する

テナントが絶対的な分離を必要とする場合(例:規制産業)、軽量VM内でコンテナを実行します。SysboxやKata Containersなどのツールは、コンテナの速度を犠牲にすることなくハードウェアレベルの分離を提供します。これはDockerの拡張コンテナ分離(ECI)で採用されているアプローチです。オーバーヘッドはベアコンテナよりも高いものの、ワークロードあたりのフルVMよりははるかに低いです。

適切な分離レベルの選択については、マルチテナントDockerアーキテクチャの設計をお読みください。

すべてをまとめる:強化チェックリスト

  1. 非rootユーザーでコンテナをビルドする。
  2. すべてのケーパビリティを削除し、必要なものだけ追加する。
  3. ファイルシステムを読み取り専用でマウントし、一時的な書き込み可能マウントを使用する。
  4. メモリ、CPU、PID制限を設定する。
  5. テナントごとに分離されたDockerネットワークを作成する。
  6. カスタムseccompおよびAppArmorプロファイルを適用する。
  7. 高セキュリティ要件のためにハイブリッドVMコンテナを評価する。

結論

コンテナの強化は一度きりの作業ではなく、継続的な規律です。上記の手順は、マルチテナントホスティングのセキュリティベースラインを形成します。単一の対策では安全性が保証されないことを忘れないでください。多層防御が鍵です。基本(非rootユーザーと削除されたケーパビリティ)から始め、リソース制限とネットワークセグメンテーションを積み重ねてください。最も機密性の高いワークロードには、コンテナをVMと組み合わせてください。このガイドを使用すれば、効率的かつ安全なマルチテナントDocker環境を自信を持ってデプロイできます。

Sources (5)