コンテナセキュリティとは?

SHARE:

コンテナセキュリティとは、コンテナのライフサイクルのすべての段階において、マルウェアやデータ漏洩、その他の脅威からコンテナを保護するプロセスです。コンテナイメージを構築した時点から、それをレジストリにロードし、本番環境で展開するまで、潜在的な脅威からコンテナを確実に保護するためのツールやプロセスを実装する必要があります。

この記事では、コンテナのライフサイクル全体にわたるコンテナセキュリティの管理について、知っておくべきことをすべて説明します。

コンテナセキュリティ

ここで学ぶ内容

  • コンテナセキュリティの一般的な脅威

  • コンテナのライフサイクル全体にわたるセキュリティ管理

  • 継続的なコンテナセキュリティ

コンテナセキュリティの一般的な脅威

コンテナセキュリティを理解するには、コンテナに影響を与えるセキュリティの脅威を理解することから始めます。

これらの脅威は多種多様であり、すべてをここで説明することはできません。しかし、コンテナセキュリティの脅威として最も一般的なものは、以下の通りです。

コンテナマルウェア

マルウェアとは、コンテナ内に展開される悪意のあるコードです。コンテナのライフサイクルの複数の段階で、コンテナに侵入することが可能です。CI/CD環境を侵害した攻撃者は、例えば、コンテナイメージの構築に使用されるソースコードリポジトリにマルウェアを仕込むことができます。あるいは、攻撃者はコンテナレジストリを侵害し、マルウェアを含む汚染されたイメージに置き換えることも可能です。コンテナマルウェア攻撃の3つ目のタイプは、ユーザーを騙して外部ソースから悪意のあるコンテナイメージをダウンロードさせるというものです。

いずれの場合も、コンテナが起動する前に検出されないマルウェアがランタイム環境に入り込み、アプリケーションから機密データを収集したり、他のコンテナを妨害したりするなど、さまざまなセキュリティ上の問題を引き起こす可能性があります。

不適切なコンテナ権限

通常、コンテナは特権のないモードで実行すべきであり、これは、コンテナが直接制御するコンテナ化された環境の外にあるリソースにはアクセスできないことを意味します。コンテナ間の通信も、コンテナ同士が通信する必要がある理由がない限り(例えば、アプリケーションコンテナからログを収集するサイドカーコンテナを実行している場合など)は制限すべきです。

コンテナが厳密に必要な以上の特権で実行されると、セキュリティリスクが生じます。特権の不適切な付与は、コンテナオーケストレーターの設定に問題がある場合に発生することが多いです。例えば、Kubernetesでオーケストレーションされたコンテナは、Kubernetesのセキュリティコンテキストとネットワークポリシーが適切に定義されていない場合、必要以上の特権が付与される可能性があります。

機密データを含むコンテナ

コンテナはデータを保存するために使用されることを想定していません。しかし、時には重要な情報をコンテナイメージ内に保存するというミスを犯す組織も存在します。例えば、Vineが非公開だと思っていたコンテナレジストリが実際には一般公開されており、ソースコードを含むイメージがホストされていたことが判明したことで、Vineのソースコード全体が公開されてしまいました。(公平を期すために言っておくと、これはコンテナの黎明期に起こったことであり、コンテナイメージの管理に関するベストプラクティスがまだ十分に確立されていなかった時期のことです。このようなミスが起こったとしても不思議ではありません。)

コンテナのライフサイクル全体にわたるセキュリティ管理

このようなリスクを回避するためには、企業はコンテナのライフサイクルのすべての段階でコンテナを保護するセキュリティ対策を導入する必要があります。以下では、各段階の概要と、各段階でチームが管理しなければならない脅威の種類について説明します。

開発パイプライン

コンテナのライフサイクルは開発パイプラインから始まり、コンテナに組み込まれるコードはここで作成されます。

前述の通り、開発ツールを侵害した攻撃者はソースリポジトリに悪意のあるコードを挿入することができ、いわゆるソフトウェアサプライチェーン攻撃につながります。開発者がイメージの構築に使用する前に悪意のあるコードを検知できなければ、そのコードはパイプラインを通じて本番環境にまで流れ込む可能性があります。

開発ツールへのアクセス制御を実施し、最小権限の原則を徹底することで、このリスクを防ぐことができます。また、ビルドや出荷の前にソースコードをスキャンしてマルウェアを検出することも有効です。

コンテナイメージ

