2026 年版 包括的なコンテナセキュリティのベストプラクティス 17 選
コンテナの導入は拡大し続けているため、悪意のある攻撃者に初期侵入経路として悪用されないよう、今すぐコンテナセキュリティのベストプラクティスを実装する必要があります。
コンテナ技術は現在、業界全体で広く普及しており、事実上の標準技術となっています。2025年のCNCF Annual Surveyによると、本番環境でコンテナを利用している組織の割合は、2023年の41%から2025年には56%へと増加しました。また、コンテナ利用者の82%が本番環境でKubernetesを導入しており、さらに66%の組織が生成AIワークロード向けにKubernetesを活用しています。
一方で、コンテナの普及拡大に伴い、それを標的とした攻撃も増加しています。コンテナはライフサイクルが非常に短いという特性を持つため、セキュリティ対策は依然として大きな課題です。実際に、コンテナの70%は5分未満で破棄されるとされており、不審な挙動や侵害の調査を極めて困難にしています。
クラウドセキュリティにおいて重要なのは、コンテナに関連するセキュリティリスクへ可能な限り早い段階で対処することです。開発ライフサイクルの後半で対策を講じると、クラウド導入のスピードを低下させるだけでなく、セキュリティやコンプライアンス上のリスクも高まります。
そのため、コンテナセキュリティは、開発、配布、実行、脅威検知、インシデント対応といった、コンテナライフサイクルのあらゆるフェーズで実施する必要があります。

脅威、脆弱性、セキュリティ上の弱点からコンテナを保護するために、17のコンテナセキュリティ・ベストプラクティスに従うことが重要です。コンテナセキュリティには、以下の4つの要素が含まれます。
- 予防(Prevention)
- 保護(Protection)
- 検知(Detection)
- 対応(Response)
予防(Prevention):シフトレフト型コンテナセキュリティのための8つのステップ
コンテナ内でアプリケーションが実行される前の段階から、脅威を未然に防ぐためのさまざまなコンテナセキュリティ対策を適用できます。
近年、ソフトウェアサプライチェーンはサイバー攻撃における主要な侵入口の一つとなっています。現代の企業は、サードパーティ製アプリケーションや依存関係、パッケージに日常的に依存しており、攻撃者がサプライチェーンを悪用した重大なセキュリティインシデントも数多く発生しています。
コンテナイメージの開発・配布段階から予防的なセキュリティ対策を実施することで、将来的なトラブルや対応コスト、時間的損失を最小限の労力で大幅に削減できます。
1. CI/CDプロセスへのコードスキャンの統合
セキュリティスキャンとは、ソフトウェア、設定情報、インフラ構成を解析し、潜在的な問題や既知の脆弱性を検出するプロセスです。スキャンは、以下のさまざまな対象に対して実施できます。
- コード(Code)
- 依存関係(Dependencies)
- Infrastructure as Code(IaC)
- コンテナイメージ
- ホスト
- クラウド設定
まず注目すべきは、最初の段階である「コード」です。アプリケーションをビルドまたはリリースする前にコードをスキャンすることで、バグや悪用される可能性のある脆弱なコードを早期に検出できます。
アプリケーションコードの検査には、SAST(Static Application Security Testing:静的アプリケーションセキュリティテスト)ツールを利用して、脆弱性やその他の問題を検出できます。代表的なオープンソースのSASTツールには、複数のプログラミング言語向けに脆弱性スキャンを提供するSonarQubeや、Goコードを解析し、ルールベースで問題を検出するgosec、各種リンター(Linter)などがあります。
SASTは開発者のローカル環境でも実行できますが、CI/CDパイプラインへ統合することで、一定水準以上のコード品質を継続的に担保できます。例えば、セキュリティチェックに失敗した場合、Pull Requestを自動的にブロックする運用も可能です。
以下は、gosecを実行するGitHub Actionsの例です。
name: "Security Scan"
on:
push:
jobs:
tests:
runs-on: ubuntu-latest
env:
GO111MODULE: on
steps:
- name: Checkout Source
uses: actions/checkout@v2
- name: Run Gosec Security Scanner
uses: securego/gosec@master
with:
args: ./...

