コンテナセキュリティの包括的なベストプラクティス
コンテナセキュリティのベストプラクティスを順守することは、検証済みのソフトウェアを確実に提供し、重大なセキュリティ侵害とその影響を防止するために不可欠です。これらのベストプラクティスは、堅牢な クラウドネイティブアプリケーション保護プラットフォーム (CNAPP) を実装する上で重要な要素です。
2023 CNCF 調査によると、90%を超える企業がコンテナを使用しており、84%の企業がKubernetesを使用または評価しています。コンテナ技術は主流となり、あらゆる場所で採用されています。
学ぶ内容
-
コンテナとは何か、そしてコンテナの有用性
-
予防策を確実に実施して、真にシフトする方法
-
実行時に脆弱性や設定ミスを検出して、正しい方法で保護する方法
しかし、コンテナは安全で孤立しているはずではないのでしょうか?まあ、ある程度はそうです。
たとえば、コンテナ内の悪用可能な脆弱性、公開されているメタデータ、および誤った認証情報設定が組み合わさると、クラウドインフラストラクチャ全体が危険にさらされる可能性があります。クラウドのラテラルムーブメントに関するブログで説明したように、ハッカーはこの一連の悪用と誤った設定を利用して、お客様のクラウドアカウントで暗号通貨のマイニングアプリケーションを実行することができます。
コンテナは、自己完結型のアプリケーションの配布メカニズムとして設計されており、アプリケーションを分離された環境で実行することができます。分離のために、コンテナはカーネルネームスペースを使用した軽量なメカニズムを採用しており、フルオペレーティングシステム、CPU、ハードウェアの仮想化など、VM に必要な複数の追加レイヤーが不要です。
これらの追加の抽象化レイヤーがないこと、およびカーネル、オペレーティングシステム、コンテナランタイムと緊密に結合していることから、コンテナの内部から外部へ、またはその逆へ、エクスプロイトを使用して容易に侵入することができます。
コンテナセキュリティのベストプラクティスには、配信されるアプリケーションやコンテナイメージ自体のセキュリティだけでなく、コンテナの構築、配布、および特別な実行に使用されるコンポーネントスタック全体も含まれます。
これには以下が含まれます。
ホストまたは VM
- コンテナランタイム
- クラスタテクノロジー
- クラウドプロバイダの設定
- その他
コンテナセキュリティは、開発、配布、実行、脅威の検知、対応という各段階に適用することができます。
クラウドとコンテナを保護する ための5つのセキュリティベストプラクティス
コンテナの安全を確保しながら、イノベーションのスピードに対応しましょう。

興味深い詳細を掘り下げ、一般的な考え方を 17 の具体的なコンテナセキュリティのベストプラクティスに分解し、DevOps ワークフローに適用できる形でご説明いたします。
複雑な構造
コンテナの人気の高さは、2 つの非常に便利な機能によるものです。
- コンテナは、すべてのライブラリと関連コンポーネントを含む自己完結型の実行可能イメージとして、ソフトウェアの配布と実行に非常に便利な手段です。また、従来の VM イメージよりもはるかに軽量です。
- カーネルネームスペースを使用してプロセスを独自の「ジャイル」内で実行することで、マウント、PID、ネットワーク、IPC など、高いセキュリティと隔離性を提供します。また、カーネル cgroups を通じて CPU 使用量やメモリの使用量を制限することも可能です。メモリ保護や権限の強制など、標準のカーネルセキュリティメカニズムによる機能も引き続き提供されます。

コンテナのセキュリティモデルは、ほとんどの場合で十分かもしれませんが、たとえば AWS は、サーバーレスソリューションに追加のセキュリティ機能を追加しています。これは、顧客間の侵害を防ぐために、仮想化をさらに 1 層追加したマイクロ仮想マシン「Firecracker」内でコンテナを実行することで実現しています。
これは、コンテナは安全ではないということですか?
これは、両刃の剣と捉えることができます。
コンテナ内で実行されているアプリケーションは、マシン上で直接実行されているアプリケーションと何ら変わりません。ファイルシステムやプロセスを他の多くのアプリケーションと共有しています。ある意味では、これらは単に脆弱性を悪用される可能性があるアプリケーションに過ぎません。
コンテナ内で実行されているからといって、これを防ぐことはできませんが、アプリケーションの脆弱性からホストシステムに侵入したり、他のアプリケーションのデータにアクセスしたりすることは、はるかに困難になります。
一方、コンテナは、別のカーネル機能セット、コンテナランタイム、そして通常はクラスタやオーケストレーターにも依存しており、これらも悪用される可能性があります。
したがって、スタック全体を考慮し、コンテナのライフサイクルのさまざまな段階でコンテナセキュリティのベストプラクティスを適用する必要があります。次の図で、この 2 つの側面を反映し、各ブロックに適用できるプラクティスに焦点を当ててみましょう。
サーバーレスコンピューティングエンジン ECS Fargate、Google Cloud Run など、これらの要素の一部が当社の制御が及ばない場合もありますので、当社は責任分担モデルで対応しています。
- プロバイダは、基本要素の稼働とセキュリティの維持に責任を負います
- そしてお客様は、上位層に集中することができます。

