コンテナセキュリティの始め方 - Buildフェーズのセキュリティ (後編)&Shipフェーズのセキュリティ

はじめに

コンテナのライフサイクル"Build - Ship - Run"の、Buildフェーズのセキュリティについて、
前編】
ではセキュリティアプローチの重要性、セキュリティ脆弱性とアタックサーフェスの関係性を解説しました。

今回【後編】では、コンプライアンス視点でのセキュリティ脆弱性の解説と対応策について触れると共に、
コンテナ運用の中で併用されやすいCIプロセスにセキュリティ対策を組み込む実例を解説します。

また、後半からはShipフェーズについても、解説します。

3行でわかる本記事のサマリ

  • コンテナイメージのセキュリティ脆弱性を考慮し、セキュリティスタンダードに準拠しているかどうか監査する必要性がある。
  • コンテナの実行ユーザーを指定しない場合rootユーザーでの実行となり、セキュリティリスクとなる可能性が高まる。
  • CIプロセスにセキュリティスキャナーを組み込むことで、コンテナイメージのセキュリティスキャンを効率的に実行できる。

目次

●Buildフェーズのセキュリティ (後編)
 ・コンテナイメージとセキュリティコンプライアンス
 ・CIプロセスへのセキュリティ実装
●Shipフェーズのセキュリティ
 ・プライベートレジストリの活用
 ・セキュリティ脆弱性の継続監視
 ・DCTの活用
まとめ

Buildフェーズのセキュリティ (後編)

7b539b9c1f99b7eafcacd46417d3bc5825529b92.png

コンテナイメージとセキュリティコンプライアンス

コンテナイメージのセキュリティ脆弱性を考えた場合、アプリケーションを稼働させるためのパッケージやライブラリ等の構成要素だけでなく、
設定ファイルで定義されている設定内容や環境変数、シークレットの実装方法、また、利用されている暗号化技術が適切であるか等を網羅的に監査する必要性についても目を向けなくてはなりません。

これらは、"Posture Management"と呼ばれ、パブリックに公開されている様々なセキュリティスタンダードを評価基準とし、
それらに準拠したコンテナイメージであるかどうかを監査する方法が一般的です。

セキュリティスタンダードには様々な種類が存在し、従来から用いられてきたGDPR, PCI, HIPAA, SOCに加えて、
コンテナセキュリティに特化したNIST SP 800-190, CIS Docker Benchmarks等も選択肢として、自社の運用ポリシーに適合するものを選択することができます。

セキュリティスタンダードに準拠しないコンテナイメージを使用してコンテナを稼働させた場合、
問題箇所がアタックサーフェスとなる可能性があり、攻撃の起点を創り出す恐れがあります。
だからこそ、コンテナイメージに対するセキュリティコンプライアンスを徹底した運用が求められます。

下記の例は、Palo Alto Networks社が提供するPrisma Cloudが実装するコンテナイメージスキャナーを活用し、
コンテナビルドにより生成されたコンテナイメージに対してセキュリティスキャンを実行した結果です。

  • 例1. コンテナの実行ユーザーを指定しないコンテナイメージビルド

Dockerfile コンテナセキュリティの始め方後編2.png

スキャン結果
コンテナセキュリティの始め方後編3.png

この例では、セキュリティスキャンの結果から、CIS Docker v1.3.1 - 4.1に定義されているコンテナの実行ユーザーのセキュリティ脆弱性が指摘されたことが確認できます。

上記のDockerfileの中でUSERを指定していないため、生成されるコンテナイメージからコンテナを実行した場合、コンテナの実行ユーザーはrootユーザーが指定されます。
rootユーザーでコンテナを実行した場合、大きなセキュリティリスクを抱えた状態でコンテナを運用することになります。

具体的には、攻撃者によりコンテナが侵害された場合、コンテナ内部でroot権限を使用した活動を許してしまうことになり、
コンテナを跨いだ被害の拡大や、コンテナホストにまで攻撃が及ぶ危険性が高まります。

下記は上記のDockerfileから生成されたコンテナイメージを使用し、実行したコンテナ内部のプロセス一覧の出力結果です。
rootユーザーでプロセスが実行されていることが確認できます。
コンテナセキュリティの始め方後編4.png

  • 例2. コンテナの実行ユーザーにnon-rootユーザーを指定するコンテナイメージビルド

Dockerfile
コンテナセキュリティの始め方後編5.pngスキャン結果
コンテナセキュリティの始め方後編6.png

この例では、セキュリティスキャンの結果から、コンプライアンスに関する脆弱性が存在しない状態を確認できます。
上記のDockerfileの中でコンテナの実行ユーザーとしてnon-rootユーザーであるnobodyを指定しているため、
コンテナ内部の全てのプロセスはnobodyユーザーを使用して実行されます。
この状態で稼働しているコンテナが侵害された場合でも、non-rootユーザーで実行できる活動は限定的であるため、被害を最小化することができます。

実例として、上記のDockerfileから生成されたコンテナイメージを使用し、実行したコンテナに対して、
例1でコンテナ内部のプロセス確認に使用したpsコマンドの実行例を下記です。

