オブジェクトの広場はオージス総研グループのエンジニアによる技術発表サイトです

コンテナ・マイクロサービス

Clair によるコンテナ・イメージの脆弱性検出

第1回 Docker と Clair の概要
オージス総研
樋口 匡俊
2017年1月16日

2013年に Docker が公開されて以来、コンテナ技術は急速な発展を続けています。Docker は、一部の先進的な開発者やスタートアップから火が付き、その後瞬く間に Amazon や Microsoft、Google 等のビッグベンダを巻き込んで、コンテナブームというべき状況を引き起こしています。そのようにコンテナ技術の利用が広がる中で、コンテナ技術を安全に利用するためのセキュリティ技術やサービスの開発も進んできました。本連載では、そうしたコンテナ・セキュリティの一分野であるイメージの脆弱性検出について、脆弱性検出のプラットフォームである Clair を例に解説します。今回解説するのは Clair の概要ですが、その前にまずは予備知識として、Docker イメージの脆弱性とは何かを見ていきましょう。

Docker はコンテナでアプリを動かす

Docker は、コンテナを作成して動かすことができるソフトウェアです。 コンテナは、仮想化技術の一種で、主にアプリケーションを動かすために利用されます。 Docker を使えば、ECサイトのショッピングカートや、ビッグデータの分析処理など、様々なアプリケーションのコンテナを簡単に作成し動かすことができます。

Docker が登場する以前から、コンテナ技術には様々なものが存在しました。 それではなぜ、従来のコンテナ技術ではなく Docker が、現在のコンテナブームというべき状況を引き起こすことができたのでしょうか? 理由の一つとして考えられるのが、イメージの仕組みを導入したことです。

イメージからコンテナが作られる

イメージとは、コンテナを作成し動かすために必要なものをひとまとめにしたものです。 Docker は、イメージからコンテナを作成して動かします。

イメージは、コンテナを作成する前に Dockerfile を用いて予め作成しておきます。 Dockerfile には、イメージとしてひとまとめにしたいアプリケーションやミドルウェア、データファイル等を記述できます。Dockerfile は、いわばイメージの作成手順書です。

作成したイメージは、Docker Hub というインターネット上のサービスで共有できます。 Docker Hub には、世界中の開発者が作成したイメージが共有されています。 共有されているイメージを利用すれば、Dockerfile でイメージを自作する手間が省けます。

例. Tomcat のイメージ

例えば、Docker で Apache Tomcat のコンテナを動かしたいとします。 Tomcat は Java の Webアプリケーションサーバであり、これを動かすためには Tomcat 本体はもちろん、OpenJDK のような Java の実行環境等、様々なものが必要です。

この場合、まずは Dockerfile を用いて Tomcat 本体 や Java の実行環境をひとまとめにしたイメージを作成します。あるいは、Docker Hub から Tomcat 公式イメージ をダウンロードします。

そのように自作あるいはダウンロードした Tomcat のイメージを基にして、Docker は Tomcat のコンテナを作成します。イメージが基になっていますので、コンテナにも Tomcat 本体や Java の実行環境は含まれています。そのため、すぐに Tomcat のコンテナを動かすことができます。

例. Tomcat のイメージ

イメージの利点

イメージの最大の利点は、ポータビリティが高いことです。 イメージは、コンテナでアプリケーションを動かすために必要なものをひとまとめにできるため、ある環境では動いていたコンテナが別の環境では動かないという事態を防ぐことができます。 つまり、一度イメージを作成すれば、異なる環境で同じコンテナを再現し動かせるのです。 このような特徴を、Java の「Write Once, Run Anywhere (WORA)」にならって Package Once, Deploy Anywhere (PODA) と言うことがあります。

PODA であるということは、環境の違いに対応する手間が減り、その分だけ開発・運用のスピードを高めることができるということです。 また、誰かがある環境で作成したイメージを自分の環境でも利用できるということでもあります。 そうした共有・再利用が容易というイメージの特徴に、Docker Hub のようなイメージ共有の仕組みが組み合わされることで、開発・運用のスピードを更に高めることができます。

イメージの脆弱性

脆弱性とは、OSやソフトウェアに含まれるセキュリティ上の欠陥のことです。 OpenSSL の脆弱性 Heartbleed や Bash の脆弱性 ShellShock 等、様々な脆弱性が日々発見・報告されています。