クラウドとコンテナを保護する ための5つのセキュリティ ベストプラクティス
イノベーションのスピードに対応しながら、コンテナの安全を確保してください。
対策:コンテナセキュリティのシフト・レフトを実現する 8 つのステップ
コンテナ内のアプリケーションが実行される前に、脅威の発生を防ぐためにさまざまな手法を適用できる場所がいくつかあります。
ソフトウェアサプライチェーンは、近年、サイバー脅威の最大の侵入ポイントとなっています。現代の企業は、サードパーティのアプリケーション、関連コンポーネント、パッケージに日常的に依存しており、脅威アクターがサプライチェーンを悪用した重大なセキュリティインシデントが数多く発生しています。
予防とコンテナセキュリティの早期適用が鍵となり、コンテナイメージの開発および配布時にいくつかのベストプラクティスを適用すれば、最小限の労力で多くのトラブル、時間、および費用を節約できます。
1. CI/CD プロセスにコードスキャンを統合します。
セキュリティスキャンとは、ソフトウェア、構成、またはインフラストラクチャを分析し、潜在的な問題や既知の脆弱性を検出するためのプロセスです。スキャンは、さまざまな段階で実行できます。
- コード
- 関連コンポーネント
- インフラストラクチャとしてのコード
- コンテナイメージ
- ホスト
- クラウド構成
- … その他
最初の段階であるコードに焦点を当てましょう。アプリケーションを出荷する前、あるいはアプリケーションを構築する前に、コードをスキャンして、バグや悪用される可能性のあるコード(新しい脆弱性)を検出することができます。
アプリケーションコードの場合、Snyk Code や Checkmarx One などの SAST(静的アプリケーションセキュリティテスト)ツールを使用して、脆弱性やその他の問題をスキャンすることができます。また、さまざまな言語の脆弱性スキャナを提供する sonarqube、ルールやリンターなどに基づいて Go コードを分析し、問題を検出する gosec などのオープンソースの SAST ツールもあります。
これらのツールは開発者のマシンで実行することもできますが、コードスキャンツールを CI/CD プロセスに統合することで、最低限のコード品質を確保することができます。たとえば、一部のチェックに失敗した場合、プルリクエストをデフォルトでブロックすることができます。
gosec を実行する Github Action
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: ./...
Code language: Perl (perl)

2. 関連コンポーネントのスキャンにより、外部からの脆弱性を軽減します。
サードパーティのライブラリやフレームワークを使用していないアプリケーションは、ごくごく小規模なおもちゃのようなものだけです。しかし、外部依存関係からコードを再利用すると、その依存関係に含まれるバグや脆弱性もアプリケーションに組み込まれることになります。依存関係のスキャンは、あらゆるアプリケーションのビルドプロセスにおけるベストプラクティスとして組み込む必要があります。
Snyk のような SCA (ソフトウェア構成分析) 機能を提供するツールを使用すると、サードパーティの関連コンポーネントを特定することができます。npm、maven、go などのパッケージ管理ツールは、脆弱性データベースとアプリケーションの関連コンポーネントを照合し、有用な警告を表示します。
たとえば、Maven で依存関係チェックプラグインを有効にするには、pom.xml
にプラグインを追加するだけです。
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>6.2.2</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
...
</project>
Code language: Perl (perl)
そして、Maven が実行されるたびに、脆弱性レポートが生成されます。

関連コンポーネントを修正済みの新しいバージョンに更新して、関連コンポーネントによる脆弱性の導入を回避してください。

