コンテナイメージの脆弱性のリスクと対策についてNIST SP 800-190に沿って考える

08 Jul 2020, 21:10 By mosuke5

少なくとも年内まで在宅勤務が確定しいるもーすけです。
さすがに、出社方法などすべて忘れました(笑)

はい、本日はコンテナイメージのセキュリティに関する考え方について書きます。
新しくコンテナ環境を導入してみたいけど、セキュリティに対してどう考えたらいいかわからないといった声や、 実際にKubernetes使い始めたけど本当にこれで安全なの?といった不安の声が聞こえてきているのでまとめてみました。

コンテナ環境におけるセキュリティのレイヤー

今回のブログではコンテナイメージに関するセキュリティについて扱いますが、 コンテナ環境という意味ではもっと多岐にわたるセキュリティの問題について考えなければなりません。

  • イメージのセキュリティ(←本日のテーマ)
  • レジストリのセキュリティ
  • Kunernetesクラスタのセキュリティ(オーケストレーションツール)
  • コンテナランタイムのセキュリティ
  • ホストOSのセキュリティ

これらを包括的に学びたい方は、後述するNISTの全体的に目を通したり、以下の書籍を購入して学ぶことをおすすめします。 ちなみにこの書籍は、わたしが知る限り日本語でコンテナセキュリティについて一番良く書かれているものです。

指針となるもの

コンテナイメージのセキュリティについて考えるとき、なにか指針となるものはないのだろうか?と考える人もいるかもしれません。 もちろん書籍もその1つかと思いますが、社内で説明する際などにもう少しお硬めの?情報源が必要なこともあるのかなと想像します。 英語ではありますが、NIST(米国立標準技術研究所)がだしている NIST SP 800-190 Application Container Security Guideというガイドが非常に役に立ちます。

このガイドラインでは、コンテナセキュリティに関するリスクのポイントと対策についてまとめられています。 対象のスコープは上で示したようにコンテナイメージのみならず包括的な内容となっています。 ただし、こちらのガイドには対策の考え方は書いてありますが、具体的な方法や実装が書かれているわけではありません。 その点については、セキュリティベンダーの製品情報や書籍などを組み合わせていくとよいです。

また、SysdigやAquaといった、コンテナセキュリティの製品をだしているベンダーでは、このNIST SP800-190のガイドにどれだけ適応しているかのチェックリストなどを公開していることも多いです。このガイドを標準に考えていると、製品選定の際にも役に立つことでしょう。 たとえばAquaではこちらからチェックリストをダウンロードすることが実際に可能です。

コンテナイメージのセキュリティに

さて、それではここからは、NIST SP 800-190の項目に沿って、コンテナイメージのセキュリティについて考えてみたいと思います。

イメージの脆弱性 (Image vulnerabilities)

リスク

コンテナイメージは、一度作成すると変わることのないアーカイブファイルとして捉えることもできます。それゆえに、作った時点では最新の状態でも、ときが経つと中で利用されているコンポーネントに脆弱性が発見されることがあり、安全ではなくなります。 従来のサーバ上で直接動作させていたアプリケーションも同様といえば同様ですが、ホスト側をアップデートすることでアプリケーションの脆弱性を減らすことも可能でしたが、ホストとは全く別物として対策しなければいけない点が異なります。 こちらはコンテナイメージの良いところでもあり弱点にもなりうる項目です。

対策

コンテナイメージに対する定期的なイメージスキャンが有効的です。
コンテナイメージのビルドをするパイプライン内でのスキャンや定期的なスキャンを検討してみましょう。 よくあるのが、ビルド時にのみスキャンをするといったケースです。 ビルド時にスキャンすることは当然重要なのですが、作りたてよりも長い間動かしている間に脆弱性がでることのほうが多いです。 頻繁にビルドを繰り返している環境かどうかによっても選択は変わると考えますが、動作しているコンテナイメージに対する定期的なスキャンも必要なことが多いです。

一般的にイメージスキャンはClairやTrivyといったソフトウェアで実施が可能なのですが、これらのツールはRPMパッケージやdebパッケージに対する既知の脆弱性に対するスキャンとなります。パッケージマネージャで管理されていないソフトウェアや独自のアプリケーションに対しては当然ながらスキャンができない点も注意が必要です。

スキャンした結果にも注意が必要です。
Common Vulnerability Scoring System (CVSS) などで指摘される脆弱性は、リスクのランク付けはあるものの、利用方法によってその重大さは変わってきます。 リスクの重要度という指標だけでパイプラインの処理をストップさせるかどうかは改めて組織・チーム内で検討してみてください。最終的にはなんらか人によるジャッジが必要なのではないかと少なくとも現時点では思います。

イメージ設定の欠陥 (Image configuration defects)

リスク

コンテナイメージの作成時に注意すべきこととして、特定のユーザアカウントで実行されるべきではないことや、コンテナ内でSSHデーモンを起動すべきでないといったことが書かれています。 わかり易い例でいうと、rootアカウントでコンテナ内のプロセスを実行しないといったことや、不必要なネットワークのリスクを作らないようにSSHデーモンは起動しないでおくと言ったことです。

対策

