MENU

コンテナエスケープとは?Dockerで特権昇格・ホスト侵害に至る攻撃手口と防御策をわかりやすく解説

「Dockerコンテナの中は安全なはずだから、万が一侵入されてもホストには影響しないだろう」——そう考えている現場エンジニアは少なくありません。しかし現実には、設定ミスや脆弱性を突かれてコンテナの「壁」を突き破り、ホストOSを乗っ取られた事例が国内外で相次いでいます。

コンテナは名前空間(namespace)やcgroupsによってホストから論理的に分離されていますが、これは物理的な隔離ではありません。設定次第でその境界はあっけなく崩れます。

この記事では、コンテナエスケープ(Container Escape)の仕組み・主な攻撃手口・具体的な防御手順を、現場で使えるレベルで解説します。DockerやKubernetesを本番環境で運用している方は、ぜひ自社の設定と照らし合わせながら読んでみてください。

コンテナエスケープとは?Dockerで特権昇格・ホスト侵害に至る攻撃手口と防御策をわかりやすく解説 - 解説

目次

コンテナエスケープとは?

コンテナエスケープとは、攻撃者がDockerやcontainerd等のコンテナランタイム上で動くコンテナから脱出し、ホストOS上での操作権限を獲得する攻撃です。

コンテナはLinuxカーネルの次の機能で隔離されています。

・名前空間(Namespaces): プロセス・ネットワーク・ファイルシステム等をコンテナごとに見えない状態にする
・cgroups(Control Groups): CPU・メモリ等のリソースを制限する
・capabilities: rootが持つ特権を細かく分割し、必要な権限だけを付与する
・seccompプロファイル: コンテナが使えるシステムコールを制限する

コンテナエスケープはこれらの隔離を何らかの手段で突破し、ホストのカーネルやファイルシステムに直接アクセスする攻撃です。成功すると、攻撃者はホストOSのroot権限を手にし、同じホスト上の他コンテナの情報を盗んだり、バックドアを設置したりすることができます。

Dockerは内部でruncというコンテナランタイムを使っています。カーネルそのものや runc に脆弱性があれば、コンテナの壁を外側から崩せてしまう点が、仮想マシン(VM)との根本的な違いです。VMはハイパーバイザーが完全に隔離しますが、コンテナはあくまで同一カーネル上の「論理的な仕切り」です。

主な攻撃手口(敵を知る)

コンテナエスケープには複数のパターンがあります。攻撃者が実際に悪用する代表的な4つの手口を解説します。

1. 特権コンテナ(–privileged)の悪用

Dockerを起動する際に --privileged オプションを指定すると、そのコンテナはほぼすべてのLinux capabilitiesを持ち、ホストのデバイスファイルやカーネル機能にフルアクセスできます。テスト目的で安易に付与されることが多い設定ですが、これは事実上「コンテナに施錠されていない扉を作る」行為です。

攻撃者はコンテナ内から /dev/sda(ホストのディスク)をマウントし、ホストOS上のファイルを自由に読み書きできます。SSH認証鍵を書き換えてホストへのログインを確立するといった手口が実際に悪用されています。

# 特権コンテナ内からホストディスクをマウントする攻撃(概念) # 攻撃者が特権コンテナに侵入した場合の流れ # fdisk -l でホストのディスクを確認 # mkdir /mnt/host && mount /dev/sda1 /mnt/host # cat /mnt/host/etc/shadow # ホストのパスワードハッシュを取得 # cp ~/.ssh/authorized_keys /mnt/host/root/.ssh/ # 攻撃者の鍵を書き込む

2. Dockerソケット(/var/run/docker.sock)のマウント

CI/CDパイプラインやモニタリングツールの便宜のため、コンテナ内にDockerのUNIXソケット(/var/run/docker.sock)をマウントする構成が見られます。このソケットはDockerデーモン(root権限で動作)への通信経路であり、コンテナ内からアクセスできると、新たな特権コンテナを起動したりホストのファイルシステムをマウントしたりすることが可能になります。

