Amazon ECRとInspectorのイメージスキャン機能の違い

この記事は [**セゾン情報システムズ Advent Calendar 2021**](https://qiita.com/advent-calendar/2021/sisco) 6日目の記事です。

## はじめに
AWS re:Invent 2021 で 脆弱性管理サービスの Amazon Inspector がリニューアルされ、全く新しい Amazon Inspector (v2) としてリリースされました。新しい Inspector ではこれまでの EC2 に対するスキャンだけではなく、新たに Amazon ECR に格納されたコンテナイメージに対するスキャンを実行できるようになりました。

https://aws.amazon.com/jp/blogs/news/improved-automated-vulnerability-management-for-cloud-workloads-with-a-new-amazon-inspector/

本記事では Inspector が提供するイメージスキャン機能と以前より提供されている Amazon ECR のスキャン機能との違いについてまとめます。

## 比較
Inspector によるイメージスキャン機能の提供により、 ECR のスキャン機能は基本スキャン (Basic scanning)、 Inspector によるスキャン機能は拡張スキャン (Enhanced scanning) という名称になりました。基本スキャンと拡張スキャンの主な違いは以下のとおりです。

|項目|基本スキャン|拡張スキャン|
|---|---|---|
|脆弱性の検知対象|OS パッケージのみ|OS とプログラミング言語パッケージ|
|脆弱性の検知タイミング|イメージ Push 時|脆弱性発生時|
|利用料金|無料|有料|
|EventBrdige との連携|あり (スキャン結果のサマリーのみ)|あり|
|AWS Security Hub との統合|なし|あり|
|AWS Organizations のサポート|なし|あり|

### 脆弱性の検知対象
基本スキャンはオープンソースの Clair プロジェクトの CVE データベースを使用したスキャンを提供します。脆弱性の検知対象は OS パッケージのみです。

拡張スキャンは OS パッケージに加え、プログラミング言語パッケージの脆弱性を検知することが可能です。対応するプログラミング言語は以下のとおりです。

* C#
* Golang
* Java
* JavaScript
* PHP
* Python
* Ruby
* Rust

https://docs.aws.amazon.com/inspector/latest/user/supported.html

### 脆弱性の検知タイミング
基本スキャンはイメージが Push された際にスキャンを起動する (Scan on push) か、手動でスキャンを開始することができます。そのため脆弱性を検知できるタイミングもそのどちらかになります。手動スキャンの実行は各イメージごとに24時間に1回に制限されます。

拡張スキャンではリポジトリに対し連続スキャンを利用することができます。連続スキャンはイメージが Push されたタイミングに加え、Amazon Inspector の脆弱性データベースの更新が行われるたびに自動的にイメージスキャンを実行します。つまり脆弱性情報の更新とほぼ同じタイミングで脆弱性を検知できることになります。

拡張スキャンでは連続スキャンを有効化するか、Push 時のみのスキャンとするかをリポジトリ名のスキャンフィルターで定義できます。**拡張スキャンでは手動のスキャン実行はできません。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/c6417c01-c9fa-dda2-3e27-c50143dc8ccf.png)

### 利用料金
基本スキャンは無料で利用できますが、拡張スキャンは有償機能です。2021年12時点の東京リージョンの月額料金は以下のとおりです。

* ECR へのプッシュ時に最初にスキャンされたコンテナイメージあたり: $0.11
* コンテナイメージに対する連続スキャンの数: スキャンごとに $0.01

料金ページ:
https://aws.amazon.com/inspector/pricing/

### EventBrdige との連携
基本スキャンが完了すると EventBridge にイベントが送信され、スキャン結果のサマリーを取得できます。

https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr-eventbridge.html

拡張スキャンが有効になっている場合、以下のようなイベントが EventBridge に送信されます。

* リポジトリスキャン頻度変更のイベント
* 初回のイメージスキャンのイベント (基本スキャンと同等の内容)
* イメージスキャンの Findings の更新 (created, updated, closed) イベント

基本スキャンとは異なり、発見された脆弱性ごとにも Event が発行されます。詳細は以下のドキュメントを参照してください。

https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html#image-scanning-enhanced-events

### AWS Security Hub との統合
AWS Security Hub を有効化している環境では Amazon Inspector との統合も自動で有効化されます。そのため拡張スキャンで発見された脆弱性は自動で Security Hub に送信され、既存のセキュリティ運用のワークフローに含めることができます。

https://docs.aws.amazon.com/inspector/latest/user/securityhub-integration.html

### AWS Organizations のサポート
新しい Amazon Inspector は AWS Organizations との統合もサポートしています。委任された管理者アカウントは組織内のすべてのメンバーアカウントに対して EC2 のスキャンと ECR のスキャン (拡張スキャン) を有効化し、脆弱性を管理することができます。また組織に新しく追加されたアカウントの自動有効化にも対応しています。

https://docs.aws.amazon.com/inspector/latest/user/adding-member-accounts.html

## 拡張スキャン利用時の注意点
### 手動スキャンは実行不可
拡張スキャンを有効にした環境では手動スキャンを実行できません。

