< lcn home

オープンソースツールで Docker イメージスキャンを実装する方法

この記事では、オープンソースのイメージスキャンツールを用いた Docker イメージスキャンについて取り上げます。プライベート Docker リポジトリ上でのセキュリティスキャンのデプロイとセットアップ方法、そして CI/CD パイプラインにおける検証ステップとしての導入方法を説明します。また、Jenkins のような CI/CD ツールや、Falco のようなランタイムセキュリティツールとイメージスキャンを統合する方法についても探っていきます。

これは、オープンソースコンテナセキュリティに関する 2 部構成シリーズの第 2 回です。第 1 回では、Falco を用いて Kubernetes のためのレスポンスエンジンを構築し、FaaS としてセキュリティプレイブックを活用するオープンソースのコンテナランタイムセキュリティに焦点を当てました。

Table of contents
This is the block containing the component that will be injected inside the Rich Text. You can hide this block if you want.

Dockerの脆弱性スキャン

CI(継続的インテグレーション)パイプラインの最後のステップの一つは、環境でプルされ実行されるコンテナイメージのビルドを含みます。したがって、独自のコードから Docker イメージをビルドする場合でも、変更していないサードパーティイメージを使用する場合でも、そのイメージに存在する可能性のある既知の脆弱性を特定し見つけることが重要です。このプロセスは Docker の脆弱性スキャン として知られています。

Docker イメージは複数の不変なレイヤーで構成されており、基本的には前のレイヤーに対する差分としてファイルやその他の変更を追加したもので、各レイヤーには一意のハッシュ ID が関連付けられています。


新しい Docker イメージを作成するとき、それは既存のイメージ(Dockerfile 内の FROM ステートメント)に基づいていることがほとんどです。そのため、このレイヤー構造を活用することで、新しいイメージを作成するたびにイメージ全体を再スキャンする必要を避けることができます。もし親イメージが脆弱であれば、その上に構築される他のイメージも同様に脆弱になります。

The Docker build process follows a manifest (Dockerfile) that includes relevant security information that you can scan and evaluate including the base images, exposed ports, environment variables, entrypoint script, external installed binaries, etc. Btw, don't miss our Docker security best practices をぜひご覧ください。

セキュアなパイプラインでは、Docker 脆弱性スキャンは CI/CD プロセスの必須ステップであるべきであり、どのイメージも本番クラスターで「Running」状態に入る前にスキャンされ、承認される必要があります。

Docker セキュリティスキャンプロセスには通常、以下が含まれます:

  • ソフトウェアパッケージ、バイナリ、ライブラリ、オペレーティングシステムファイルなどを、1 つまたは複数のよく知られた脆弱性データベースと照合すること。 一部の Docker スキャンツールには、一般的な Docker イメージのスキャン結果を含むリポジトリがあり、キャッシュとして利用することで処理を高速化できます。
  • Dockerfile とイメージメタデータの分析:特権(root)ユーザーとしての実行、不正なポートの公開、完全なトレーサビリティを確保するために特定のバージョンではなく「latest」とタグ付けされたベースイメージの使用など、セキュリティ上重要な構成を検出します。
  • ユーザー定義ポリシー:すべてのイメージに対して確認したい要件のセット(例:ソフトウェアパッケージのブラックリスト、ベースイメージのホワイトリスト、SUID ファイルが追加されていないかなど)。

発見されたセキュリティ問題は分類・グループ化し、異なる優先度を割り当てることができます。たとえば、警告通知で十分なものもあります。

[tweetbox design="default" float="none"]Implementing #Docker image scanning with #opensource tools: @anchore and @falcoorg #Kubernetes #CloudNative #security[/tweet_box]

Docker イメージスキャンに使えるオープンソースツール