関連コンポーネントは後でスキャンすることも可能ですが、アプリケーションのビルドが完了すると、一部のメタデータ情報が利用できなくなるため、依存関係のスキャン精度が低下します。また、Go や Rust などの静的リンクアプリケーションでは、依存関係のスキャンが不可能になる場合もあります。
3. イメージスキャンを使用してコンテナイメージを分析します。
アプリケーションのビルドとパッケージングが完了したら、通常、最小限のライブラリ、依存フレームワーク(Python、Node など)、および構成ファイルとともにコンテナ内にコピーします。コンテナのビルドと実行時のセキュリティ確保に焦点を当てたベストプラクティスについては、「Dockerfile のベストプラクティス 20」をご覧ください。
イメージスキャナを使用して、コンテナイメージを分析します。イメージスキャンツールは、コンテナイメージのベースディストリビューションによって提供されるオペレーティングシステムパッケージ (rpm、dpkg、apk など) の脆弱性を検出します。また、前の段階で依存関係のスキャンを適用していない場合でも、Java、Node、Python などのパッケージの依存関係にある脆弱性も検出します。

イメージのスキャンは、自動化および実施が簡単です。CI/CD パイプラインの一部として組み込み、新しいイメージがレジストリにプッシュされたときにトリガーしたり、クラスタアドミッションコントローラで検証して、準拠していないイメージが実行されないようにすることができます。別のオプションとして、Sysdig を使用して、イメージが実行されているホストで実行が開始されるとすぐにイメージをスキャンすることもできます。
例としては、Github Action と Sysdig Secure Inline Scan Action の統合があります。
name: "Security Scan"
on:
push:
jobs:
build-and-scan:
runs-on: ubuntu-latest
steps:
- name: Build the Docker image
run: docker build . --file Dockerfile --tag my-image:latest
- name: Scan image
id: scan
uses: sysdiglabs/scan-action@v3
with:
image-tag: my-image:latest
sysdig-secure-token: ${{ secrets.SYSDIG_SECURE_TOKEN }}
input-type: docker-daemon
run-as-user: root
Code language: Perl (perl)
前の例では、Docker イメージを構築し、Docker デーモンからローカルでスキャンしています。
スキャン結果はアクションの出力の一部として直接提供され、チェックの状態に応じてプルリクエストのマージをブロックすることができます。

4. イメージコンテンツの信頼性を強化します。
コンテナイメージの整合性は、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
Code language: Perl (perl)
現在、「example1」という署名キーがあります。公開部分は次の場所にあります。
$HOME/example1.pub
Code language: Perl (perl)
そして、民間企業は以下に拠点を置くことになります。
$HOME/.docker/trust/private/<key ID>.key
Code language: Perl (perl)
他の開発者もキーを生成し、公開部分を共有することができます。
次に、許可された署名者のキーをリポジトリ(この例では airadier/alpine)に追加して、署名付きリポジトリを有効にします。
$ 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
Code language: Perl (perl)
そして、リポジトリ内のイメージに次のように署名することができます。
$ 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
Code language: Perl (perl)
DOCKER_CONTENT_TRUST
環境変数が 1
に設定されている場合、プッシュされたイメージは自動的に署名されます。
$ 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
Code language: Perl (perl)
イメージの署名者は、次のようにして確認できます。
$ 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...
Code language: Perl (perl)
環境変数 DOCKER_CONTENT_TRUST
が 1
に設定されている場合、Docker CLI は信頼情報のないイメージのプルを拒否します。
$ 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
Code language: Perl (perl)
Admission コントローラを使用して、Kubernetes クラスタでコンテンツの信頼を強制することができます。
5. 一般的なコンテナセキュリティの設定ミスと修正方法
ホスト、コンテナランタイム、クラスタ、またはクラウドリソースの設定が間違っていると、攻撃の侵入経路を残したり、特権をエスカレートして横移動を行う簡単な手段を作ったりする可能性があります。
ベンチマーク、ベストプラクティス、および強化ガイドでは、これらの設定ミスを発見する方法、それが問題となる理由、およびそれらを修正する方法に関する情報を提供しています。さまざまな情報源の中でも、Center for Internet Security (CIS) は最も重要です。これは、さまざまな環境に関する無料のベンチマークを公開している非営利団体で、あらゆる個人や企業が知識を提供することができます。セキュリティのベンチマークの事実上の標準となっています。
コンテナのセキュリティに関するこのような設定を確実に確認する最善の方法は、可能な限り自動化することです。このために、主に静的構成分析に基づくいくつかのツールがあり、さまざまなレベルの構成パラメータを確認し、その修正に関するガイダンスを提供することができます。Sysdig Secure には、コンプライアンス機能が含まれており、CIS ベンチマークや、PCI DSS、SOC 2、NIST 800-53、NIST 800-190、 HIPAA、ISO 27001、GDPR などのコンプライアンス基準に基づいて、すべてのインフラストラクチャ(Linux ホスト、Docker、Kubernetes、EKS、GKE、AKS、MKE、OpenShift クラスタなど)を、単一の集中型ダッシュボードで