psコマンドの実行にはroot権限が必要であるため、non-rootユーザーの権限では実行できないことが確認できます。
同様に、コンテナのセキュリティ脆弱性を狙った攻撃の振る舞いの大部分がroot権限を必要とするオペレーションをトリガーとして利用するため、
rootユーザー権限を活用できないこの状態では攻撃が失敗に終わる結果が期待できます。

コンテナセキュリティの始め方後編7.pngコンテナ内部の実行ユーザーを確認する代替手段として、下記のコマンドを用います。

コンテナセキュリティの始め方後編7_2.png

この結果から、コンテナ内部の実行ユーザーのUIDが65534であることが確認できます。
実行ユーザーがrootの場合はUIDは0と表示されます。

CIプロセスへのセキュリティ実装

ここまでBuildフェーズにおけるセキュリティ脆弱性の検知と対処について解説してきました。
しかし、実際のコンテナ運用サイクルの中でセキュリティスキャンを手作業で繰り返し実行することは現実的ではありません。

特にコンテナ運用では、コンテナが持つ特性を利用し、比較的短い周期でコンテナイメージのアップデートが実行されることが少なくないため、セキュリティスキャンの実行頻度も上がります。
このような課題に対しては、コンテナイメージの生成に用いられるCIプロセスにセキュリティスキャナーを組み込むことが有効です。

具体的な方法は、CIプロセスでのコンテナイメージビルドの直後に、生成されたコンテナイメージに対してセキュリティスキャナーによるイメージスキャンを実行し、
あらかじめ定めた脆弱性の閾値に基づいたセキュリティ監査を行います。

コンテナセキュリティの始め方後編8.png上記のように、自動化されたCIプロセス内部にセキュリティスキャナーを実装することで、コンテナイメージに対するイメージスキャンを効率的に実行できます。
導入を検討する際は、使用しているCIツールと実装するセキュリティスキャナーの親和性を確認する必要があります。

コンテナセキュリティの始め方 - Shipフェーズのセキュリティ

00480f1b4b8b2235049cebbb27065dbb5830929c.png

コンテナ運用のライフサイクルの中で、コンテナイメージの生成を実行するBuildフェーズに続き、
生成されたコンテナイメージを共有利用するための仕組みを提供するフェーズがShipフェーズです。

コンテナイメージを共有利用するという考え方は、コンテナテクノロジーの特徴の一つであるポータビリティに該当します。
ビジネスにおけるコンテナテクノロジーの活用シーンに対しても、大きな効果をもたらします。
本章では、Shipフェーズがもたらすコンテナ運用に対する利点を最大限活かしながら
セキュアな運用を実現するためのセキュリティ実装方法を紹介します。

プライベートレジストリの活用

Shipフェーズでのセキュリティを考える場合に、最も基本的かつ重要な観点は、コンテナイメージの秘匿性を考慮するか否かです。

コンテナイメージの共有方法は、不特定多数のユーザーが利用できるパブリックレジストリ内でパブリックレポジトリを利用するパターン、
許可されたユーザーのみがアクセス可能なプライベートレジストリを利用するパターン、
パブリックレジストリ内でプライベートレポジトリを利用するパターンなど、多岐に渡ります。

どういったパターンでイメージを共有するべきかは、対象のコンテナイメージの利用用途を基に判断します。
ビジネスロジックの中でコンテナを運用する場合は、コンテナイメージに対して不特定多数のユーザーがアクセスできる必要はないケースがほとんどで、
コンテナイメージ内に機密性の高い情報が含まれる可能性も少なくありません。
このようなケースでは、プライベートレジストリを独自に構築し、セキュアに運用する運用スタイルが推奨されます

自社で開発したアプリケーションをOSSとしてパブリックに提供するような場合には、パブリックレジストリの利用を選択することになります。

プライベートレジストリの運用には相応の運用スキルが求められるため、セキュアな運用が求められる場合にも、
その秘匿性レベルに応じてパブリックレジストリ内でプライベートレポジトリを利用する選択肢も候補に挙がります。

コンテナセキュリティの始め方後編10.png

コンテナセキュリティの始め方後編11.png

セキュリティ脆弱性の継続監視

Buildフェーズで十分なセキュリティ脆弱性チェックを実行したコンテナイメージに対して、Shipフェーズでも継続したセキュリティ脆弱性の監視が必要です。
下記の例では、イメージレジストリにコンテナイメージを格納した直後のセキュリティスキャン結果と
同一のイメージに対して4日後にセキュリティスキャンを実行した結果を記載しています。
時間の経過と共にセキュリティ脆弱性が増加することが確認できます。

イメージレジストリへの格納直後のスキャン結果
コンテナセキュリティの始め方後編12.png

4日後のスキャン結果
コンテナセキュリティの始め方後編13.png

従来からのコンピューティング手法と同様に、コンテナイメージの構成要素に対しても日々新しいセキュリティ脆弱性が発生します。