攻撃者の視点では、docker.sock を持つコンテナへの侵入は「ホストへのパス」と同義です。コンテナを一つ踏み台にするだけで、ホスト全体を掌握できます。

3. capabilitiesの過剰付与

--privileged にはしないものの、CAP_SYS_ADMIN や CAP_NET_ADMIN などの強力なcapabilityを付与している場合も危険です。CAP_SYS_ADMIN はファイルシステムのマウントや名前空間の操作を許可するため、コンテナエスケープの足がかりになります。

2019年に公開された CVE-2019-5736(runcの脆弱性)は、コンテナ内から runc バイナリを書き換えてホスト上で任意コードを実行できるもので、特権を持たないコンテナでも悪用可能という点で業界に衝撃を与えました。

4. Linuxカーネルの脆弱性を利用した脱出

コンテナはホストカーネルを共有しています。ホストカーネルに権限昇格の脆弱性があれば、コンテナ内から悪用できます。代表例が CVE-2022-0847(Dirty Pipe) です。Linuxカーネル5.8~5.16の範囲に影響し、コンテナ内の一般ユーザーがroot権限に昇格でき、ホストに影響を及ぼす操作が可能になりました。コンテナだけ最新イメージを使っていても、ホストカーネルが古ければ意味がありません。

コンテナエスケープに利用される権限昇格(Privilege Escalation)の仕組みについては、別記事でも詳しく解説しています。

具体的な防御手順

1. –privilegedフラグは原則として使わない

本番・ステージング環境を問わず、--privileged は使用禁止にしてください。本当に特定の機能が必要な場合は、必要なcapabilityだけを個別に付与する方針を徹底します。

# NG: 特権コンテナ(使用禁止) # docker run --privileged myapp # OK: 必要なcapabilityのみ付与する docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp

どのcapabilityが必要かは docker run --cap-drop ALL で起動してエラーを確認し、必要なものだけ追加する方法で絞り込めます。

2. Dockerソケットをコンテナにマウントしない

CI/CDで「Dockerの中でDockerを動かす(DinD)」構成が必要な場合は、docker.sock のマウントではなく Kaniko や Podman などのデーモンレスビルドツールへの移行を検討してください。どうしても必要な場合は、そのコンテナのイメージ・依存関係・起動元を厳密に管理します。

3. rootlessモードでDockerを運用する

Dockerのrootlessモードを使うと、Dockerデーモン自体を非rootユーザーで動かせます。コンテナエスケープが起きてもホストのroot権限が得られないため、被害を大幅に限定できます。

# rootlessモードのセットアップ(Ubuntu/Debian) dockerd-rootless-setuptool.sh install # 設定後、rootlessモードで起動しているか確認 docker info | grep -i rootless # 出力例: rootless: true

4. seccompプロファイルとAppArmorを適用する

seccompはコンテナが使えるシステムコールを制限し、AppArmorはファイルシステムや機能へのアクセスをポリシーで制御します。Dockerはデフォルトのseccompプロファイルを持っていますが、本番環境ではアプリケーションの動作に合わせた厳格なプロファイルを作成するのが理想です。

seccompの詳細な設定は「Linuxのseccomp入門|システムコールフィルタリングでプロセスの攻撃面を最小化する実践ガイド」を参考にしてください。

5. コンテナのファイルシステムを読み取り専用にする

コンテナ実行時に --read-only フラグを付けると、コンテナ内からファイルシステムへの書き込みを禁止できます。攻撃者がコンテナに侵入しても、バックドアの設置やスクリプトの投下が難しくなります。書き込みが必要なディレクトリは --tmpfs でメモリ上に用意します。

# 読み取り専用+必要な箇所だけtmpfsを使う docker run --read-only --tmpfs /tmp --tmpfs /var/run myapp