その他、linux-bench、docker-bench、kube-bench、kube-hunter、kube-striker、Cloud Custodian、OVAL、OS Queryなどのツールも利用できます。
ホストベンチマーク制御の例
Linux をインストールしたばかりの物理マシン、クラウドプロバイダでプロビジョニングされた仮想マシン、またはオンプレミスには、ご存じない、セキュリティ上の問題のある設定がいくつか含まれている可能性があります。これらを長期間、本番ワークロードやインターネットに接続して使用する場合は、特別な注意が必要です。これは、Kubernetes や OpenShift ノードにも当てはまります。結局のところ、これらは仮想マシンです。クラウドプロバイダーがプロビジョニングしたクラスターを使用しているからといって、完全にセキュリティが確保されていると仮定しないでください。
CISには、ディストリビューションに依存しないLinux用のベンチマークと、Debian、CentOS、Red Hat、およびその他の多くのディストリビューション専用のベンチマークがあります。
検出可能な設定ミスの一例:
Linux ディストリビューションの例
次の図は、CIS Benchmark for Distribution Independent Linux によって提供されており、rsh
サーバーが有効になっていないことを確認するための設定です。


コンテナのセキュリティ確保の例 ランタイムベンチマークの制御
Docker などのコンテナランタイムを所有するサーバーに自分でインストールする場合は、ベンチマークを使用して、デフォルトの安全でない設定がすべて修正されていることを確認することが不可欠です。次の図は、Docker クライアントコマンドの認証が有効になっていることを確認するための設定を示しています。


オーケストレータのベンチマーク制御の例
Kubernetes は、デフォルトでは、多くの認証メカニズムをサードパーティの統合によって管理するようにしています。ベンチマークを実行することで、考えられるすべてのセキュリティ上の問題に対処することができます。以下のイメージは、–anonymous-auth 引数が false に設定されていることを確認するための設定を示しています。


クラウドベンチマーク制御の例
クラウドプロバイダーアカウントのベンチマーク(クラウドセキュリティポスチャ管理(CSPM)とも呼ばれます)は、アカウント上のすべての資産のセキュリティをチェックするため、不可欠です。攻撃につながる可能性のあるすべての設定、非公開であるべきリソースが公開されている場合(S3 バケットなど)、または暗号化されていないストレージは、この種のベンチマークで定義されます。クラウドアカウント内の資産は常に変化するため、すべてが可能な限り安全であることを常に監視する必要があるため、このベンチマークは自動化することが不可欠です。次のイメージは、90 日以上使用されていない認証情報が無効になっていることを確認する設定チェックの例です。



6. IaC スキャンとポリシーをコードとして組み込みます。
クラウドリソースの管理は複雑な作業ですが、Terraform や CloudFormation などのツールを使用すると、その負担を軽減することができます。インフラストラクチャはコードとして「宣言」され(別名「Infrastructure as Code」)、リポジトリに保存され、バージョン管理されます。そして、自動化によって定義の変更が適用され、既存のインフラストラクチャが宣言内容に合わせて最新の状態に保たれます。
インフラストラクチャ・アズ・コードを使用している場合は、インフラストラクチャが作成または更新される前に、その構成を検証するためのIaCスキャン機能を備えたツールを組み込んでください。他のリンティングツールと同様に、IaCスキャンツールをローカルおよびパイプラインに適用し、セキュリティ問題を引き起こす変更をブロックすることを検討してください。
Policy-as-codeは、コンテナのセキュリティやインフラストラクチャなどを管理するポリシーをコードで定義、管理する関連アプローチです。このアプローチを活用することで、IaC および Kubernetes 環境全体のコンプライアンスとガバナンスを自動化し、組織全体の拡張性と一貫性を確保することができます。
Sysdig には、IaC セキュリティ機能が含まれており、Terraform、Helm、YAML ファイルなどの IaC ツール全体の設定ミスをスキャンしてソースにマッピングするほか、ポリシー管理の OSS 標準である OPA を活用して、複数の IaC ソースおよび Kubernetes クラスタ全体で一貫したポリシーを適用します。

