ブログ

マルチテナントホスティングのための実践的なDocker隔離セキュリティチェックリスト

この実践的なチェックリストでマルチテナントDockerホスティングを保護:非rootユーザー、ケイパビリティ、seccomp、ユーザー名前空間、リソース制限、読み取り専用ファイルシステム。

概要

マルチテナントDockerホスティングでは、コンテナエスケープを防ぐために強力な隔離が必要です。この記事では、6つの主要な領域をカバーする実践的なセキュリティチェックリストを提供します:非rootでの実行、ケイパビリティの削除、seccompプロファイルの適用、ユーザー名前空間のリマッピングの有効化、リソース制限の設定、読み取り専用ルートファイルシステムの使用。各ステップにはDocker Composeの具体的な設定例が含まれています。また、ユーザー名前空間のカーネル互換性問題やseccomp適用時のパフォーマンストレードオフなど、よくある落とし穴についても学べます。このチェックリストに従うことで、不必要な複雑さを追加することなく攻撃面を大幅に削減できます。記事の最後には、本番マルチテナント環境向けの推奨ベースライン設定を紹介します。

マルチテナントDocker環境を運用していると、コンテナエスケープ攻撃の脅威に夜も眠れないかもしれません。1つのカーネルエクスプロイトでコンテナから脱出し、攻撃者がホストや他のテナントのデータに無制限にアクセスできるようになります。Dockerは名前空間、cgroups、ケイパビリティといった強力な隔離プリミティブを提供しますが、設定ミスが隙を生みます。この記事では、今日から適用できるステップバイステップのセキュリティチェックリストを紹介します。各ステップには動作するDocker Composeスニペットと重要な注意点が含まれています。最後には、セキュリティとパフォーマンスのバランスが取れた強化されたベースラインが得られます。

1. コンテナを非rootユーザーとして実行する

コンテナはデフォルトでコンテナ内のrootとして実行されます。攻撃者がコンテナ内でrootを取得すると、エスケープの有利なスタートを切れます。Dockerfileで常に非rootユーザーを定義してください。

FROM alpine:3.18
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

Composeでは、ユーザーを直接設定することもできます:

services:
  app:
    image: myapp
    user: "1000:1000"

注意点: 一部のアプリケーションでは、正当な操作(例:1024以下のポートへのバインド)にrootが必要な場合があります。コンテナ全体をrootとして実行する代わりに、CAP_NET_BIND_SERVICEを使用してください。隔離の基本についてさらに詳しくは、Dockerで真のマルチテナント隔離を実現するガイドをご覧ください。

2. 全ケイパビリティを削除し、必要なものだけ追加する

Linuxケイパビリティはコンテナに細かい権限を付与します。デフォルトでは、Dockerは一連のケイパビリティを付与します。すべてを削除し、必要なものだけを許可してください。

services:
  app:
    image: myapp
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE  # 必要な場合

注意点: SYS_ADMINNET_RAWのようなケイパビリティはほとんど必要ありません。アプリケーションを監査して最小セットを決定してください。すべてのケイパビリティを削除することで、多くのエスケープベクトルをブロックします。

3. Seccompプロファイルを適用する

Seccomp(セキュアコンピューティングモード)は、コンテナが利用できるシステムコールをフィルタリングします。Dockerには、特定のフラグを持つcloneのような危険なシステムコールをブロックするデフォルトのseccompプロファイルが同梱されています。さらにカスタマイズすることもできます。

services:
  app:
    image: myapp
    security_opt:
      - seccomp=/path/to/custom-profile.json

強化されたプロファイルでは、unshareptracemountなどをブロックする場合があります。Dockerのデフォルトから始めて、さらに制限を追加してください。注意点: 厳格すぎるプロファイルはアプリケーションを壊す可能性があります。ステージング環境で徹底的にテストしてください。コンテナエスケープ防御の詳細については、コンテナエスケープからの防御をお読みください。

4. ユーザー名前空間リマッピングを有効にする

ユーザー名前空間は、コンテナのrootユーザーを非特権ホストユーザーにマッピングします。つまり、攻撃者がコンテナ内でrootを取得しても、ホスト上で特別な権限を持ちません。

Dockerデーモンで有効にするには、/etc/docker/daemon.jsonを編集します:

{
  "userns-remap": "default"
}

その後、Dockerを再起動します。注意点: ユーザー名前空間リマッピングには2つの欠点があります:注意深く設定しないとボリュームマウントが機能しなくなる(ファイルがリマップされたユーザーによって所有される)ことと、古いカーネルのoverlay2などの一部のストレージドライバーと互換性がないことです。徹底的にテストしてください。

5. Cgroupsでリソース制限を設定する

リソース制限は、侵害されたコンテナがホストに対してDoS攻撃を仕掛けるのを防ぎます。cgroupsを使用してCPU、メモリ、ディスクI/Oを制限します。

services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

Docker Compose v3の場合は、deployセクションを使用します(swarmまたはcompose v2で動作)。通常のDockerの場合は、--memory--cpusを使用します。注意点: 制限を低く設定しすぎるとOOMキルが発生する可能性があります。使用状況を監視し、適宜調整してください。

6. 読み取り専用ルートファイルシステムを使用する

読み取り専用ルートファイルシステムは、攻撃者が悪意のあるバイナリを書き込んだり、コンテナ内の設定ファイルを変更するのを防ぎます。

services:
  app:
    image: myapp
    read_only: true
    tmpfs:
      - /tmp:noexec,nosuid,size=64m

書き込みアクセスが必要なディレクトリ(/tmpなど)にはtmpfsをマウントします。これにより、すべての書き込み可能データが一時的になります。注意点: 一部のアプリケーションは永続ストレージを必要とします。その場合は名前付きボリュームを使用してください。

よくある落とし穴

  • カーネル互換性: ユーザー名前空間リマッピングといくつかのseccompルールには、新しいLinuxカーネル(4.14+)が必要です。カーネルバージョンを確認してください。
  • パフォーマンスへの影響: Seccompとユーザー名前空間はわずかなオーバーヘッドを追加しますが、ほとんどのワークロードでは無視できます。特定のアプリでベンチマークを取ってください。
  • 複雑さ: 6つの対策すべてを一度に適用すると、問題が発生する可能性があります。1つずつ適用し、各変更をテストしてください。

オーケストレーションパターンのより広範な概要については、マルチテナントDockerアーキテクチャの設計ガイドをご覧ください。

結論

安全なマルチテナントDockerホストには特別なツールは必要ありません。Dockerの組み込み機能を正しく使用するだけです。非rootユーザーから始め、すべてのケイパビリティを削除し、seccompプロファイルを適用し、ユーザー名前空間リマッピングを有効にし、リソース制限を設定し、読み取り専用ファイルシステムを使用します。このチェックリストは、最も一般的なエスケープ手法をブロックする強力なベースラインを形成します。実装後は、docker-bench-securityなどのセキュリティツールを実行して設定を確認してください。セキュリティはプロセスであり、製品ではありません。新しいカーネルの脆弱性が発見されたら、設定を見直してください。ホスティングサービスを紹介する自動ランディングページについては、Pagenzaを使用して数分でサイトを公開できます。

Sources (5)