2. 依存関係スキャンによる外部脆弱性の低減
外部ライブラリやサードパーティ製コンポーネントを利用することは、利便性を高める一方で、既知のバグや脆弱性をアプリケーションに取り込んでしまうリスクも伴います。
そのため、依存関係スキャン(Dependency Scanning)を実施し、サードパーティ製ライブラリや依存パッケージに古いバージョンや脆弱性が含まれていないかを確認することが重要です。
こうした検査には、SCA(Software Composition Analysis:ソフトウェア構成分析)機能を持つツールを活用できます。npm、 Maven、Goなどのパッケージ管理ツールは、アプリケーションの依存関係と脆弱性データベースを照合し、問題のあるライブラリを検出して警告を提供できます。
例えば、Mavenでdependency-checkプラグインを有効化する場合は、pom.xml にプラグインを追加するだけで利用できます。
<project>
<build>
<plugins>
...
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
...
</project>
And every time maven is executed, it will generate a vulnerability report:

脆弱性を持つ依存ライブラリの混入を防ぐためには、修正済みバージョンへ継続的に更新することが重要です。
なお、依存関係スキャンをアプリケーションのビルド後に実施すると、スキャン精度が低下する可能性があります。これは、ビルド後には依存関係に関する一部のメタデータが失われるためです。特にGoやRustのような静的リンク型アプリケーションでは、依存関係の特定自体が困難、または不可能になるケースがあります。
3. イメージスキャンによるコンテナイメージの解析
アプリケーションをビルド・パッケージ化した後は、必要最小限のライブラリや依存フレームワーク(Python、Node.js など)、設定ファイルとともにコンテナへ格納するのが一般的です。
コンテナのビルドおよび実行時のセキュリティ強化については、「Dockerfile のベストプラクティス トップ 20」記事で詳しく学ぶことができます。
コンテナイメージには、イメージスキャンツールを用いて脆弱性分析を実施します。これにより、ベースイメージに含まれるOSパッケージ(rpm、dpkg、apk など)の脆弱性を検出できます。
また、Java、Node.js、Pythonなどの依存ライブラリに含まれる脆弱性も検出可能であり、前段階で依存関係スキャンを行っていない場合でも補完的な役割を果たします。