7. ホストスキャンでホストを保護します
ホストの保護は、コンテナの保護と同じくらい重要です。コンテナが実行されているホストは、通常、Linux カーネルを備えたオペレーティングシステム、一連のライブラリ、コンテナランタイム、およびバックグラウンドで実行されているその他の一般的なサービスとヘルパーで構成されています。これらのコンポーネントはいずれも、脆弱性や設定ミスがあり、実行中のコンテナへのアクセスポイントとして利用されたり、サービス拒否攻撃の原因となる可能性があります。
たとえば、コンテナランタイム自体に問題があると、実行中のコンテナに影響を与える可能性があります。ホストで新しいコンテナの作成を妨げる DoS 攻撃がそれです。
ホスト構成の強化については、「安全でない構成」のセクションで既に説明しました。しかし、脆弱なコンポーネントをどのように検出すればよいのでしょうか?ホストスキャンツールを使用すると、カーネル、glibc などの標準ライブラリ、サービス、さらにはホスト上に存在するコンテナランタイムの既知の脆弱性を検出することができます(コンテナイメージに対するイメージスキャンとよく似ています)。
Sysdig は、ホストを透過的にスキャンし、検出した脆弱性を報告します。次の図は、ダッシュボードでリスクを一目で簡単に検出できることを示しています。

この情報を使用して、オペレーティングシステム、カーネル、パッケージなどを更新してください。最も重要で悪用される可能性の高い脆弱性を排除するか、少なくともその存在を認識し、ファイアウォール、ホストへのユーザーアクセス制限、使用されていないサービスの停止などの他の保護メカニズムを適用してください。
8. 安全でないコンテナの実行を防ぐ
最後の防衛線として、Kubernetes Admission Controllers は、安全でないコンテナがクラスタ内で実行されるのをブロックすることができます。前述のイメージスキャンに関するベストプラクティスにより、この問題は軽減できますが、デプロイするすべてが CI/CD パイプラインや既知のレジストリを通過するとは限りません。サードパーティのイメージや手動によるデプロイもあります。たとえば、急いで手動デプロイを行うためにプロトコルをスキップしたり、クラスタにアクセスできる攻撃者がイメージスキャナをスキップしてイメージをデプロイしたりする可能性があります。
アドミッションコントローラーを使用すると、ポッドの仕様(アノテーションの適用、特権ポッドの検出、ホストパスの使用など)やクラスタのステータス(クラスタ内のすべてのインバウンドホストが一意である必要があるなど)に基づいて、コンテナを受け入れるかブロックするかを定義するポリシーを定義できます。
クラウドとコンテナを保護する ための5つのセキュリティ ベストプラクティス
イノベーションのスピードに対応しながら、コンテナの安全を確保してください。
保護 – コンテナを安全に実行
実行直前にビルド時間と構成のコンテナセキュリティのベストプラクティスを順守しても、コンテナの安全性を 100% 確保することはできません。新しいコンテナの脆弱性は毎日発見されているため、今日は非常に安全であるコンテナも、明日には新たに公開されたエクスプロイトの潜在的な被害者になる可能性があります。
このセクションでは、コンテナの脆弱性管理と保護対策ワークロードに組み込むための、コンテナセキュリティのベストプラクティスをご紹介します。
リソースを保護します
コンテナやホストには脆弱性が存在し、新たな脆弱性が継続的に発見されています。ただし、危険なのはホストやコンテナの脆弱性そのものではなく、攻撃ベクトルと悪用可能性です。
たとえば、実行中のコンテナまたは脆弱なサービスへの接続を妨害することで、ネットワーク経由で悪用可能な脆弱性から保護できます。また、攻撃ベクトルがホストへのローカルアクセス(ホストへのログイン)を必要とする場合は、そのホストへのアクセスを制限できます。
したがって、ホスト、クラウドアカウント、およびリソースにアクセスできるユーザーの数を制限し、さまざまなメカニズムを使用して不要なネットワークトラフィックをブロックしてください。
- クラウドプロバイダーの VPC、セキュリティグループ、ネットワークルール、ファイアウォールルールなど、VM、VPC、およびインターネット間の通信を制限します。
- ホストレベルのファイアウォールで、必要なサービスの最小セットのみを公開します。
- Kubernetes ネットワークポリシー、およびサービスメッシュや API ゲートウェイなどの追加ツールを使用すると、ネットワークリクエストをフィルタリングするためのセキュリティ層を追加できます。
イメージの署名の検証
「イメージコンテンツの信頼性」で説明したように、イメージの署名は、イメージが改ざんされていないことを保証するための保護メカニズムです。イメージの署名を検証することで、タグの可変性を利用した一部の攻撃も防止でき、タグが発行者によって署名された特定のダイジェストに対応していることを確認できます。以下の図は、この攻撃の例です。