Docker イメージスキャンツールはいくつか存在しており、最も一般的なものには以下が含まれます:

  • Anchore Engine: Anchore Engine はオープンソースのイメージスキャンツールです。検査、分析のための集中サービスを提供し、ユーザー定義の受け入れポリシーを適用して、コンテナイメージの自動検証と認証を可能にします。
  • CoreOS/Clair: アプリケーションコンテナ内の脆弱性を静的解析するためのオープンソースプロジェクトです(現在は appc/Rkt および Docker を含みます)。
  • Vuls.io: NVD、OVAL などの情報に基づいたエージェントレスの Linux 脆弱性スキャナーです。コンテナイメージの一部サポートがありますが、コンテナ専用ツールではありません。
  • OpenScap: NIST 認証済みの Security Content Automation Protocol(SCAP)に従い、ソフトウェアの構成や既知の脆弱性を調べる自動監査ツールのスイートです。こちらもコンテナ専用ではありませんが、ある程度のサポートを含みます。


オープンソース Docker スキャンツール: Anchore Engine

柔軟なユーザー定義Anchore Engine は現在利用可能なオープンソースツールの中で私たちの第一の選択肢となりました。

  • Anchore Engine を使用すると、開発者はコンテナイメージの詳細な分析を実行し、クエリを実行し、レポートを作成し、CI/CD パイプラインで使用できるポリシーを定義できます。
  • Anchore Engine を使えば、Docker V2 互換のコンテナレジストリからコンテナイメージをダウンロードし、ユーザー定義ポリシーに基づいて分析・評価することが可能です。
  • スキャンには CVE ベースのセキュリティスキャンだけでなく、セキュリティ、コンプライアンス、運用のベストプラクティスに関するチェックを含めたポリシーベースのスキャンも含まれます。

Anchore Engineのソースとエンドポイント

Anchore Engine のアーキテクチャは 6 つのコンポーネントで構成されており、1 つのコンテナにデプロイすることも、スケールアウトすることもできます。

  • API Service: コードから REST API を使用して、またはコマンドラインを直接使ってアクセスできる中央通信インターフェース。
  • Image Analyzer Service: 「worker」によって実行されるコンポーネントで、実際の Docker イメージスキャンを行う Anchore ノード
  • Catalog Service: 内部データベースおよびシステム状態サービス。
  • Queuing Service: エンジンタスクを整理、保持、スケジュールするサービス。
  • Policy Engine Service: ポリシー評価と脆弱性照合ルールを担当。
  • Kubernetes Webhook Service: Kubernetes 固有の Webhook サービスで、イメージが生成される前に検証を行う。

Anchore Engine アーキテクチャ


Docker イメージスキャンのための Anchore Engine のデプロイ

docker-compose を使用して Anchore をインストールする方法

Anchore Engine を試すための最も手っ取り早い方法のひとつは、docker-compose スタックを使ってローカルに素早くデプロイすることです。

mkdir anchore
cd anchore
curl https://raw.githubusercontent.com/anchore/anchore-engine/master/scripts/docker-compose/docker-compose.yaml > docker-compose.yaml
mkdir config
curl https://raw.githubusercontent.com/anchore/anchore-engine/master/scripts/docker-compose/config.yaml > config/config.yaml
mkdir db
docker-compose up -d

この config.yaml ファイルでは、ログレベル、リスニングポート、認証情報、Webhook 通知など、いくつかのパラメータを調整できます。

CLI クライアントも Docker コンテナとして提供されており、DockerHub から直接プルすることができます。

docker pull anchore/engine-cli:latest

次に、すべての Anchore Engine サービスが起動して稼働していることを確認できれば、利用を開始する準備は整います。

docker run anchore/engine-cli:latest anchore-cli --u admin --p foobar --url http://172.18.0.1:8228/v1 system status