イメージスキャンは自動化しやすく、セキュリティポリシーとして強制適用することも容易です。CI/CDパイプラインへ組み込むほか、新しいイメージがレジストリへプッシュされた際に自動実行することも可能です。さらに、KubernetesのAdmission Controllerによってイメージを検証し、ポリシー違反のイメージがクラスタ内で実行されないよう制御できます。また、コンテナ起動時にイメージスキャンを実施するアプローチも有効です。
4. イメージコンテンツ信頼性(Image Content Trust)の強制
コンテナイメージの完全性を保証するために、Notaryなどのツールを用いてデジタル署名を付与できます。署名はAdmission Controllerやコンテナランタイムで検証可能です。これにより、信頼済みイメージのみの実行を許可し、改ざんや未承認イメージの利用を防止できます。
以下に簡単な例を示します。
$ docker trust key generate example1
Generating key for example1...
Enter passphrase for new example1 key with ID 7d7b320:
Repeat passphrase for new example1 key with ID 7d7b320:
Successfully generated and loaded private key. Corresponding public key available: /Users/airadier/example1.pub
Now, we have a signing key called “example1.” The public part is located in:
$HOME/example1.pub
and the private counterpart will be located in:
$HOME/.docker/trust/private/.key
Other developers can also generate their keys and share the public part.
Now, we enable a signed repository by adding the keys of the allowed signers to the repository (airadier/alpine in the example):
$ docker trust signer add --key example1.pub example1 airadier/alpine
Adding signer "example1" to airadier/alpine...
Initializing signed repository for airadier/alpine...
...
Enter passphrase for new repository key with ID 16db658:
Repeat passphrase for new repository key with ID 16db658:
Successfully initialized "airadier/alpine"
Successfully added signer: example1 to airadier/alpine
And we can sign an image in the repository with:
$ docker trust sign airadier/alpine:latest
Signing and pushing trust data for local image airadier/alpine:latest may overwrite remote trust data.
The push refers to repository [docker.io/airadier/alpine]
bc276c40b172: Layer already exists
latest: digest: sha256:be9bdc0ef8e96dbc428dc189b31e2e3b05523d96d12ed627c37aa2936653258c size: 528
Signing and pushing trust metadata
Enter passphrase for example1 key with ID 7d7b320:
Successfully signed docker.io/airadier/alpine:latest
If the DOCKER_CONTENT_TRUST environment variable is set to 1, then pushed images will be automatically signed:
$ export DOCKER_CONTENT_TRUST=1
$ docker push airadier/alpine:3.11
The push refers to repository [docker.io/airadier/alpine]
3e207b409db3: Layer already exists
3.11: digest: sha256:39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01 size: 528
Signing and pushing trust metadata
Enter passphrase for example1 key with ID 7d7b320:
Successfully signed docker.io/airadier/alpine:3.11
We can check the signers of an image with:
$ docker trust inspect --pretty airadier/alpine:latest
Signatures for airadier/alpine:latest
SIGNED TAG DIGEST SIGNERS
latest be9bdc0ef8e96dbc428dc189b31e2e3b05523d9... example1
List of signers and their keys for airadier/alpine:latest
SIGNER KEYS
example1 7d7b320791b7
Administrative keys for airadier/alpine:latest
Repository Key: 16db658159255bf0196...
Root Key: 2308d2a487a1f2d499f184ba...
環境変数 DOCKER_CONTENT_TRUST=1 を設定すると、Docker CLI は署名などの信頼情報を持たないコンテナイメージの pull を拒否します。
$ export DOCKER_CONTENT_TRUST=1
$ docker pull airadier/alpine-ro:latest
Error: remote trust data does not exist for docker.io/airadier/alpine-ro: notary.docker.io does not have trust data for docker.io/airadier/alpine-ro
Kubernetesクラスタでは、Admission Controller を用いて Content Trust を強制適用できます。これにより、署名済みかつ信頼されたコンテナイメージのみ実行を許可する運用が可能になります。
5. 一般的なコンテナセキュリティ設定ミスへの対処
ホスト、コンテナランタイム、Kubernetesクラスタ、クラウドリソースなどが誤って設定されている場合、攻撃者に侵入経路を与えたり、権限昇格やラテラルムーブメント(横展開)を容易にしてしまう可能性があります。
こうした設定ミスへの対処には、自動化を活用することが最も効果的です。さまざまなセキュリティツールを利用することで、自動的に設定を検査・修正できます。例えば、静的構成解析ツール(Static Configuration Analysis Tools)を使用すると、複数のレイヤーにわたる設定パラメータを検証し、問題点や修正方法に関するガイダンスを提供できます。
また、Center for Internet Security(CIS)は、インフラ構成を評価するためのベンチマークを提供しており、自身の環境と比較しながらセキュリティレベルを確認できます。
そのほか、以下のようなツールも利用できます。
ホストベンチマーク管理の例
Linuxをインストールしたばかりの物理マシンや、クラウド環境またはオンプレミス環境でプロビジョニングされた仮想マシン(VM)には、初期状態のままでは気付きにくい安全でない設定が含まれている場合があります。
これらを長期間運用する場合や、本番ワークロードの実行、インターネットへの公開を行う場合には、特別な注意が必要です。これはKubernetesやOpenShiftのノードについても同様です。結局のところ、これらもVMであり、クラウドプロバイダーが提供するクラスタだからといって、完全に安全な状態で提供されているとは限りません。
CIS(Center for Internet Security)は、Distribution Independent Linux向けのベンチマークに加え、Debian、CentOS、Red Hatなど各種Linuxディストリビューション向けのベンチマークも提供しています。
これらを利用することで、以下のような設定ミスを検出できます。
コンテナランタイムのセキュリティベンチマーク管理の例
自社で管理するサーバにコンテナランタイムであるDockerをインストールする場合は、セキュリティベンチマークを活用し、デフォルトの安全でない設定が適切に修正されていることを確認することが重要です。
例えば、Dockerクライアントコマンドに対する認可(Authorization)が有効化されていることを確認する必要があります。



オーケストレーター向けベンチマーク管理の例
Kubernetesでは、デフォルト設定のままでは多くの認証機構がサードパーティ製インテグレーションに委ねられています。そのため、セキュリティベンチマークを適用することで、潜在的な脆弱性や不適切な設定に対処することが重要です。以下の例では、--anonymous-auth 引数が false に設定されていることを確認する構成を示しています。これにより、匿名ユーザーによるアクセスを無効化できます。


