OPS

Amazon ECRの脆弱性スキャン結果をリアルタイムでメール通知する方法

Amazon ECRの脆弱性スキャン結果をリアルタイムでメール通知する方法

2023.03.09

本記事のポイント

Amazon Elastic Container Registry(以下、ECR)を利用している企業様の中でECRにイメージがプッシュされたタイミングなどに実施される脆弱性スキャンの結果をリアルタイムで通知したいと考えている方は多いのではないでしょうか。
本記事では、Amazon EventBridge(以下、EventBridge)と連携し脆弱性スキャンが完了したタイミングでメール通知する方法をご紹介します。


Amazon ECRの脆弱性スキャンとは

脆弱性スキャンの説明の前にECRについて軽くご説明します。
ECRとはセキュリティ、スケーラビリティ、信頼性を備えた AWS マネージドコンテナイメージレジストリサービスです。簡潔に説明するとAmazon Elastic Container Service(以下、ECS)のタスク定義やAmazon Elastic Kubernetes Service(以下、EKS)のポッド仕様で使用できるイメージを管理するサービスです。

そのECRにイメージが作成された際にソフトウェアに脆弱性がないか自動的に確認してくれるのがスキャンになります。スキャンは以下の通り2種類ありますが、本ページではベーシックスキャンについての通知方法をご紹介します。

拡張スキャン

Amazon ECR は Amazon Inspector と統合され、リポジトリの自動継続的なスキャンを提供します。コンテナイメージは、オペレーティングシステムとプログラミング言語パッケージの両方の脆弱性についてスキャンされます。新しい脆弱性が発生すると、スキャン結果が更新され、Amazon Inspector は EventBridge にイベントを発行してユーザーに通知します。

ベーシックスキャン

Amazon ECR は、オープンソースの Clair プロジェクトの共通脆弱性識別子 (CVE) データベースを使用します。ベーシックスキャンでは、プッシュ時にスキャンするようにリポジトリを設定します。手動スキャンを実行すると Amazon ECR によってスキャン結果のリストが提供されます。

引用元:スキャンとは(AWS公式)

Amazon ECRの脆弱性スキャン結果を確認してみよう

それでは早速ですがECRのスキャン結果について確認してみようと思います。
まずはAWSコンソールにログインしECRの管理画面を開きます。
※検索窓に「ECR」と入力してもでてこないので「ECS」で検索します。

左側メニューのAmazon ECRの下にリポジトリがあるのでクリックします。
するとECRの管理画面が表示されご利用中のリポジトリが表示されるかと思います。

確認したいリポジトリ名をクリックすると今度はイメージ一覧が表示されます。
その中からスキャンが実施されたイメージの脆弱性列の詳細をクリックすることによりスキャン結果を確認することができます。

ベーシックスキャンでは上記で確認したスキャン結果の画面を見に行かなければどのような内容でスキャンされたのかを知ることができません。
そこでスキャン結果をリアルタイムで通知するために利用するのがEventBridgeというサービスです。

Amazon EventBridgeとは

EventBridgeとはアプリケーションをさまざまなソースからのデータに接続するために使用できるサーバーレスのイベントバスサービスです。今回ではECRにてスキャンが完了したタイミングをEventBridgeにて検知しAmazon Simple Notification Service(以下、SNS)へ連携します。
※SNSとは通知先の情報(メールアドレスなど)を管理するためのサービスです。

基本的には各サービスの中間的な役割を担うサービスですが他にもJSON形式のデータを整形することができ、とても使い勝手のよいサービスとなっています。

Amazon EventBridgeにて脆弱性スキャン結果を検知してみよう

では、早速ですがECRのスキャンをEventBridgeにて検知させてみましょう。
まずはEventBridgeの管理画面を開きます。

左側メニューからルールをクリックします。
するとルールの一覧画面が表示されます。

「ルールを作成」をクリックすると実際の設定画面になりますので、以下を参考に設定を投入します。

ステップ1 ルールの詳細を定義

ステップ1では名前のみ入力し他の項目はデフォルトで問題ありません。
入力後、「次へ」をクリックしステップ2へ進みましょう。

ステップ2 イベントパターンを構築

ステップ2では主に以下の設定項目があります。
・イベントソース
イベントソースではデフォルトのAWS イベントまたは EventBridge パートナーイベントを選択します。

・サンプルイベント
サンプルイベントでは、連携元のサービス(今回ではECR)からどのような情報(JSON形式)を受信するかサンプルとして確認することができます。
今回ではECRからスキャン結果の情報をEventBridgeにて処理するので、サンプルイベントからECRと検索しECR Image Scanを選択してみましょう。するとテキストエリアにJSON形式で情報が表示されると思います。最後の項番6ではこの情報を整形する方法もご紹介しますので本項目では確認するレベルで問題ありません。

・作成のメソッド
作成のメソッドでは「パターンフォームを使用する」を選択します。

・イベントパターン
イベントパターンでは以下の通り設定します。
イベントソース:AWSのサービス
AWSのサービス:Amazon Elastic Container Registry(ECR)
イベントタイプ:ECR Image Scan

上記設定後、「次へ」をクリックしステップ3へ進みましょう。

ステップ3 ターゲットを選択