6. ホストカーネルを常に最新に保つ

コンテナはホストカーネルを共有するため、カーネルの脆弱性がそのままコンテナエスケープの足がかりになります。unattended-upgrades や Livepatch を活用し、カーネルパッチを自動適用する仕組みを整えてください。再起動なしでパッチを適用したい場合は「Linuxのカーネルライブパッチ入門」も参照してください。

中小企業でも今日からできること

フルスペックのコンテナセキュリティ対策は一朝一夕では整えられませんが、次の3点は今日から実施できます。

・既存コンテナの特権確認: docker inspect コンテナ名 | grep Privileged で true になっているものをリストアップし、使用理由を確認する
・docker.sockマウントのチェック: docker inspect コンテナ名 | grep docker.sock で不要なマウントを発見・除去する
・ホストカーネルのバージョン確認: uname -r でカーネルバージョンを確認し、既知のCVEが適用済みかを照合する

Dockerコンテナ全体の設定を体系的に見直したい場合は、「Dockerコンテナのセキュリティ強化|特権コンテナ・rootless運用・イメージ脆弱性スキャンの実践ガイド」もあわせて参照してください。

また、Linuxのcapabilitiesをより深く理解したい方は「Linuxのcapabilities(ケーパビリティ)入門|rootを使わずに特権操作を安全に委譲する実践ガイド」も役立ちます。

よくある誤解と注意点

・「コンテナはVMと同じくらい安全」は誤り: VMはハイパーバイザーが完全に分離しますが、コンテナはカーネルを共有します。VMのような完全な隔離ではない点を前提にした設計が必要です
・「Kubernetesなら安全」は誤り: Kubernetes上でも特権コンテナや過剰なcapabilityは同様の脅威をもたらします。Pod Security Admission(PSA)でポリシーを強制することが重要です
・「公式イメージなら大丈夫」は誤り: 公式イメージでもバージョンが古ければ脆弱性を含みます。TrivyやGrypeなどのスキャナで定期的にイメージを検査する習慣をつけましょう
・「ネットワーク分離さえすれば」は誤り: ネットワーク分離はコンテナエスケープを防ぎません。エスケープはカーネルやファイルシステムへのアクセスで成立するため、実行時の設定が防御の要です

コンテナエスケープとは?Dockerで特権昇格・ホスト侵害に至る攻撃手口と防御策をわかりやすく解説 - まとめ

本記事のまとめ

コンテナエスケープは「コンテナは安全な箱」という思い込みを逆手に取った攻撃です。重要なポイントを整理します。

攻撃経路 主なリスク 対策
–privilegedコンテナ ホストディスクへのフルアクセス 使用禁止・capabilityを最小化
docker.sockマウント Dockerデーモン経由でホスト操作 マウント禁止・Kanikoなどへ移行
過剰なcapability 名前空間・カーネル操作が可能 –cap-drop ALLで最小権限化
カーネル脆弱性(CVE-2022-0847等) 一般ユーザーからroot権限の奪取 カーネルの定期更新・Livepatch
書き込み可能なコンテナFS バックドア・スクリプトの設置 –read-onlyで書き込みを禁止

コンテナの「隔離」は完璧ではありません。設定の一つひとつが防御の厚みになります。まずは --privileged と docker.sock のマウントを点検することから始めてみてください。

Linuxのサーバーセキュリティ全般については、姉妹サイトLinuxMaster.JPでも多くの実践記事を公開しています。あわせて参考にしてください。

PR

サイバーセキュリティプログラミング 第2版(Justin Seitz・Tim Arnold/オライリー・ジャパン)

攻撃者の視点でPythonを使ったセキュリティツールの実装を学べる実践書。コンテナ環境での権限昇格や脆弱性の仕組みをコードレベルで理解したい方に最適です。

関連記事をもっと読む

同じテーマの記事をまとめています。あわせて読みたい記事はこちらからご覧いただけます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次