実行時にコンテナの権限を制限する
コンテナ内で悪用される脆弱性の影響範囲は、コンテナの権限、およびホストやその他のリソースからの分離のレベルに大きく依存します。実行時設定により、既存および将来の脆弱性の影響を次のように軽減できます。
- 効果的なユーザー:コンテナを root として実行しないでください。さらに、ホストの実際のユーザーにマップされないランダムな UID(Openshift など)を使用するか、Docker および Kubernetes で(準備ができた時点で)ユーザーネームスペース機能を使用してください(公開時点では利用できません)。
- コンテナの権限を制限する:Docker および Kubernetes には、機能を削除し、特権コンテナを許可しない方法があります。Seccomp および AppArmor を使用すると、コンテナが実行できる操作の範囲をさらに制限することができます。
- リソース制限を追加します。コンテナがすべてのメモリまたは CPU を消費して、他のアプリケーションの動作を妨害することを防ぎます。
- 共有ストレージまたはボリュームには注意してください。具体的には、hostPath や、ホストからのファイルシステムの共有などです。
- hostNetwork、hostPID、hostIPCなどのその他のオプション: Kubernetes は、コンテナとホストのネームスペースを共有し、分離を弱めます。
- Pod Security Standards (PSS) および Security Context Constraints (SCCs for Openshift) を定義します:クラスタにガードレールを設定し、コンテナの設定ミスを防ぎます。PSS および SCC は、セキュリティコンテキストが定義されたポリシーに準拠していない場合、ポッドを拒否するアドミッションコントローラーです。
コンテナの脆弱性を賢く管理
脆弱性を賢く管理および評価します。すべての脆弱性に修正プログラムが用意されているわけではなく、また、現在、簡単に適用できるとは限りません。
しかし、そのすべてが簡単に悪用できるわけではなく、悪用するにはローカルアクセスや物理的なアクセスが必要な場合もあります。
次のような優れた戦略を立てる必要があります。
- 修正が必要なものを優先付けする:ランタイムで使用されているホストおよびコンテナの脆弱性に焦点を当てる必要があります。本番環境には存在しない脆弱性に対処すると、組織を実際に危険にさらす脆弱性に対処するために使える貴重な時間を無駄にしてしまいます。また、積極的に悪用されていない脆弱性は、悪意のある攻撃者によって悪用されている脆弱性よりもリスクが低くなります。重大または高深刻度の脆弱性のうち、修正プログラムが利用可能で、積極的に悪用されており、本番環境で使用されているものは 1% にすぎません。これらの最もリスクの高い脆弱性に優先順位を付けることで、重要なリスクに対処しながら、時間を大幅に節約することができます。
- コンテナとホストを保護するための対策として、修正の適用を計画します:チケットを作成して追跡し、脆弱性管理を標準的な開発ワークフローの一部とします。
- 影響がないと判断した脆弱性については、例外を作成します:これにより、ノイズが減少します。例外を永続的に追加する代わりに、一時停止して後で再評価することを検討してください。
戦略は、コンテナ脆弱性スキャナが、特定の基準に従って検出された脆弱性についてアラートをトリガーし、次のようなさまざまなレベルで予防と保護を適用するために使用できるポリシーに落とし込む必要があります。
- チケット発行:検出された脆弱性を開発者に通知し、修正を適用できるようにします。
- イメージレジストリ:脆弱なイメージがプルされないようにします。
- ホスト/カーネル/コンテナ:実行中のコンテナをブロックし、追加の保護対策を追加するか、重大な問題に対してホストまたはコンテナを強制終了、隔離、またはシャットダウンして対応します。
また、実行中のコンテナに適用される新しい脆弱性が発見された場合に確実にアラートを受け取るよう、脆弱性のスキャンと再評価を継続的に実行することも重要です。Sysdig Secure は、脆弱性フィードが更新されるたびにスキャンポリシーを再評価するため、この点で役立ちます。
検知 – 異常な動作に対するアラート
これまで、予防と保護、コンテナを最良の状態で稼働させ、潜在的および既知の攻撃を予測することに重点を置いてきました。コンテナを構築、配布、実行する際に、適切な権限と保護機能を備えた予防手法を適用し、基盤となるスタックを確実に保護することで、攻撃者が実行できる行動の範囲を制限することができます。しかし、だからといって、コンテナの実行を忘れて、適用したセキュリティ対策だけを信頼してよいというわけではありません。セキュリティ対策が実行されている場合でも、その対策が攻撃の対象になる可能性があります。アプリケーションの異常な動作や予期しない動作を検出して、是正措置を講じ、セキュリティインシデントの再発を防ぐ必要があります。
攻撃ベクトルにはさまざまなものがあります。たとえば、MITRE ATT&CK は、「現実の世界での観察結果に基づく」戦術と手法の広範なリストを提供しており、予防措置の適用と、攻撃や侵入が行われている可能性のある異常な動作を検知するための活動分析の両方に利用できます。MITRE ATT&CK マトリクス for コンテナは、コンテナテクノロジーを具体的に標的とした手法を網羅しています。

