2021年12月31日金曜日

セキュリティ・ミニキャンプオンライン2021 参加記 ~内容編5:コンテナとその実行基盤を取り巻くセキュリティの基礎と実践~

ミニキャンプオンライン2021「ファイルシステムについて仕組みを知ろう」の募集課題、事前課題、講義、修了試験についての記事です。

他講義リンク

 

コンテナとその実行基盤を取り巻くセキュリティの基礎と実践

コンテナオーケストレーションの基礎と、それのセキュリティ対策についての演習を行った講義でした。

コンテナを利用する際の対策を学んだとともに、本講義で初めてKubernetesを利用し、便利で楽しそうなため自分でも何か使ってみたいなと思いました。

しかし、コンテナオーケストレーションが有効なのはノードがたくさんある場合なので、そんなお金はないからしばらくはないかな~って感じです…誰か俺にスパチャしてくれ

募集課題

コンテナ型仮想化技術やコンテナオーケストレーションツールがシステム構築・運用に与えた影響と、それらの環境において懸念されるセキュリティ上の脅威を一つ取り上げて、その原因や影響、対策等について論じるといった問題です。ミニキャンプオンライン概要ページ(https://www.security-camp.or.jp/minicamp/online2021.html)募集要項の問題5にあたります。

自分はこの課題を提出していませんが、書いていたとしたら

  • コンテナ型仮想化技術の利点として、OSにソフトウェアを直接インストールするより、ソフトウェア間の依存関係を保つことが容易なため、構築が行いやすい。
  • コンテナオーケストレーションツールによって、システム構築後のスケーリングや冗長化が簡単になった
  • 利用するコンテナイメージに悪意のあるコードが含まれている可能性がある。対策としては公式が提供するもののみを利用することがあげられる

らへんをまとめていたと思います。

募集時にはセキュリティ上の脅威はこれとコンテナブレイクアウトくらいしか知りませんでしたが、のちの講義(3章が当たります)を受け、思っていたよりコンテナの扱いには気を遣う必要があるのだなと感じました。

事前課題 

Docker、Kubernetes、Open Policy Agent/Regoについての基礎知識をつけるため、実際にコマンドを打って動作を確認したり、ポリシーを記述したりしました。自分は卒業研究の方でDocker、Docker Composeを利用していたため、DockerとKubernetesは扱いやすかったです。

Rego言語についてですが、ポリシーの記述用なので順次実行とは違った考えが必要なところが少し難しかったです(以下の講義スライド78ページなど)。また、公式ドキュメント(https://www.openpolicyagent.org/docs/latest/)も充実しており、テスト用にPlayground(https://play.openpolicyagent.org/)もあるので、実際に定義を行うときはこれらを利用すればなんとかなりそうだとも思いました。

講義

こちらの講義は資料が上がっているため、是非確認してみてください。

初めにコンテナ型仮想化やコンテナオーケストレーションの基礎を学び、後半ではTrivyを使ってコンテナイメージに含まれる脆弱性を調べてそれへの対応を考えたり、ポリシー定義をしてデプロイ前に防がれるのを確認する実習をしました。今回はTrivyの実習について書こうと思います。

Trivyの実習

講義資料の76ページが該当します。資料の通りコンテナの脆弱性を見つけるだけでなく、「対応方法」を考える必要がありました。以下が自分の書いた内容となっています。

ここで重要だったのが、Trivyで脆弱性を調査すると重大な脆弱性が複数表示されたりしますが、「コンテナの利用法」を考えて対応を考えることです。自分が見つけた脆弱性もそうですが、コンテナをMySQLとしてのみ使えば脅威は低いです。この実習で行った脆弱性の調査でも「サイバー攻撃対応入門」のIDSアラートを調査した際と同じような「経験や慣れ」が必要そうと思いました。

また、脆弱性をなくすにはバージョンを上げる等の対応が考えられますが、開発側の事情で更新が難しいといったこともあります。したがって、いろんな事情を考慮した対応方法を考えることが大事だと学びました。

修了試験

仕様に沿うGateKeeper用のポリシーを記述するという問題でした。仕様が

  • 検査対象のマニフェストはPod
  • Podに含まれるコンテナのイメージの指定においてダイジェスト(SHA-256ハッシュ値)が利用されていない場合にリクエストを拒否
  • ダイジェストに対応するイメージが存在するかは問わないが、SHA-256の書式には則っていなければならない

というものです。

自分はこの問題に取り組む時間がありませんでした…最後には大ヒントが出ていて、「ダイジェストを判定する正規表現を書け」という問題になっていたため、ちょっと後悔が残りました。

まず、正規表現以外のポリシーについて考えると、講義資料83、84ページを参考にすることで


package example
violation[{"msg": msg}] {
  c := input.review.object.spec.containers[_]
  # ここで正規表現を使い判定
  msg := "ダイジェストが利用されていないコンテナイメージがあります"
}
  

と書くことができます。イメージ名は「input.review.object.spec.containers[_].image」で参照できるため、c.imageでイメージ名を調べることができます。

Regoでの正規表現は「re_match」関数で行え、マッチした際にtrueを返すので、SHA-256の書式にマッチする正規表現を書き、NOTを取れば答えとなります。

肝心の正規表現ですが、イメージ名が

  • イメージ名のみ
  • タグ付き(<イメージ名>:<タグ名>)
  • SHA-256ハッシュ値(<イメージ名>@sha256:<ハッシュ値>)

のいずれかを取り、下のみを通すものを作らなければなりません。

イメージ名は1文字以上の任意の文字を取るので、「.+」で表せます。

ハッシュ値は256ビットの値=64桁の16進数で表されるため、[a-f0-9]{64}で表されます。

したがって、これらを組み合わせた

.+@sha256:[a-f0-9]{64}

が答えとなります。ポリシーは


package example
violation[{"msg": msg}] {
  c := input.review.object.spec.containers[_]
  # ここで正規表現を使い判定
  not re_match(".+@sha256:[a-f0-9]{64}", c.image)
  msg := "ダイジェストが利用されていないコンテナイメージがあります"
}
  

となります。

ここまで解いて、大ヒント出てから取り掛かれば間に合ったかもな…と思いました。時間配分等も考えられるようにならないとですね。おしまい。

0 件のコメント:

コメントを投稿