### リポジトリ単位のスキャン設定は非推奨に
リポジトリレベルのイメージスキャンの設定は非推奨になりました。基本スキャンを使用する場合でもスキャンフィルターの利用が推奨されます。リポジトリレベルの設定とレジストリのスキャンフィルターを両方設定した場合は、レジストリのスキャンフィルターの設定が優先されます。拡張スキャンの連続スキャン設定はスキャンフィルターでのみ指定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/c071a8de-0238-71a1-2aa0-4aced4612e60.png)

### 連続スキャンはイメージが Push されてから 30 日まで
連続スキャンが構成されると、イメージがリポジトリにプッシュされてから 30 日間スキャンされます。過去 30 日間にイメージが更新されていない場合、そのイメージの連続スキャンは一時停止されます。

### 基本スキャンは併用できない
スキャン設定はレジストリ全体に対しての設定です。リポジトリごとにスキャンタイプを切り替えることはできません。また拡張スキャンを有効化した場合、コンソール上からは過去の基本スキャンの結果が参照できなくなります (No scan findings と表示されます)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/b134c363-c71a-e1f6-098e-7a7d21b33d3b.png)

結果は消えているわけではなく、スキャンタイプを基本スキャンに戻すと再度参照できるようになります。

## 拡張スキャンをやってみる
### 設定
Amazon ECR コンソールの Private registry → Scanning の編集をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/5c90e1f3-d298-346b-64bf-0c48112f6bb8.png)

スキャンタイプで拡張スキャンを選択します。レジストリに対する設定となるため、基本スキャンとの併用はできないことに注意してください。連続スキャン、Push 時のスキャンそれぞれに対し、スキャンフィルターで対象のリポジトリを絞ることができます。ここでは `test/` で始まるリポジトリ名を対象とするようにフィルターを設定しましたが、すべてのリポジトリを対象とすることもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/2ba84e2b-c7ba-f4a2-4624-65503bc23ce3.png)


拡張スキャンの追加料金に関するメッセージが表示されるため、確認をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/abae8ee5-b709-c6f2-e856-58abb250fb03.png)

スキャン設定がベーシックから拡張版に変わったことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/f673adac-2365-cacb-3ec0-fdecafe7a631.png)

新しい Inspector コンソールの Account management ページを確認すると ECR container scanning が Enabled になっていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/576b3300-bffb-d382-0da3-5fb53d556c36.png)

Inspector のダッシュボードで拡張スキャンが有効になっているリポジトリのカバレッジを確認することもできます。この環境ではもともと基本スキャンで「イメージプッシュ時のスキャン」を有効にしていたリポジトリが4つあったため、それが引き継がれています。リポジトリ単位のイメージスキャンの設定は非推奨となったため、無効化してスキャンフィルターで対象を管理する方が望ましいでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/4d5092c1-df8c-7616-3557-7c19d1937082.png)

### 動作確認
実際にイメージを push してみます。拡張スキャンはプログラミング言語固有の脆弱性を検知できるため、ここでは Java アプリケーションのコンテナイメージ を使用します。先ほど設定したスキャンフィルターに合致するようリポジトリ名を入力して作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/2b8a5b43-27a3-67ba-343d-620675ffe3ad.png)


作成されたリポジトリのスキャン頻度が Continuous に設定されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/61191208-fb37-03e4-6966-a3fa83bbf2d2.png)

脆弱性を検知させるため、テスト用の古い Java アプリケーションが含まれるイメージを push しました。

```shell-session
$ aws ecr get-login-password | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded

$ docker tag test/java-sample-app:v1.1.0 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test/java-sample-app:v1.1.0
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test/java-sample-app:v1.1.0
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test/java-sample-app]
c5baabd61e59: Pushed 
88e64033fc7f: Pushed 
0466be121ce3: Pushed 
b87942114db6: Pushed 
v1.1.0: digest: sha256:69a58fe6b25d21015da0f170ffa6934f2ec2827562238ecbde902ldkgi2d082b size: 1165
```

Inspector のコンソールを確認すると、かなり多くの脆弱性を検知していることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/24778dfd-3b16-9827-b9bf-585412639d73.png)

All Findings から Critical な脆弱性の1つを確認します。Java で JSON を処理するためのライブラリである Jackson の脆弱性を検知しています。基本スキャンではこのようなプログラミング言語パッケージの脆弱性は検知できません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/60887fc5-2040-c0e4-ad51-bf7e08709570.png)

Security Hub にも結果が連携されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/33fce9f6-334d-bade-75f1-42d409194b8e.png)

拡張スキャンは有料ではありますが、プログラミング言語パッケージの脆弱性の検知や、自動連続スキャンの実行など充実した機能が備わっています。基本スキャンとの併用はできないものの、そのメリットは十分に感じることができたので積極的に使っていこうと思います。

### 追記: 既存のイメージに拡張スキャンが実行されるか
拡張スキャンを有効化した際に、既存のリポジトリに格納されている一部のイメージも初回のスキャンが実行されることに気づきました。
検証した限りでは

* リポジトリが連続スキャンの対象となっている
* Push されてから30日以内のイメージである

という条件を満たせば格納済みのイメージに対しても初回のスキャンが実行されるようです。
## 公式ドキュメント
https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html

https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ecr.html

以上です。
参考になれば幸いです。