リアルタイムのイベントおよびログ監査を設定
コンテナのセキュリティに対する脅威は、さまざまなログおよびイベントのソースを監査し、異常なアクティビティを分析することで検出できます。イベントのソースには、次のようなものがあります。
- ホストおよび Kubernetes のログ
- クラウドログ(AWS の CloudTrail、GCP の Activity Audit など)
- コンテナ内のシステムコール
Falco は、実行されたシステムコールを監視し、不審なアクティビティについてアラートを生成することができます。コミュニティが提供したルールライブラリが含まれており、簡単な構文を使用して独自のルールを作成することもできます。Kubernetes 監査ログもサポートされています。
Falco の使用例については、MITRE ATT&CK の検出に関する記事でご覧いただけます。
Sysdig Secure は Falco の機能を拡張し、イベントを di から取り込むこともできます。
たとえば、次のルールは、アカウントで新しい 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.
Code language: Perl (perl)
Sysdig には、対応するコンプライアンス基準および制御にタグ付けされた、増え続ける一連のルールも搭載されており、インフラストラクチャ内のすべてのセキュリティイベントを調査するための一元化されたダッシュボードも提供しています。

インシデント対応とフォレンジック
システムでセキュリティインシデントが発生したことを検知したら、脅威を阻止し、さらなる被害を最小限に抑えるための措置を講じてください。コンテナを強制終了したり、ホストをシャットダウンしたりする代わりに、コンテナを分離、一時停止、またはスナップショットを撮ることを検討してください。適切なフォレンジック分析を行うことで、多くの手がかりを得ることができ、何が、いつ、どのように発生したかを明らかにすることができます。以下を特定することが重要です。
- セキュリティインシデントが実際の攻撃か、単なるコンポーネントの故障か。
- 何が起こったのか、どこで発生したのか、他の影響を受ける可能性のあるコンポーネントはあるか?
- セキュリティインシデントの再発を防止するにはどうすればよいか?
分離して調査する
セキュリティインシデントが検出されたら、まずそれを迅速に停止して、さらなる被害を最小限に抑える必要があります。
- 停止とスナップショット:可能であれば、ホストまたはコンテナを分離します。コンテナランタイムでは、コンテナを「一時停止」(「docker pause」コマンド)するか、スナップショットを撮ってから停止することができます。ホストの場合は、ファイルシステムレベルでスナップショットを撮ってからシャットダウンします。EC2 または VM インスタンスの場合は、インスタンスのスナップショットも撮ることができます。その後、分離に進みます。スナップショットを、ネットワークに接続されていない安全なサンドボックス環境にコピーし、ホストまたはコンテナを再開することができます。
- 調査とフォレンジック:分離したら、理想的には、ライブコンテナまたはホストを調査し、実行中のプロセスを調査します。ホストまたはコンテナが起動していない場合は、ファイルシステムのスナップショットに集中することができます。ログと変更されたファイルを確認します。Sysdig Secure captures のようなツールを使用すると、イベントに関するすべてのシステムコールを記録し、コンテナまたはホストがシャットダウンした後でも調査を行うことができるため、フォレンジック機能が大幅に強化されます。
- 最終手段として侵害されたコンテナと/またはホストを停止する:疑わしい活動を単純に破壊することで、短期的な追加の被害を防止できます。しかし、発生した詳細が不明なままでは、再発を防止できず、次なる攻撃を待ち、再び停止する「whack-a-mole」のような無限ループに陥る可能性があります。
設定ミスを修正する
調査により、攻撃が可能になった原因を明らかにする必要があります。攻撃元を特定したら、再発防止のためのセキュリティ対策を講じてください。ホスト、コンテナ、またはアプリケーションが侵害される原因は、過剰な権限、公開されているポートやサービス、悪用された脆弱性などの設定ミスである可能性があります。
前者の場合、誤った設定を修正して再発を防止してください。後者の場合、ファイアウォールの設定変更、より制限の厳しいユーザーの使用、ファイルやディレクトリへの追加の権限やACLによる保護など、設定の変更により脆弱性の悪用を防止(またはその範囲を限定)できる可能性があります。
この問題が、お客様の環境内の他の資産にも当てはまる場合は、それらすべてに修正を適用してください。リモートネットワーク接続を介してエクスプロイトが実行できる場合、インターネットからアクセス可能なアプリケーションなど、露出している資産では、この対応が特に重要です。
脆弱性にパッチを適用する
可能であれば、脆弱性自体を修正します。
- オペレーティングシステムパッケージ(dpkg、rpm など)の場合:まず、ディストリビューションベンダーが、修正を含むパッケージのアップデート版を提供しているかどうかを確認します。パッケージまたはコンテナベースイメージをアップデートしてください。
- 古いディストリビューションバージョン:ベンダーは、アップデート版およびセキュリティ修正の提供を停止します。手遅れになる前に、サポートされているバージョンを使用しているホストおよびイメージを維持してください。
- NodeJS、Go、Java などの言語パッケージの場合:関連コンポーネントの更新バージョンを確認してください。大規模なバージョンアップデートで発生する可能性のある重大な変更の計画やテストに追加の時間を割くことができない場合は、セキュリティの問題だけを修正したマイナーアップデートやパッチバージョンを探してください。ただし、古いバージョンは永久にメンテナンスされるわけではないため、事前に計画を立てておく必要があります。
- ディストリビューションがパッチ適用バージョンを提供していない場合や、メンテナンスされていないパッケージの修正がない場合: 修正が存在し、手動で適用またはバックポートできる可能性があります。これには追加作業が必要ですが、システムにとって重要なパッケージで、公式の修正バージョンがまだ存在しない場合などに必要になる場合があります。NVD、ベンダーのフィードやソース、バグ報告の公開情報など、脆弱性データベースのリンクを確認してください。修正が利用可能な場合、それを特定できるはずです。
影響を受けるパッケージに適用可能な修正プログラムがない場合でも、設定や保護措置(例:ファイアウォール、隔離など)により、脆弱性の悪用を防ぐことが可能な場合があります。また、複雑で脆弱性に関する深い知識が必要になる可能性がありますが、ご自身のコードに追加のチェックを追加することも可能です。例えば、ウェブAPIサーバーで使用されているJSON処理ライブラリのオーバーフローによる脆弱性は、HTTPリクエストレベルでチェックを追加し、オーバーフローを引き起こす可能性のある文字列を含むリクエストをブロックすることで防止できます。
ループを閉じる
残念ながら、ホストとコンテナのセキュリティは、セキュリティコンテナのベストプラクティスを一度適用すれば、それ以上何もする必要がないという一方向的なものではありません。ソフトウェアとインフラストラクチャは日々進化しており、複雑さが増し、新たなエラーが発生します。これにより、脆弱性や設定の問題が発生します。また、新たな攻撃やエクスプロイトが絶えず発見されています。
まず、予防とセキュリティのベストプラクティスを取り入れることから始めます。次に、主にホストやワークロード、そしてクラウドサービスにも保護対策を施します。異常な振る舞いを監視・検知し続け、発見されたインシデントに対して対応、調査、報告を行います。フォレンジック証拠によってループを閉じます。発見された脆弱性を修正し、保護を強化して、イメージの再構築、パッケージの更新、リソースの再設定を行い、将来のセキュリティインシデントに備えたインシデントレポートを作成します。
その過程で、リスクを評価し、脆弱性を管理する必要があります。複雑で大規模な環境では、管理すべき入力の数が膨大になる可能性があるため、分類して優先付けを行い、最もリスクの高いものから優先的に対応してください。

結論
コンテナセキュリティのベストプラクティスを DevOps ワークフローに簡単に適用する方法について確認しました。特に、次の点を覚えておいてください。
- セキュリティをシフト・レフトし、まず予防から始めましょう。
- すべての資産を保護しましょう。
- 組織内で発生するすべてのことを把握し、問題をできるだけ早く監視および検出しましょう。
- 攻撃は避けられないため、インシデント対応計画を立てましょう。
コンテナセキュリティのベストプラクティスには、提供されたアプリケーションやコンテナイメージ自体だけが含まれるわけではないことを覚えておいてください。コンテナの構築、配布、および具体的な実行に使用されるコンポーネントスタック全体も対象に含める必要があります。
70% のコンテナは 5 分以内で終了するため、異常な振る舞いや侵害の調査が非常に困難です。
クラウドネイティブセキュリティの重要なポイントの 1 つは、コンテナのセキュリティリスクにできるだけ早く対処することです。開発の後段階で対処するとopment life cycle slows down the pace of cloud adoption, while raising security and compliance risks.
クラウドとコンテナを保護する ための5つのセキュリティベストプラクティス
イノベーションのスピードに対応しながら、コンテナの安全を確保してください。