ステップ3ではSNSへ連携するための設定をします。
ターゲットを選択からSNS トピックを選択し表示されたトピックからメール通知させたいトピックを選択しましょう。
追加設定は一旦デフォルトのままで良いです。

上記設定後、「次へ」をクリックしステップ4へ進みましょう。

ステップ4 タグを設定

ステップ4ではタグの設定ができますが今回は特に設定しませんので「次へ」をクリックし最終確認に進みましょう。

ステップ1~4まで問題ないことを確認し「ルールの作成」をクリックします。
これでECRのスキャンが完了したタイミングでメール通知してくれるルールが作成されました。

実際にECRのスキャンを実行すると以下のようなメールが通知されるかと思います。
※一部記載できない内容は〓で置き換えています。

件名: AWS Notification Message

本文:

{"version":"0","id":"〓ID〓","detail-type":"ECR Image Scan","source":"aws.ecr","account":"〓account〓","time":"〓time〓","region":"ap-northeast-1","resources":["〓resources〓"],"detail":{"scan-status":"COMPLETE","repository-name":"〓repository-name〓","image-digest":"〓image-digest〓","image-tags":["latest"],"finding-severity-counts":{"MEDIUM":19,"INFORMATIONAL":8,"LOW":7}}}

上記のメール内容では見づらいので項番5でメール内容を整形してみましょう。

メール通知内容を整形してみよう

先ほど作成したルールではメール通知はされるが本文がJSON形式となっていて見づらいため、本文を整形してみましょう。

まずは作成したルールを開き右上の「編集」をクリックしましょう。

左側からステップ3の「ターゲットを選択」をクリックし編集画面を開きます。

追加設定を展開すると設定項目が表示されるので「ターゲット入力を設定」を「入力トランスフォーマー」を選択します。
入力トランスフォーマーを設定が表示されるのでクリックすると、設定画面が表示されるのでターゲット入力トランスフォーマーにサンプルとしては以下を設定します。

入力パス:

{"CRITICAL":"$.detail.finding-severity-counts.CRITICAL","HIGH":"$.detail.finding-severity-counts.HIGH","INFORMATIONAL":"$.detail.finding-severity-counts.INFORMATIONAL","LOW":"$.detail.finding-severity-counts.LOW","MEDIUM":"$.detail.finding-severity-counts.MEDIUM","UNDEFINED":"$.detail.finding-severity-counts.UNDEFINED","detailtype":"$.detail-type","image":"$.detail.image-tags","repository":"$.detail.repository-name","time":"$.time"}

テンプレート:

"脆弱性のスキャン結果をご報告致します。"

"【ECR情報】"
"イベントタイプ:<detailtype>"
"スキャン日時 :<time>"
"リポジトリ名 :<repository>"

"【スキャン結果】"
"CRITICAL   :<CRITICAL>件"
"HIGH     :<HIGH>件"

上記設定後、「確認」をクリックし設定を保存してください。

再度ECRのスキャンを実行すると以下のメールが通知されると思います。

本文:

"脆弱性のスキャン結果をご報告致します。"

"【ECR情報】"
"イベントタイプ:ECR Image Scan"
"スキャン日時 :〓スキャン日時〓"
"リポジトリ名 :〓リポジトリ名〓"

"【スキャン結果】"
"CRITICAL   :〓件数〓件"
"HIGH     :〓件数〓件"

入力トランスフォーマーの設定が少し分かりづらいので補足ですが設定内容としてはJSON形式のデータを任意の名前で記録するための設定、記録したデータを使う設定の2つがあるイメージです。

まずは入力パスでJSON形式のデータを任意の名前で記録するのですが、例として以下のJSONがあったとします。

JSON:

{
	"version":"0",
	"id":"〓",
	"detail-type":"ECR Image Scan",
	"source":"aws.ecr",
	"account":"〓",
	"time":"〓",
	"region":"ap-northeast-1",
	"resources":["〓"],
	"detail":
		{
		"scan-status":"COMPLETE",
		"repository-name":"〓",
		"image-digest":"〓",
		"image-tags":["latest"],
		"finding-severity-counts":
			{
			"MEDIUM":〓,
			"INFORMATIONAL":〓,
			"LOW":〓
		}
	}
}

上記JSONのdetail-typeの値を取得したい場合は以下のように入力パスを記載します。

{ "〓任意の名前〓":"$.detail-type"}

設定後、テンプレートで以下のように<>で囲い記載することによりdetail-typeの値を出力することができます。

<〓任意の名前〓>

MEDIUMのように階層構造になっているデータを入力パスで指定する場合は以下のように.(ドット)で区切り記載することにより可能です。

{"〓任意の名前〓":"$.detail.finding-severity-counts.MEDIUM"}

また、入力パスは以下のように,(カンマ)で区切ることにより複数指定することが可能です。

{ "〓任意の名前〓":"$.detail-type","〓任意の名前〓":"$.detail.finding-severity-counts.MEDIUM"}

まとめ

今回はECRの脆弱性スキャン結果をEventBridgeにて検知しリアルタイムでメール通知する方法をご紹介しました。EventBridgeはECRの他にもさまざまなサービスと連携することが可能なサービスですのでぜひ他のサービスと連携しより良い環境構築をしてはいかがでしょうか。

最後までお読みいただき、ありがとうございました。