イメージレジストリに格納されてから長い時間が経過したコンテナイメージを使用し続けることは、大きなセキュリティリスクを伴うため、
継続的なセキュリティ監視を実行し、適切に対処できることが必要です。
イメージレジストリに格納されているコンテナイメージに対するセキュリティスキャンの結果が、
自社の運用ポリシーで定められているセキュリティ基準に違反する場合には、
対象のコンテナイメージの利用を中止し、Buildフェーズでのセキュリティ対策の適用とコンテナイメージの再生成を実行します。

こうした運用を継続的に実施することで、Shipフェーズのコンテナイメージをセキュアに保つことができます。

なお、パブリックに提供されているイメージレジストリやクラウド事業者が提供するイメージレジストリでも、
コンテナイメージに対するセキュリティスキャン機能が提供されるケースが増えていますが、有料であることがほとんどです。

DCTの活用

イメージレジストリを利用してコンテナイメージを共有利用する場合に、個々のコンテナイメージに対して署名を施すことにより、信頼性を証明する手法を活用することができます。
最も有名なイメージレジストリの1つであるDockerHubでは、DCT (Docker Content Trust)という名称で機能提供されていますが、様々なイメージレジストリで同様の機能が利用できます。
DCTはCNCFプロジェクトであるNotaryに準拠した機能実装であり、下記のようにコンテナイメージを提供する立場と利用する立場の双方にセキュリティ利点を提供します。

  • コンテナイメージを提供する立場

  生成したコンテナイメージをイメージレジストリに格納する際に、秘密鍵を用いてコンテナイメージに署名する
   ⇒ 秘密鍵を保持している正規のユーザーのみがコンテナイメージをイメージレジストリに格納できる

  • コンテナイメージを利用する立場

  コンテナイメージ提供者が発行する公開鍵を用いて、コンテナイメージの署名を検証する
   ⇒ 対象のイメージが改ざんされておらず、正規の提供者によって作成されたものであることを確認できる

上記のようにDCTを活用することで、Shipフェーズでよりセキュアなコンテナ運用が可能になります。
DCTを利用する場合、機能の有効化や鍵の受け渡しなど若干の手間は発生しますが、十分な導入効果が期待できると言えます。

まとめ

Buildフェーズで実行するセキュリティ脆弱性対策の中で、コンプライアンス準拠を徹底するアプローチは、
コンテナ運用のセキュリティレベルを強化するために欠かせない重要な要素です。
セキュリティスタンダードを評価基準としたPosture Managementにより、アタックサーフェスを極小化し、堅牢なコンテナ運用を実現します。

無償で利用できるソリューションは限られていますが、OSSとして提供されているDocker Bench for SecurityやDockleを活用することで比較的容易にコンプライアンスチェックが実装できます。
より充実した機能を求める場合には有償ツールの導入を検討してみると良いでしょう。

また、Dockerfileの書式がベストプラクティスに準拠しているかを診断するためのツールであるhadolintを使用することも、よりセキュアなDockerfileを書くために効果的です。

さらに、Buildフェーズで実行するセキュリティ脆弱性対策をより効率的に実装するために、CIプロセスにセキュリティスキャナーを組み込むアプローチが効果的です。
コンテナテクノロジーが本来持っている利点を活かしながら、確実なセキュリティ対策を実現します。

Shipフェーズでは、コンテナイメージをよりセキュアに共有利用する方法を、自社のコンテナ運用特性に合わせて適切に選択する必要があります。
プライベートレジストリとパブリックレジストリのどちらを使用するかに始まり、その中でレポジトリに関してもプライベートかパブリックかを選択することで最適解を導き出します。

また、イメージレジストリにコンテナイメージを格納した後も、継続的にセキュリティ脆弱性の監視を実行する必要があります。
時間の経過と共に発生するセキュリティ脆弱性を可能な限り早期に把握し、適切な対処を施すことでセキュアなコンテナイメージを維持します。
オプションとして、イメージレジストリにコンテナイメージを格納する場合とイメージレジストリからコンテナイメージを取得する場合に、
DockerHubにおけるDCTのような署名技術を活用することで、よりセキュアなコンテナ運用が可能になります。
自社の運用ポリシーに応じて実装を検討してみると良いでしょう。

次回は、"Build - Ship - Run"の最後のフェーズであるRunフェーズのセキュリティについて解説します。

シリーズ記事のご紹介 【コンテナセキュリティの始め方】

d25532088d528fee276e93b126c39fdc47a35a09.png

関連資料のご紹介

『コンテナ環境をプラットフォームまるごと保護!今話題のCNAPPとは?』
コンテナセキュリティのベストプラクティスにあわせ、それらをホストするクラウドのセキュリティを、
ガートナー社が提唱する「CNAPP」の観点を用いてデモを交えて解説します。
動画の視聴はこちら.jpg

『後悔しないクラウドセキュリティ選び「6つの視点」~クラウド環境のセキュリティ、どんな論点で考えるべき!?~』
ホワイトペーパーのダウンロードはこちら3.JPG

メルマガ登録バナー(セキュリティ).jpg

ランキング