イメージには、OpenSSL や Bash 等、様々なソフトウェアを含めることができます。 このことはイメージの利点ではありますが、その反面、OpenSSL や Bash 等が抱えている脆弱性のリスクをイメージも同様に抱えているということでもあります。 例えば、もしも Heartbleed 対策が施されていない OpenSSL がイメージに含まれている場合、そのイメージから作成したコンテナは Heartbleed を利用した攻撃を受け悪用されてしまうかもしれません。

Heartbleed を含むイメージ

イメージに脆弱性が存在するケース

イメージに脆弱性が存在するのは、例えば下記のようなケースです。

  1. イメージを作成する際、脆弱性が存在するソフトウェアをうっかり含めてしまった。

    Dockerfile は、ソフトウェアに脆弱性が存在していても教えてくれません。 Dockerfile には、イメージに含めるソフトウェアを自由に記述できます。 脆弱性が存在するソフトウェアを Dockerfile に記述すれば、そのソフトウェアがそのままイメージに含まれてしまいます。

  2. Docker Hub から脆弱性が存在するイメージをダウンロードしてしまった。

    Docker Hub で共有されているイメージが安全であるとは限りません。 上記1のケースのように、脆弱性が存在するイメージがうっかり作成され、共有されているかもしれません。 また、悪意ある人が、脆弱性が存在するイメージを共有しているかもしれません。

  3. イメージを作成した後で、新たな脆弱性が発見された。

    昨日安全だったイメージが、今日も安全であるとは限りません。 Heartbleed も ShellShock も、広く普及していた OpenSSL や Bash で発見された脆弱性です。

イメージの脆弱性に対応するには?

こうしたイメージが抱える脆弱性のリスクを軽減するにはどうすればよいでしょうか? 様々な対応方法が考えられますが、下記の2点は基本ともいえるものでしょう。

  1. 脆弱性情報を日々チェックする

    インターネット上には、誰でも参照できる脆弱性情報のデータベースが存在します。 中でも最も有名なのは、米国政府が支援している CVENVD でしょう。 CVE は、Red HatUbuntu などOS毎のデータベースや、JVN のような日本語のデータベース等、80種類以上のデータベースと連携して脆弱性情報を公開しています。 NVD は、CVE で公開されている脆弱性情報の補足として、脆弱性の影響度の評価を行う等しています。 それらのデータベースを日々チェックして、脆弱性に適切に対応するための情報を収集するとよいでしょう。

  2. イメージの構成を把握する

    どのようなパッケージやライブラリがイメージに含まれているか、正しく把握することも必要です。 イメージに含まれているものと上記1の脆弱性情報を結びつけることで、イメージに脆弱性が存在するかどうか、その脆弱性はどのようなものかを知ることができます。 脆弱性が存在することが分かれば、あとはパッチを適用する等の対応を実施することになります。

こうした対応を人手のみで実践することは決して容易ではありません。 何らかのツールや仕組みを導入することを検討すべきでしょう。

Clair はイメージの脆弱性を検出する

Clair は、イメージをスキャンして、既知の脆弱性を検出するためのプラットフォームです。 Clair を利用することで、イメージが抱える脆弱性のリスクを軽減できます。

下記は、Clair がイメージをスキャンした結果の例です。Heartbleed の脆弱性が存在する openssl パッケージが、イメージに含まれていたことを示しています。

    CVE-2014-0160 (Medium)
      The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do
      not properly handle Heartbeat Extension packets, which allows remote attackers
      to obtain sensitive information from process memory via crafted packets that
      trigger a buffer over-read, as demonstrated by reading private keys, related to
      d1_both.c and t1_lib.c, aka the Heartbleed bug.

      Package:       openssl @ 1.0.1e-2
      Fixed version: 1.0.1e-2+deb7u5
      Link:          https://security-tracker.debian.org/tracker/CVE-2014-0160
      Layer:         070631c9df775fc663146eed886c73b8beaf392338664295bf470b365c6ada1d

Clair のユースケース

例えば、Docker を利用している開発チームにおいて、Clair を下記のように利用することができます。

  1. 開発者のローカルマシン内のイメージから手動で脆弱性を検出する。

    Docker を開発に利用していると、様々なイメージが各開発者のローカルマシンにたまっていきます。 各開発者は Clair を用いて、手動でローカルマシン内のイメージをスキャンし脆弱性を検出することができます。

  2. 開発チームのレジストリ内のイメージから自動で脆弱性を検出する。

    レジストリとは、Docker Hub のイメージ共有の仕組みをオープンソース化したものです。 Docker Hub を利用して世界中の開発者とイメージを共有するのではなく、開発チームだけでイメージを共有したい場合等にレジストリを利用します。

    レジストリには、開発チームの誰かが作成したイメージが日々登録・更新されていきます。 Clair を利用すると、レジストリにイメージが登録されたら、そのイメージを自動でスキャンする仕組みを構築できます。 それによって、もし誰かが脆弱性を含むイメージを登録しても、そのイメージが他の開発者に拡散されたり、本番環境にリリースされたりすることを防げます。