6. IaCスキャンとPolicy as Codeの導入
クラウドリソースの管理は非常に複雑ですが、HashiCorp Terraform や AWS CloudFormation のようなツールを利用することで、その負担を軽減できます。
Infrastructure as Code(IaC)では、インフラ構成をコードとして定義し、リポジトリで管理・バージョン管理を行います。そして、自動化によって定義内容を適用し、既存インフラを最新状態に維持します。
IaCを利用している場合は、インフラを作成・更新する前に設定内容を検証できるIaCスキャンツールを導入することが重要です。これらのツールはリンターと同様に、ローカル環境およびCI/CDパイプライン内で実行でき、セキュリティ上の問題を含む変更をブロックする運用も可能です。
また、「Policy as Code」は、コンテナセキュリティやインフラ管理などに関するポリシーをコードとして定義・管理するアプローチです。この仕組みにより、IaCやKubernetes環境におけるコンプライアンスおよびガバナンスを自動化し、組織全体で一貫性とスケーラビリティを確保できます。
さらに、IaCセキュリティ機能を備えたコンテナセキュリティツールの導入も検討すべきです。Terraform、Helm、YAMLファイルなどを対象に設定ミスをスキャンし、その問題箇所をソースコードへマッピングできます。
加えて、ポリシー管理のOSS標準である Open Policy Agent(OPA)を利用することで、複数のIaCソースやKubernetesクラスタ全体に対して、一貫したポリシーを適用できます。
7. ホストスキャンによるホスト環境の保護
ホスト環境のセキュリティ確保は、コンテナを保護するのと同じくらい重要です。コンテナが稼働するホストは、通常、Linuxカーネルを含むOS、各種ライブラリ、コンテナランタイム、そしてバックグラウンドで動作する共通サービスや補助プロセスによって構成されています。
これらのコンポーネントのいずれかに脆弱性や設定ミスが存在すると、実行中のコンテナへ侵入するための入口として悪用されたり、DoS(Denial of Service)攻撃を引き起こす原因となる可能性があります。
例えば、コンテナランタイム自体の脆弱性が、実行中のコンテナへ直接影響を及ぼすことがあります。CVE-2021-20291 はその一例であり、新しいコンテナの作成を妨害するDoS攻撃として悪用可能です。
こうした脆弱なコンポーネントは、ホストスキャンツールを利用することで検出できます。ホストスキャンでは、Linuxカーネル、glibc のような標準ライブラリ、各種サービス、さらにはコンテナランタイムに存在する既知の脆弱性を検出可能です。
ホストスキャンツールから得られた情報をもとに、OS、カーネル、各種パッケージを更新し、重大かつ悪用されやすい脆弱性を解消することが重要です。少なくとも、脆弱性の存在を把握したうえで、以下のような追加防御策を適用する必要があります。
- ファイアウォールの導入
- ホストへのユーザーアクセス制限
- 不要サービスの停止
8. 安全でないコンテナの実行を防止する
最後の防御策として、Kubernetes の Admission Controller を利用することで、安全でないコンテナがクラスタ内で実行されるのを防ぐことができます。イメージスキャンのベストプラクティスによって多くのリスクを軽減できますが、実際にはすべてのデプロイがCI/CDパイプラインや既知のレジストリを経由するとは限りません。
サードパーティ製イメージや手動デプロイが行われるケースもあります。例えば、緊急対応時に手順を省略して手動デプロイを実施したり、クラスタへのアクセス権を持つ攻撃者がイメージをデプロイしたりする可能性があります。
Admission Controller を使用することで、Pod仕様(例:アノテーションの強制、特権Podの検出、HostPath利用の検出など)やクラスタの状態(例:クラスタ内でIngressホスト名の一意性を要求するなど)に基づいて、コンテナの実行を許可または拒否するポリシーを定義できます。
保護(Protection):コンテナを安全に実行するために
実行前に、ビルド時や設定時のコンテナセキュリティ・ベストプラクティスを適用していても、それだけでコンテナが100%安全になるわけではありません。
新たなコンテナ脆弱性は日々発見されており、現在安全に見えるコンテナであっても、明日には新たに公開された脆弱性の影響を受ける可能性があります。
ここで紹介するコンテナセキュリティ・ベストプラクティスは、コンテナ実行時のセキュリティ強化に重点を置いています。
1. リソースを保護する
コンテナやホストには脆弱性が存在する可能性があり、新たな脆弱性も継続的に発見されています。しかし、本当に危険なのはホストやコンテナの脆弱性そのものではなく、攻撃経路(Attack Vector)や悪用可能性(Exploitability)です。
例えば、ネットワーク経由で悪用可能な脆弱性であっても、実行中のコンテナや脆弱なサービスへの接続を防ぐことで保護できます。また、攻撃にホストへのローカルアクセス(ホストへのログイン)が必要な場合は、そのホストへのアクセスを制限できます。
ホスト、クラウドアカウント、各種リソースへアクセスできるユーザー数を制限し、不要なネットワーク通信を遮断することが重要です。そのために、以下のような仕組みを利用します。
- クラウドプロバイダーにおける Security Group、ネットワークルール、ファイアウォールルールなどを利用し、VM、VPC、インターネット間の通信を制限する
- ホストレベルのファイアウォールにより、必要最小限のサービスのみを公開する
- Kubernetesクラスタでは Kubernetes Network Policy を利用し、さらに Service Mesh や API Gateway などの追加ツールによって、ネットワークリクエストをフィルタリングする追加のセキュリティレイヤーを提供できる
2. イメージ署名を検証する
イメージ署名は、コンテナイメージが改ざんされていないことを保証するための保護メカニズムです。イメージ署名を検証することで、タグの可変性(Tag Mutability)を悪用した攻撃の一部を防ぐこともできます。これにより、そのタグが発行者によって署名された特定のダイジェストに対応していることを保証できます。
以下の図は、この攻撃の例を示しています。