Service simplequeue (dockerhostid-anchore-engine, http://anchore-engine:8083): up
Service analyzer (dockerhostid-anchore-engine, http://anchore-engine:8084): up
Service policy_engine (dockerhostid-anchore-engine, http://anchore-engine:8087): up
Service catalog (dockerhostid-anchore-engine, http://anchore-engine:8082): up
Service apiext (dockerhostid-anchore-engine, http://anchore-engine:8228): up
Service kubernetes_webhook (dockerhostid-anchore-engine, http://anchore-engine:8338): up

Engine DB Version: 0.0.7
Engine Code Version: 0.2.3

Helmを使って Kubernetes に Anchore Engine をインストールする方法

You can also install Anchore Engine in Kubernetes with Helmと Kubernetes にインストールすることもできます。実行手順は次のとおりです:

helm install --name anchore-stack stable/anchore-engine

デプロイが完了すると、サービスに接続するための手順や便利なコマンドの一覧が表示されます。

その前に、すべての Pod が起動して稼働しているかを確認してみましょう。

kubectl get pods
NAME READY STATUS RESTARTS AGE
anchore-stack-anchore-engine-core-5bf44cb6cd-zxx2k 1/1 Running 0 38m
anchore-stack-anchore-engine-worker-5f865c7bf-r72vs 1/1 Running 0 38m
anchore-stack-postgresql-76c87599dc-bbnxn 1/1 Running 0 38m

次に、画面に表示された手順に従って、anchore-cli ツールを備えたエフェメラルコンテナを起動します。

ANCHORECLIUSER=admin
ANCHORECLIPASS=$(kubectl get secret --namespace default anchore-stack-anchore-engine -o jsonpath="{.data.adminPassword}" | base64 --decode; echo)
kubectl run -i --tty anchore-cli --restart=Always --image anchore/engine-cli --env ANCHORECLIUSER=admin --env ANCHORECLIPASS=${ANCHORECLIPASS} --env ANCHORECLIURL=http://anchore-stack-anchore-engine.default.svc.cluster.local:8228/v1/
/ anchore-cli system status

helm install コマンドから直接設定できるパラメータは数多くあります。デフォルトのパスワードを必ず変更し、永続ストレージボリュームを設定することが重要です。すべての項目については values.yaml ファイルを確認してくださ

プライベート Docker リポジトリをスキャンするように Anchore を設定する

自分でホスティングしている場合でも、一般的なクラウドレジストリを利用している場合でも、Docker V2 互換のプライベートイメージレジストリを Anchore Engine に追加するのは非常に簡単です。

Anchore にプライベート Docker リポジトリをスキャンさせるには、レジストリ関連のすべての操作に対して registry サブコマンドを使用します。その動作はほとんど自己説明的です。

anchore-cli registry add index.docker.io <user> <password>
anchore-cli registry list
Registry Type User
index.docker.io docker_v2 mateobur

また、index.docker.io をローカルレジストリの URL に置き換えてください。

これで準備が整い、プライベートレジストリからイメージをプルしてスキャンできるようになります。

anchore-cli image add index.docker.io/mateobur/secureclient:latest
Image Digest: sha256:dda434d0e19db72c3277944f92e203fe14f407937ed9f3f9534ec0579ce9cdac
Analysis Status: analyzed
Image Type: docker
Image ID: 5e1be4e7763143e8ff153887d2ae510fe1fee59c9a55392d65f4da73c9626d76
Dockerfile Mode: Guessed
Distro: ubuntu
Distro Version: 18.04
Size: 127739629
Architecture: amd64
Layer Count: 6

Full Tag: index.docker.io/mateobur/secureclient:latest

プライベートリポジトリからプルするには、コンテナ名にレジストリの URL を追加する必要があります。<username>/<imagename> だけを入力しても動作しません。

なお、ベンダー固有の Docker レジストリによっては、ユーザー名/パスワード以外に追加のパラメータが必要になる場合があります。例えば、Anchore を使って Amazon Elastic Container Registry (ECR) をスキャンするケースがそれに該当します。

CI/CD セキュリティ:Jenkins で行う Docker 脆弱性スキャン

Jenkins はオープンソースのオートメーションサーバーであり、デリバリーパイプラインに含まれる一般的なツールをサポートするプラグインエコシステムを備えています。Jenkins は CI/CD プロセスの自動化を支援します。Anchore は CI/CD パイプラインにシームレスに組み込めるよう設計されており、開発者が Git などのソースコード管理システムにコードをコミットすると、この変更をトリガーに Jenkins がビルドを開始し、コンテナイメージを作成します。

一般的なワークフローでは、そのコンテナイメージは自動テストにかけられます。しかし、もしイメージが Docker セキュリティスキャンに合格せず(組織のセキュリティやコンプライアンス要件を満たしていない場合)、そのイメージに対して自動テストを実行する時間を費やすのは意味がありません。より良いアプローチは、ビルドを失敗させて「早く学ぶ」ことであり、適切なレポートを開発者に返し、問題に対応できるようにすることです。


Jenkins のインターフェースからアクセスできる公式プラグインリストにある「Anchore プラグイン」を利用できます。

プラグインをインストールし、Engine との接続を設定したら(上記リンクの手順に従ってください)、パイプラインの中で Anchore の評価をもうひとつの(必須の)ステップとして組み込むことができます。

こうすることで、カタログは自動的に最新の状態に保たれ、Docker レジストリに到達して自動化された機能テストが実行される前に、不安全なイメージを検出して排除することが可能になります。

「Manage Jenkins -> Configure System」メニューから、Engine API エンドポイントおよび認証情報との接続を設定する必要があります。


ビルドパイプラインの最後のステップとして、イメージ名、タグ、そして(オプションで)Dockerfile のパスをワークスペース内のローカルファイル 「anchore_images」 に書き込むことができます。


その後、次のビルドステップで Anchore コンテナイメージスキャナーを呼び出すことができます。

Anchore が「ビルド停止」となる脆弱性を検出した場合、ビルドは失敗します。もちろん、何をトリガーとしてビルドを停止させるかは自分で定義できます


以下は、Anchore Engine によってビルドプロセスが停止された例です。各脆弱性についての説明や、詳細な記述や緩和手順へのリンクなどが含まれています。

このような評価の結果は Anchore Engine のカタログに追加されます。その後、この承認/却下された Docker イメージのカタログを利用して、Kubernetes API によってどの Pod を受け入れるかをフィルタリングしたり、Sysdig Falco のランタイムルールへの入力として活用したりすることができます。

Anchore Engine と Kubernetes を統合してイメージを検証する

Kubernetes の ImagePolicyWebhook アドミッションコントローラーは、バックエンドの Webhook によって Pod をクラスターに許可するかどうかなどのアドミッションの決定を行うことを可能にします。

Anchore Engine は、この機能を有効にするために特別に設計された Webhook サービスを提供しています。

詳細はドキュメント全体をクイックスタートスクリプトも用意されています。

すでに kubectl と helm が利用可能で設定済みであることを前提として、次を実行します:

git clone https://github.com/viglesiasce/kubernetes-anchore-image-validator.git
cd kubernetes-anchore-image-validator/
./hack/install.sh

install.sh スクリプトを実行した後、Kubernetes の Webhook 設定を有効にする必要があります。その手順は Helm の出力に表示されます。


File: DockerscanValidatingWebhookConfiguration.yaml
-----------------------------------------------------

Anchore engine policy validator is now installed.

Create a validating webhook resources to start enforcement:

KUBE_CA=$(kubectl config view --minify=true --flatten -o json | jq '.clusters[0].cluster."certificate-authority-data"' -r)
cat > validating-webook.yaml <

有効化してから数分後には、すべての Pod が anchore ネームスペース上で稼働するようになります。

kubectl get pods -n anchore
NAME READY STATUS RESTARTS AGE
analysis-anchore-engine-core-97dc7ccdb-w9bhb 1/1 Running 0 3h
analysis-anchore-engine-worker-7b5c95b57c-d9dmg 1/1 Running 0 3h
analysis-anchore-policy-validator-54d598ddb7-6ts 1/1 Running 0 3h
analysis-postgresql-c7df6d66f-xhnrz 1/1 Running 0 3h

統合を有効化するための手順に従うと、新しい Webhook が設定されていることを確認できるようになります。

kubectl get validatingwebhookconfiguration
NAME AGE
analysis-anchore-policy-validator.admission.anchore.io 20h

これで Anchore は、Kubernetes でスケジュールされるすべての Pod のイメージを解析し、セキュアでないと評価されたコンテナは次のように実行フェーズに入ることはありません。

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedCreate 19s (x13 over 41s) daemonset-controller Error creating: admission webhook "analysis-anchore-policy-validator.admission.anchore.io" denied the request: Image failed policy check: wordpress:latest

禁止された Docker イメージまたは未スキャンのイメージをブロックする

一方では、デプロイ前にイメージスキャンがあり、もう一方では、デプロイ後にランタイムセキュリティがあります。この 2 つの間に関連性はあるのでしょうか?実際にはあります。それぞれのイベントは、両方の側面で有用となり得ます。

例えば、Anchore Engine の Docker スキャンを Falco のランタイムセキュリティと統合することを考えてみましょう。Anchore Engine によってセキュアでないとマークされたイメージがノード上で生成されたときにアラートをトリガーする Sysdig Falco ルールを作成するとしたらどうでしょうか。これは多くの場面で有用です。たとえば Kubernetes Webhook を使用していない場合、Kubernetes を利用していない場合、Webhook が失敗した場合、あるいはコンテナが稼働した後に脆弱性が見つかった場合などです。

すでに Anchore Engine API に接続するためのユーザー、パスワード、URL を把握している場合、Sysdig Falco と Anchore の統合を直接利用できます。

docker run --rm -e ANCHORECLIUSER=$ANCHORE_USER
-e ANCHORECLIPASS=$ANCHORECLIPASS
-e ANCHORECLIURL=http://$HOST:$PORT/v1
sysdig/anchore-falco

これにより、Falco の設定に直接追加できるルールが出力されます。

- macro: anchorestoppolicyevaluationcontainers
condition: container.image.id in ("52057de6c8d0d0143dfc71fde55e58edaf3ccc5c2212221a614f45283c5ab063", "65bf726222e13b0ceff0bb20bb6f0e99cbf403a7a1f611fdd2aadd0c8919bbcf", "a8a59477268d92f434d86a73b5ea6de9bf7b05d536359413e79da1feb31f87aa", "a5b7afcfdcc878fae7696ea80eecc31114b9c712a1e896cba87a999d255e4a7b", "8753edeb1aa342081179474cfe5449f1b7d101d92d2799a7840da744b9bbb3ca", "857bc7ff918f67a8e74abd01dc02308040f7f7f9b99956a815c5a9cb6393f11f", "8626492fecd368469e92258dfcafe055f636cb9cbc321a5865a98a0a6c99b8dd", "e86d9bb526efa0b0401189d8df6e3856d0320a3d20045c87b4e49c8a8bdb22c1")

- rule: Run Anchore Containers with Stop Policy Evaluation
desc: Detect containers which does not receive a positive Policy Evaluation from Anchore Engine.

condition: evt.type=execve and proc.vpid=1 and container and anchorestoppolicyevaluationcontainers
output: A stop policy evaluation container from anchore has started (%container.info image=%container.image)
priority: INFO
tags: [container]

この統合を定期的に実行し、ステータスを再評価して、クラスター内で実行された場合にアラートを出したい新しい Docker イメージで Falco ルールを更新する必要があります。

結論

イメージスキャンとランタイムセキュリティに関する主なポイントは以下のとおりです:

  • ランタイムセキュリティはデプロイ後に行われますが、イメージスキャンは CI/CD パイプライン内で、イメージを公開する前やレジストリに登録された段階で実行されます。
  • ランタイムセキュリティとイメージスキャンはコンテナライフサイクルの異なる段階で発生しますが、両者の間には関連があり、コンテナ内部に含まれるものやその機能に関する情報など、有用な結びつきを見出すことができます。
  • イメージスキャンを分析・検査・サポートするためのオープンソースツールはいくつか存在します。その中でも Anchore Engine は、柔軟なユーザー定義ポリシー、API、そして優れたパフォーマンスにより、推奨される選択肢です。

Anchore と、最初の部分で紹介したすべてのオープンソースプロジェクト ― Falco、NATS、Kubeless、Helm、そして言うまでもなく Kubernetes ― に Python や Golang のコードを組み合わせることで、私たちが優れたオープンソースコンテナセキュリティのリファレンススタックと考えるものを構築しています。

このプロジェクトへ貢献するには、次のようにさまざまな方法があります:

@anchore までお気軽にご連絡ください!

FAQs

No items found.

セキュリティ専門家とともに、
クラウドを防御する正しい方法を試してみよう