情報の取得 + イメージのスキャン = 脆弱性の検出

Clair には大きく2つの機能があります。

  1. 既知の脆弱性情報の取得

    Clair は、Red Hat や Ubuntu、NVD 等、インターネット上の脆弱性情報のデータベースから既知の脆弱性情報を取得します。 取得した情報は、データベース(PostgreSQL)に格納します。

  2. イメージのスキャン

    Clair は、イメージを静的に解析し、どのような OS やパッケージを含んでいるか明らかにします。 スキャンした結果と、上記1で取得した脆弱性情報とを結びつけて、イメージにどのような脆弱性が含まれているか知ることができます。

この 1 と 2 は、先述の「イメージの脆弱性に対応するには?」で挙げた 1 と 2 にそれぞれ対応することが分かるかと思います。

Clair はプラットフォームである

Clair は単なるツールというよりは、イメージの脆弱性を検出するツールやシステムを構築するためのプラットフォームというべき特徴を備えています。

その一つが REST API です。REST API を介してイメージのスキャンを実行したり、スキャン結果を参照する等、Clair に対して様々な操作を行うことができます。

また、Clair は既知の脆弱性情報の取得処理や、イメージのスキャン処理等、様々な処理をコンポーネント化しています。コンポーネントは自作することも可能で、独自のスキャン処理等を追加できます。

こうしたプラットフォームとしての Clair を利用して、HyperclairKlarClair w/ SQS 等のサードパーティ製ツールも開発されています。

Clair 概要図

Clair は ●● しない

あらゆる脅威に対応できる完璧なセキュリティ製品はありません。 Clair もまた対応できる範囲には限りがあります。 ここでは Clair が「しない」ことをいくつか挙げてみます。 (コンポーネントを自作する等した場合はこの限りではありません。)

Clair は、ソフトウェアそのものは解析しない

Clair は ソフトウェアを管理している dpkg や rpm 等のパッケージ管理システムのファイルを解析します。

Clair は、パッケージ管理されていないソフトウェアの脆弱性を検出しない

Clair が脆弱性を検出するのは、dpkg や rpm 等のパッケージ管理システムで管理されているパッケージだけです。 例えば、パッケージ管理システムを使わずに、自力でtarファイルを展開してツールをインストールした場合、そのツールはイメージに含まれていてもスキャンされず、脆弱性も検出されません。

Clair は、未知の脆弱性を検出しない

Clair が検出できるのは、CVE等で公開されている既知の脆弱性のみです。

Clair は、GUIを提供しない

Clair は CLI で起動します。Clair の設定ファイルはテキストエディタ等で編集します。Clair の操作は REST API で行います。それらを実行するための GUI は提供していません。

Clair は、脆弱性を修正しない

Clair は、脆弱性の修正されたバージョンを教えてくれますが、そのバージョンに更新する作業は別途人手で行う必要があります。

Clair のターゲット

このように Clair は、イメージのあらゆる構成要素から、あらゆる種類の脆弱性を漏れなく検出してくれるものではありません。 Clair が検出するのは、イメージの構成要素のうち、パッケージ管理システムで管理されたパッケージに存在する、既知の脆弱性のみです。

果たして Clair だけで、イメージの脆弱性対策として十分といえるのでしょうか? Clair の開発元の CoreOS社によると、深刻な脆弱性の大部分は、単にパッケージを更新することで解決できるのだそうです。 つまり、Clair のスキャン結果に従ってパッケージを更新すれば、それだけで多くの脆弱性が解決できるはずということです。

セキュリティ対策に割ける予算や人、時間は決して潤沢とは言えない場合が多いでしょう。 Clair は、限られたリソースの中で、パッケージにターゲットを絞って効果的なセキュリティ対策を実施することを支援するものと言えるでしょう。

まとめ

今回は、Docker イメージの脆弱性検出のプラットフォームである Clair の概要を解説しました。 予備知識として、Docker イメージの基本についても解説しましたが、更に Docker について知りたい方は、別途連載中の「さわって理解するDocker入門」もご覧ください。

次回は、Clair のコンポーネントについて解説する予定です。