3. 実行時におけるコンテナ権限を制限する
コンテナ内部の脆弱性が悪用された場合、その影響範囲(Blast Radius)は、コンテナに付与された権限や、ホストおよび他リソースからの分離レベルに大きく依存します。
実行時の設定によって、現在および将来発見される脆弱性の影響を、以下の方法で軽減できます。
- 実行ユーザーID(Effecitve User ID) :コンテナを root ユーザーで実行しないようにします。さらに、ホスト上の実ユーザーにマッピングされないランダムUID(OpenShift など)を利用するか、Docker や Kubernetes の User Namespace 機能を使用します
- コンテナ権限の制限:Docker や Kubernetes では、Capabilities の削除や Privileged コンテナの禁止が可能です。さらに、Seccomp や AppArmor により、コンテナが実行可能な操作範囲を追加で制限できます。
- リソース制限の追加:コンテナがメモリやCPUを過剰消費し、他アプリケーションを圧迫することを防ぎます。
- 共有ストレージやボリューム利用への注意:特に hostPath や、ホストファイルシステムの共有には注意が必要です。
- Pod Security Standards(PSS)の定義:クラスタ内にガードレールを設定し、設定ミスのあるコンテナを防止します。PSS は Admission Controller として機能し、Security Context が定義済みポリシーに準拠しない Pod を拒否します。
4. コンテナ脆弱性を適切に管理する
脆弱性は適切に管理・評価する必要があります。すべての脆弱性に対して修正パッチが存在するわけではなく、迅速かつ容易に適用できるとも限りません。
また、すべての脆弱性が容易に悪用されるわけではなく、中にはホストへのローカルアクセスや物理アクセスが必要となるものもあります。
そのため、以下を含む適切な脆弱性管理プログラムを実装することが重要です。
- 修正すべき対象を優先順位付けする:実行時に使用されているホストおよびコンテナの脆弱性に注力します。本番環境で使用されていない脆弱性への対応は、実際に組織へリスクをもたらす重大な脆弱性への対応時間を浪費する可能性があります。また、アクティブなエクスプロイトが存在しない脆弱性は、現在攻撃者に悪用されている脆弱性よりリスクが低いといえます。重大(Critical)または高(High)レベルの脆弱性のうち、修正パッチが存在し、アクティブなエクスプロイトが確認され、かつ本番環境で利用されているものは全体の1%に過ぎません。
- コンテナおよびホストを保護するための修正計画を立てる:チケットを作成・追跡し、脆弱性管理を標準的な開発ワークフローの一部に組み込みます。
- 悪用不可能な脆弱性に対する例外を定義する:これによりノイズを削減できます。ただし、恒久的な例外登録ではなく、一時的なスヌーズ設定を利用し、後で再評価できるようにすることが推奨されます。
脆弱性管理戦略には、特定条件に応じてアラートを発行できるコンテナ脆弱性スキャナーの利用も含めるべきです。また、さまざまなレベルで予防および保護を適用します。
- チケット管理:検出された脆弱性を開発者へ通知し、修正対応を促します。
- イメージレジストリ:脆弱なイメージが取得(pull)されること自体を防止します。
- ホスト / カーネル / コンテナ:重大な問題を持つコンテナに対して、実行ブロック、隔離、停止、あるいはホストやコンテナのシャットダウンなどの対応を行います。
また、継続的な脆弱性スキャンと再評価を実施し、実行中のコンテナに影響する新たな脆弱性が発見された際にアラートを受け取れるようにすることも重要です。
検知(Detection):悪意のある、または異常な挙動に対するアラート
予防(Prevention)および保護(Protection)の対策を実施した後は、コンテナ内で発生する不審または異常な挙動をどのように検知するかに注力する必要があります。
1. リアルタイムのイベントおよびログ監査を設定する
コンテナセキュリティに対する脅威は、さまざまなログやイベントソースを監査し、異常なアクティビティを分析することで検知できます。主なイベントソースには、以下が含まれます。
- ホストおよび Kubernetes のログ
- クラウドログ(AWS CloudTrail、Google Cloud の Cloud Audit Logs など)
- コンテナ内で実行されるシステムコール
Falco は、実行されたシステムコールを監視し、不審なアクティビティに対してアラートを生成できるツールです。コミュニティによって提供されているルールライブラリが含まれており、シンプルな構文を用いて独自ルールを作成することも可能です。また、Kubernetes の監査ログ(Audit Log)にも対応しています。
Falcoの活用例については、以下の「MITRE ATT&CK の検知」に関する記事で確認できます。
例えば、以下のルールでは、アカウント内で新しい ECS タスクが実行されるたびにアラートを発報します。
rule: ECS Task Run or Started
condition: aws.eventSource="ecs.amazonaws.com" and (aws.eventName="RunTask" or aws.eventName="StartTask") and not aws.errorCode exists
output: A new task has been started in ECS (requesting user=%aws.user, requesting IP=%aws.sourceIP, AWS region=%aws.region, cluster=%jevt.value[/requestParameters/cluster], task definition=%aws.ecs.taskDefinition)
source: aws_cloudtrail
description: Detect a new task is started in ECS.
インシデント対応とフォレンジック調査
システム内でセキュリティインシデントが発生していることを検知した場合は、脅威を封じ込め、被害の拡大を防ぐための対応を直ちに実施する必要があります。単純にコンテナを停止したりホストをシャットダウンしたりするのではなく、対象を隔離(Isolation)したり、一時停止(Pause)したり、スナップショットを取得したりする方法も検討すべきです。
適切なフォレンジック分析を行うことで、「何が」「いつ」「どのように」発生したのかを明らかにするための証拠を取得できます。特に、以下の点を特定することが重要です。
- そのセキュリティインシデントは実際の攻撃だったのか、それとも単なるコンポーネント障害だったのか
- 具体的に何が起き、どこで発生し、他に影響を受けた可能性のあるコンポーネントは存在するのか
- 同様のセキュリティインシデントを再発させないためには、どのような対策が必要か
1. イベントを隔離し、調査を実施する
セキュリティインシデントを検知した場合は、被害拡大を防ぐため、まず迅速に封じ込めを行う必要があります。
停止とスナップショット取得:可能であれば、対象のホストやコンテナを隔離します。コンテナランタイムでは、コンテナを「一時停止(pause)」したり(例:docker pause コマンド)、スナップショットを取得したうえで停止したりできます。ホストについても、ファイルシステムレベルでスナップショットを取得した後にシャットダウンする方法があります。EC2 や仮想マシン(VM)では、インスタンス全体のスナップショット取得も可能です。その後、対象を隔離し、取得したスナップショットをネットワーク接続のない安全なサンドボックス環境へコピーして、ホストやコンテナを再開できます。
調査とフォレンジック分析:隔離後は、可能であれば稼働中のコンテナやホストへアクセスし、実行中プロセスなどを調査します。すでに停止している場合は、取得したファイルシステムのスナップショットを中心に分析を行います。ログや変更されたファイルを確認することが重要です。また、イベント発生前後のシステムコールを記録し、コンテナやホスト停止後でも詳細な分析を可能にするフォレンジック支援ツールも存在します。
最終手段としてのコンテナ/ホスト削除:侵害された可能性のあるコンテナやホストを単純に破棄すれば、短期的には追加被害を防止できます。しかし、何が起きたのかを十分に調査しないまま対処すると、再発防止策を講じることが難しくなります。その結果、攻撃が発生するたびに対象を削除するだけの「いたちごっこ」状態に陥り、根本的な解決ができなくなる可能性があります。
2. 設定ミスを修正する
調査によって、なぜ攻撃が可能になったのかが明らかになるはずです。攻撃の原因を把握したら、同じ攻撃が再び発生しないよう、セキュリティ対策を講じる必要があります。
ホスト、コンテナ、またはアプリケーションが侵害される原因としては、過剰な権限設定や公開されたポート・サービスなどの不適切な設定、あるいは脆弱性の悪用が考えられます。
前者の場合は、再発防止のために設定ミスを修正します。後者の場合でも、ファイアウォール設定の見直し、より制限されたユーザーの利用、追加の権限設定やアクセス制御リスト(ACL)によるファイルやディレクトリの保護など、設定変更によって脆弱性の悪用を防止、または少なくとも影響範囲を限定できる可能性があります。
3. 脆弱性にパッチを適用する
可能であれば、脆弱性そのものを修正する必要があります。
- OS パッケージ(dpkg、rpm など)の場合:まず、ディストリビューションベンダーが修正済みバージョンのパッケージを提供しているか確認します。修正版が存在する場合は、パッケージまたはコンテナのベースイメージを更新します。
- Node.js、Go、Java などの言語パッケージの場合:依存関係の更新版を確認します。大規模なバージョン更新による互換性問題への対応やテストに十分な時間を割けない場合は、セキュリティ修正のみを含むマイナーアップデートやパッチバージョンを優先的に検討します。
- 未修正またはメンテナンスされていないパッケージの場合:手動適用やバックポート可能な修正が存在する場合があります。これには追加作業が必要になりますが、システムにとって重要なパッケージであり、公式な修正版がまだ提供されていない場合には必要となることがあります。NVD などの脆弱性データベース、ベンダーの情報提供、公開されているバグレポートなどを確認することで、修正方法を特定できる可能性があります。修正が存在する場合は、その内容を見つけ出せるはずです。
影響を受けるパッケージに適用可能な修正が存在しない場合でも、設定変更や保護対策(ファイアウォール、隔離など)によって脆弱性の悪用を防止できる可能性があります。また、脆弱性に対する深い理解が必要になる場合もありますが、自身のコードに追加のチェック処理を実装することも可能です。
例えば、Web API サーバーで使用されている JSON 処理ライブラリにオーバーフロー脆弱性が存在する場合、HTTP リクエストレベルで入力値を検査し、オーバーフローを引き起こす可能性のある文字列を含むリクエストを遮断することで、脆弱性の悪用を防止できる場合があります。
4. セキュリティ改善のサイクルを継続する
残念ながら、ホストやコンテナのセキュリティは、「一度設定すれば終わり」というものではありません。コンテナセキュリティのベストプラクティスを一度適用しただけで、その後更新不要になるわけではないのです。ソフトウェアやインフラは日々進化しており、それに伴って複雑性も増し、新たな設定ミスや問題が生まれます。その結果として、脆弱性や設定不備が発生します。また、新たな攻撃手法やエクスプロイトも継続的に発見されています。
まずは、予防とセキュリティのベストプラクティスを導入します。そのうえで、主にホストやワークロードに対して、さらにクラウドサービスにも保護対策を適用します。そして、異常な挙動を継続的に監視・検知し、対応、調査(Investigation)、およびインシデント報告を行います。
フォレンジックによって得られた証拠は、発見された脆弱性の修正や保護対策の改善につながり、セキュリティサイクルを再び最初から回すことになります。これには、以下のような対応が含まれます。
- イメージの再構築
- パッケージの更新
- リソース設定の再構成
- インシデントレポートの作成
その過程では、リスク評価と脆弱性管理も必要になります。大規模かつ複雑な環境では、管理すべき要素が膨大になる可能性があるため、分類と優先順位付けを行い、最もリスクの高い項目から対応することが重要です。
コンテナは保護すべき対象が複雑なスタックで構成されている
コンテナが広く普及した背景には、特に次の2つの大きな利点があります。
- コンテナは、ソフトウェアを配布・実行するための非常に便利な仕組みであること。ライブラリや依存関係をすべて含んだ自己完結型の実行イメージとして提供できる一方で、従来の仮想マシン(VM)イメージよりもはるかに軽量です。
- カーネルの namespace 機能を利用することで、プロセスをそれぞれ独立した「隔離環境(jail)」内で実行でき、高いレベルのセキュリティと分離性を提供できること。これには、マウント、PID、ネットワーク、IPC などの分離が含まれます。また、kernel cgroups によって CPU 使用率やメモリ使用量などのリソース制限も可能です。さらに、メモリ保護や権限制御などは、標準的なカーネルセキュリティ機構によって引き続き提供されます。