コンテナイメージは、コンテナを実行するために必要なコードを含むファイルです。イメージはコンテナそのものではなく、実行中のコンテナのベースとなる青写真です。したがって、コンテナイメージの内容にマルウェアや機密データが含まれている場合、そのイメージから作成されたコンテナは安全ではありません。

前述の通り、マルウェアがコンテナイメージに侵入しないようにするためには、社内のソースコードをスキャンする必要があります。

しかし、コンテナイメージにはサードパーティのソースからインポートされたリソースが含まれることが多いため、自社のコードをスキャンするだけでは不十分です。コンテナスキャナーを使用してコンテナイメージ全体をスキャンし、イメージの内容を評価して、安全でないことが分かっているコンポーネントをすべて特定する必要があります。イメージのスキャンでは、すべてのタイプの脅威を検知することはできません(特に、脆弱性データベースにまだ記録されていないカスタムマルウェアは検知できない可能性があります)。しかし、既知の脅威の大半を警告してくれます。

コンテナレジストリ

コンテナイメージが作成された後、通常はコンテナレジストリに保存され、そこからユーザーがダウンロードします。

レジストリのセキュリティを確保するために、いくつかのベストプラクティスに従う必要があります。まず、アクセス制御を適用して、承認されたユーザーのみがレジストリ内のイメージにアクセスできるようにする必要があります。これにより、イメージにプライベートなアプリケーションやデータが含まれている場合に発生する可能性がある、偶発的なデータ漏洩を防止できます。

次に、どのイメージが登録されているかを確認するために、レジストリを定期的に監査します。攻撃対象領域を最小限に抑えるために、アプリケーションの旧バージョンを含む時代遅れのイメージは削除すべきです。

最後に、サードパーティのレジストリからコンテナイメージを使用する際には、ソースを信頼できることを確認してください。最も人気の高いパブリックコンテナレジストリであるDocker Hubのイメージの半分は、少なくとも1つのセキュリティ脆弱性を抱えています。また、攻撃者が意図的に、無防備なユーザーを誘い込むような名前(mysqlimageやnginxappなど)の悪意のあるイメージをアップロードすることもあります。非公式のパブリックレジストリからイメージをダウンロードすることは避け、作成元の組織にどれほど信頼を寄せていても、すべてのイメージを必ずスキャンしてください。

コンテナのランタイム環境

コンテナのライフサイクルの最終段階は、実行時です。これは、レジストリからダウンロードしたコンテナイメージを使用して、コンテナを本番環境にデプロイする段階です。

コンテナセキュリティの最も複雑な側面の1つが、ランタイムセキュリティです。これは、使用するコンテナアプリケーションスタックの種類によって異なる複数の可動部分が関与するためです。しかし、ほとんどの場合、実行時のセキュリティは、以下のセキュリティ対策に基づいています。

  • コンテナランタイム:これは、実際にコンテナを実行するサーバー上のプロセスです。ランタイムソフトウェアが最新の状態であり、既知のセキュリティ脆弱性に対するパッチが適用されていることを確認する必要があります。
  • オーケストレーター:コンテナオーケストレーターはコンテナをデプロイし、管理します。 ほとんどのオーケストレーターは、コンテナの権限を制限し、セキュリティリスクを最小限に抑えるためのさまざまなツールを提供していますが、サードパーティの監視および分析ツールを使用して、オーケストレーターレベルでのセキュリティ問題を検出することも必要です。
  • ノード:Kubernetesノードは、コンテナをホストするサーバーです。ノードレベルでの侵害が攻撃者にコンテナ環境への影響を許さないようにするためには、ノードのオペレーティングシステム、ユーザーアカウント、ネットワーク構成、その他のリソースを保護する必要があります。

継続的なコンテナセキュリティ

コンテナのライフサイクルは、循環する連続的なプロセスです。 特定のアプリケーションのコンテナが実行環境にデプロイされた後、アプリケーションが更新されるとサイクルが新たに開始され、新しいコンテナセットがパイプラインにプッシュされます。 それぞれの新しいコンテナには、新しいリスクが含まれている可能性があります。

したがって、コンテナのセキュリティは一度設定すればそれで終わりというものではありません。コンテナのライフサイクル全体にわたって継続的にリスクを監視する必要があります。また、監視ツール、脆弱性データベース、構成を更新し、環境が進化する中でコンテナのセキュリティに関するベストプラクティスを継続的に遵守できるようにする必要があります。