root権限でコンテナ内のプロセスを起動しないようにまずは努めましょう。 KubernetesのPod Security Policiesでrootでの実行を制限してしまうことなども考えられます。 また、SSHデーモンを起動しないといった観点では、1コンテナ1プロセス(1サービス)の原則に立ち返ることが重要かと思います。 Kubernetesでは、メインのプロセスが落ちた際にはPodの終了を意味し、オートヒーリング機能でPodの再起動を試みますが、コンテナ内のメインプロセス以外のプロセスについては監視対象ではないです。停止しても自動で再起動されることはないため、複数プロセスを起動することを前提にすること自体がコンテナのメリットを活かしきれない状態ともいえます。

マルウェア (Embedded malware)

リスク

コンテナイメージはソフトウェアパッケージの集合体なので、当然ながらマルウエアをイメージ内に含めてしまう可能性があります。イメージ内や他のコンテナ、ホストを攻撃する可能性を持っています。マルウエアはイメージを作成するベースイメージに含まれる可能性もありえます。

対策

コンテナ内のマルウエアの検出には、Aquaなどの商用製品をご利用いただくのが一番と個人的に考えます。 また、コンテナ内のプロセスをroot権限で動かさないことで、起動後にマルウエアを起動されるリスクを減らすことや、その影響範囲を狭めることが可能です。 製品の利用にはコストもかかるはなしなので、まずはroot権限で動かさないなどの対策から実施することが効率的かもしれません。

平文のシークレット (Embedded clear text secrets)

リスク

多くのアプリケーションは、データベースの接続や他のシステムにアクセスするためのSSHの鍵やX.509の証明書を利用します。これらをコンテナイメージ内に直接に保管することができてしまいますが、それはセキュリティリスクになるということです。

対策

一番基礎的なところでは、シークレット情報はKubernetesのSecretリソースを用いて、コンテナの起動時に環境変数で渡すかファイルとしてマウントする方法をとるということです。この対応は必ず行ってください。

次にコンテナイメージを作るときの注意です。 上のリスクに書いてあるとおり、コンテナイメージ内にシークレットを保存しないことは当然なのですが、コンテナイメージ内に書き込んだシークレットを後から削除しても、事実上消えないというコンテナのレイヤーの仕組みを理解することが重要です。

例えば、以下のようなDockerfileを利用してイメージのビルドした場合、最終的に出来上がるイメージではgit-repo-keyは削除され存在しませんが、イメージのレイヤーとしてgit-repo-keyは残っています。 レイヤー内に残っているファイルは簡単に取り出すことができます。 コンテナイメージのビルドプロセスでのシークレットの扱いも十分に気をつけましょう。

FROM centos:8
ADD ./git-repo-key /tmp
RUN rm /tmp/git-repo-key

もし、ビルドプロセスでシークレットが必要な場合は、例えばDocker環境であれば、BuildKitを有効化して docker build --secret コマンドを使ってビルドするなどがあります。

信頼性のないイメージの利用 (Use of untrusted images)

リスク

もっとも一般的でハイリスクの1つと言われているのが、信頼性のないイメージの実行とのことです。コンテナイメージのポータビリティ性や再利用の簡単さゆえに起きやすい問題ともされています。信頼性のないイメージを使ってしまうことで、結果的にコンテナイメージ内にマルウエアを含んでしまうことや情報漏洩につながってしまうことがあります。

対策

コンテナイメージに限らずですが、パブリックなコンテナイメージを利用する場合には、そのイメージを作っている組織を必ず確認してましょう。 信頼のおける組織が出しているイメージであるかや、そのイメージをビルドするのに使っているDockerfileが公開されているか(必要に応じて中身を確認)などを総合的に見て判断しましょう。
また、仮に信頼のある組織のものだったとしても、コンテナイメージのタグは上書き可能で、安全とおもって利用していたイメージが書き換えられている可能性もあります。 イメージの利用時にタグ名ではなくDigest値を用いることで、タグの上書きされたとしても、同じイメージを使い続けることができます。(当然、Digest値を取得した時点でマルウエアなど仕込まれていたら対策になりません)

# Dockefile
FROM [email protected]:9e0c275e0bcb495773b10a18e499985d782810e47b4fce076422acb4bc3da3dd
RUN xxxxx
...

OpenShift

宣伝というわけではないのですが?、Red Hatが提供しているOpenShiftというKubernetesサービスは、エンタープライズ向けにKubernetesを拡張してプロダクトを開発しています。 コンテナのプロセスをrootで起動させない設定や、コンテナ内のプロセスの実行ユーザをランダム化させる設定、Red Hatとしてテストした信頼性のあるコンテナイメージの提供(Container Catalog)、イメージスキャン機能をもつQuayなど、コンテナ環境をより安全に利用するための仕組みを多数にご用意しています。 ご興味あればみてみてください。

まとめ

というわけで、本日はNIST SP 800-190に沿って、コンテナイメージのセキュリティについて見てきました。 コンテナ環境のセキュリティという観点でいうとごくごく一部であり、非常に奥が深いです。 みなさんのコンテナライフをより安全に送っていたく参考になればと思います。 より詳しい内容は、ぜひNIST SP 800-190をよんで頂き、下記の書籍を手にとっていただくことをおすすめします。

フィードバック・相談(β)

本記事に対して、執筆者にフィードバックや聞きたいことがあればこちらのフォームからご記入ください。執筆者に問い合わせてみる

このエントリーをはてなブックマークに追加
comments powered by Disqus