コンテナのセキュリティモデルは、多くの場合において十分なものと言えます。しかし例えば AWS では、サーバーレス環境向けに追加のセキュリティ対策を導入しています。具体的には、Firecracker と呼ばれるマイクロ VM 上でコンテナを実行することで、さらに一段階の仮想化レイヤーを追加し、顧客間をまたぐ侵害(cross-customer breaches)を防止しています。
コンテナはもともと、自己完結型アプリケーションを配布するための仕組みとして設計されており、隔離された環境でプロセスを実行できるようになっています。その分離機能を実現するために、コンテナではカーネルの namespace を利用した軽量な仕組みを採用しており、VM に必要なフル OS、CPU 仮想化、ハードウェア仮想化などの追加レイヤーを不要にしています。
一方で、こうした追加の抽象化レイヤーが存在しないこと、さらにコンテナがカーネル、OS、コンテナランタイムと密接に結び付いていることから、コンテナ内部から外部へ、あるいは外部からコンテナ内部へと侵入するためのエクスプロイトが成立しやすくなる側面もあります。
これは、コンテナが安全ではないという意味でしょうか?
これは、いわば「諸刃の剣」と言えます。
コンテナ内で動作するアプリケーションは、本質的にはマシン上で直接実行されるアプリケーションと変わりません。複数のアプリケーションとファイルシステムやプロセスを共有しており、脆弱性を含んでいる可能性があるという点でも同様です。
コンテナ上で実行されているからといって、こうした脆弱性自体を防げるわけではありません。しかし、アプリケーションの脆弱性を悪用してホストシステムへ侵入したり、他のアプリケーションのデータへアクセスしたりすることは、より困難になります。
その一方で、コンテナはカーネル機能、コンテナランタイム、さらに通常はクラスタやオーケストレーション基盤にも依存しており、それら自体が攻撃対象となる可能性もあります。
そのため、コンテナセキュリティを考える際には、システム全体のスタックを視野に入れる必要があります。そして、コンテナライフサイクルの各段階において、それぞれに適したセキュリティベストプラクティスを適用していくことが重要です。
それでは、これら2つの観点を次の図で整理し、各ブロックで適用可能なセキュリティ対策について見ていきましょう。
ECS Fargate や Google Cloud Run のようなサーバーレスコンピューティング環境では、共有責任モデル(Shared Responsibility Model)に基づき、スタックの一部を利用者側で管理できないケースがあります。
- この場合、クラウドサービスプロバイダー(CSP)が、基盤となる下位レイヤーの運用およびセキュリティ確保を担当します。
- そのため、利用者は主に上位レイヤーのセキュリティ対策に集中することができます。

Sysdig によるコンテナセキュリティ対策
コンテナを頻繁に利用し、Kubernetes 環境を運用している場合、脅威は非常に速いスピードで変化します。従来型のセキュリティツールでは可視性にギャップが生じることがあり、十分な対策が難しくなる場合があります。
Sysdig のコンテナセキュリティは、クラウドネイティブ環境に対応したセキュリティ機能を提供し、脅威への先回りを可能にします。また、組織に実際に影響を与えるリスクを優先的に特定し、脆弱性や脅威の背景情報やコンテキストを把握することができます。

Sysdig Secureのユースケーストップ5︓クラウドとコンテナの保護
イノベーションのスピードを維持しながら、コンテナの安全性を確保します。
