新たなAmazon Inspectorと統合されたAmazon ECRのイメージスキャン拡張版がリリースされました! #reinvent

AWS re:Invent 2021にて、Amazon Inspectorの大幅アップデートが発表され、Amazon ECRと統合しコンテナイメージの継続的な脆弱性スキャンが可能になりました!
2021.11.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンサル部のとばち(@toda_kk)です。

AWS re:Invent 2021にて、Amazon Inspectorの大幅アップデートが発表されました!

従来はEC2インスタンスのみが脆弱性スキャンの対象でしたが、Amazon ECRと統合することでコンテナイメージのスキャンにも対応できるようになっています!

Enhanced Scanning、日本語ですと「拡張スキャン」という名称でマネジメントコンソールから確認できます。

一部はSnykの脆弱性データベースを利用している

ECRにおいて従来のイメージスキャン(Basic scanning)では、ClairというOSSのツールがベースとなっていました。

一方、拡張スキャンはInspectorとECRが統合された機能となっており、Inspectorでは脆弱性の検知のためにSnykの脆弱性データベースを利用しているようです。

Amazon Inspector has partnered with Snyk to receive additional vulnerability intelligence for its vulnerability database.

Snykはアプリケーションに特化したセキュリティプラットフォームであり、ソースコードやライブラリとその依存関係、コンテナやInfrastructure as Codeにおける脆弱性を検知し修正するためのツールを提供しています。

さらに言えば、SnykはDockerとも統合されており、docker scanコマンドを実行することで内部的にはSnykエンジンでイメージスキャンが実行されます。

ということは、同じコンテナイメージに対してdocker scanを実行した場合とECRの拡張スキャンを実行した場合とで、脆弱性の検知結果は同じになるのではないか、と考えられます。

実際にそうなるのか、ごく簡単にではありますが、検証してみました。

いきなり検証結果の結論

docker scanによるイメージスキャンと、ECRの拡張スキャンとでは、実行結果は異なっていました。

どうやら、内部的に全く同じ脆弱性データベースを参照しているわけではなさそうです。

ECR拡張スキャンを有効化する

まずは、ECRの拡張スキャンを有効化してみます。

従来のイメージスキャンでは、リポジトリ毎にプッシュ時の自動スキャンを有効化する設定がありました。

拡張スキャンの場合は、プライベートレジストリの設定として有効化する必要があります。

リポジトリではなくレジストリ(=リージョン)毎に、従来のスキャンと拡張スキャンのどちらか一方を設定する形になります。

拡張スキャンの実行頻度の設定として、継続的なスキャンと、プッシュ時のみのスキャンのどちらか一方が設定できます。

スキャン対象とするリポジトリを限定したい場合は、「フィルターを追加」によって可能です。フィルターにはワイルドカード(*)が利用できるため、スキャンしたいリポジトリ名には特定の文字列を含ませることでリポジトリを追加した際も自動でスキャン対象に含める、といった運用が可能になります。

なお、拡張スキャンを利用可能なリージョンにおいては、従来のイメージスキャンの設定は非推奨となっています。

リポジトリ毎の設定で従来のイメージスキャンを有効化していても、レジストリの設定で拡張スキャンが有効化されていれば拡張スキャンの方が優先されます。

マネジメントコンソールでは、ECRプライベートレジストリのリポジトリ一覧ページでリポジトリ毎の「スキャン頻度」の設定を確認できるようになっています。

ECR拡張スキャンを実行してみる

それでは実際に、ECR拡張スキャンを試してみます。

検証用のイメージとして、Ubuntu と Nginx の公式イメージを使います。さまざまな脆弱性を検知して欲しいため、少し古いイメージを用意してECRプライベートレジストリにプッシュしていきます。

それぞれ、"test-scan-ubuntu" "test-scan-nginx" という名前でリポジトリを作成し、下記のようなコマンドを実行していきます。

ECRへのプッシュ

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

$ docker pull ubuntu:bionic-20210118
bionic-20210118: Pulling from library/ubuntu
d519e2592276: Pull complete
d22d2dfcfa9c: Pull complete
b3afe92c540b: Pull complete
Digest: sha256:ea188fdc5be9b25ca048f1e882b33f1bc763fb976a8a4fea446b38ed0efcbeba
Status: Downloaded newer image for ubuntu:bionic-20210118
docker.io/library/ubuntu:bionic-20210118
$ docker tag ubuntu:bionic-20210118 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-ubuntu:v1
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-ubuntu:v1
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-ubuntu]
9f10818f1f96: Pushed
27502392e386: Pushed
c95d2191d777: Pushed
v1: digest: sha256:2aeed98f2fa91c365730dc5d70d18e95e8d53ad4f1bbf4269c3bb625060383f0 size: 943

 $ docker pull nginx:1.19.7
1.19.7: Pulling from library/nginx
45b42c59be33: Pull complete
8acc495f1d91: Pull complete
ec3bd7de90d7: Pull complete
19e2441aeeab: Pull complete
f5a38c5f8d4e: Pull complete
83500d851118: Pull complete
Digest: sha256:f3693fe50d5b1df1ecd315d54813a77afd56b0245a404055a946574deb6b34fc
Status: Downloaded newer image for nginx:1.19.7
docker.io/library/nginx:1.19.7
$ docker tag nginx:1.19.7 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-nginx:v1
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-nginx:v1
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-nginx]
2acf82036f38: Pushed
9f65d1d4c869: Pushed
0f804d36244d: Pushed
9b23c8e1e6f9: Pushed
ffd3d6313c9b: Pushed
9eb82f04c782: Pushed
v1: digest: sha256:b08ecc9f7997452ef24358f3e43b9c66888fadb31f3e5de22fec922975caa75a size: 1570

ECRへのプッシュが完了した後イメージスキャンが実行開始され、しばらくすると検出された脆弱性をFindingsとして確認できます。

脆弱性の一覧と、Inspectorによって評価された脅威の重要度を確認できます。古いイメージなので、それなりに出ています。特にNginxの方は激しいですね。

Ubuntuのスキャン結果
Nginxのスキャン結果

FindingsはInspectorのダッシュボードからも確認できます。Inspectorのダッシュボードでは、ECRだけでなくEC2インスタンスで検出された脆弱性についても一元的に確認することができるようです。

ECR拡張スキャンとdocker scanで実行結果を比較してみる

さて、続いてdocker scanコマンドによるイメージスキャンを実行してみます。

まず事前準備として、Docker IDを用いた認証が必要となります。まだDocker IDを登録していない場合は、Dokcer HubからSingupが必要です。

docker scan --loginを実行することで、表示されるURLから認証画面にアクセスできます。通常は、デフォルトのブラウザが開き自動的にページに遷移します。

Docker IDを用いた認証

$ docker scan --login

Now redirecting you to our auth page, go ahead and log in,
and once the auth is complete, return to this prompt and you'll
be ready to start using snyk.

If you can't wait use this url:
https://snyk.io/login?token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&utm_medium=Partner&utm_source=Docker&utm_campaign=Docker-Desktop-2020&os=darwin&docker=false

Docker IDとパスワードを入力し、ログインします。

Snykとの関連付けを行うページが表示されるので、「Authenticate」します。

成功すると、CUI上では下記のような文言が表示されます。

認証成功

Your account has been authenticated. Snyk is now ready to be used.

docker scanコマンドによるイメージスキャンができるようになったので、先ほどと同じように Ubuntu と Nginx で実行してみます。

Ubuntuのスキャン結果

$ docker scan 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-ubuntu:v1
Testing 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-ubuntu:v1...

(一部抜粋)

Organization:      tobachi
Package manager:   deb
Project name:      docker-image|123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-ubuntu
Docker image:      123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-ubuntu:v1
Platform:          linux/amd64
Base image:        ubuntu:bionic-20210118
Licenses:          enabled

Tested 90 dependencies for known issues, found 35 issues.

Base Image              Vulnerabilities  Severity
ubuntu:bionic-20210118  35               0 critical, 1 high, 10 medium, 24 low

Recommendations for base image upgrade:

Minor upgrades
Base Image              Vulnerabilities  Severity
ubuntu:bionic-20210930  25               0 critical, 0 high, 4 medium, 21 low

Major upgrades
Base Image              Vulnerabilities  Severity
ubuntu:impish-20211015  13               0 critical, 0 high, 2 medium, 11 low

Nginxのスキャン結果

$ docker scan 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-nginx:v1
Testing 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-nginx:v1...

(一部抜粋)

Organization:      tobachi
Package manager:   deb
Project name:      docker-image|123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-nginx
Docker image:      123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/test-scan-nginx:v1
Platform:          linux/amd64
Base image:        nginx:1.19.7
Licenses:          enabled

Tested 136 dependencies for known issues, found 158 issues.

Base Image    Vulnerabilities  Severity
nginx:1.19.7  158              18 critical, 33 high, 24 medium, 83 low

Recommendations for base image upgrade:

Minor upgrades
Base Image    Vulnerabilities  Severity
nginx:1.20.2  67               2 critical, 3 high, 4 medium, 58 low

Alternative image types
Base Image         Vulnerabilities  Severity
nginx:1.20.2-perl  67               2 critical, 3 high, 4 medium, 58 low

検出結果のうち、脆弱性の重要度ごとの件数部分を抜粋してみました。

前掲のECR拡張スキャンでの実行結果と比較してみると、Ubuntu、Nginxのどちらのイメージでも検出された件数が異なっていることがわかります。

つまり、どうやらdocker scanによるイメージスキャンとECR拡張スキャンとで、同じ動作が実行されているわけではなさそうです。

検出結果に違いが出た理由についてはさらなる検証が必要そうですが、おそらく内部的に参照している脆弱性データベースが全く同じというわけではないのではないかと予想しています。

再び公式アナウンスのページからSnykに関して言及されている箇所を引用しますが、 "receive additional vulnerability intelligence for its vulnerability database" と表現されています。

Amazon Inspector has partnered with Snyk to receive additional vulnerability intelligence for its vulnerability database.

Inspectorでは単純にSnykのデータベースをそのまま使っているわけではなく、AWSが従来より内部で運用していたデータベースに追加してSnykのデータベースを統合している、ということなのだと考えられます。

というわけで、docker scanによるイメージスキャンや、さらにいえばSnyk純正のイメージスキャンと、ECRのイメージスキャンとは別物と考えて良さそうです。

さらに、検出結果の違いで言えば、ECRの従来のイメージスキャン(Basic Scanning)と拡張スキャンとで違いが出るのか、出るとすればどういった違いになるのか、ということが気になってきます。こうした点についても、別途検証を重ねていきたいと思います。

よくありそうな質問

検出結果のほかに、多くの人が疑問に思いそうな内容を勝手にまとめてみました。

なお、引用は全てAWS公式ドキュメントのユーザーガイドからのものとなります。

拡張スキャンでは料金は発生する?

従来のイメージスキャンは無料で利用できましたが、拡張スキャンではInspectorの料金が発生します。

イメージをプッシュした初回時のスキャンと、継続的な再スキャンとで、料金が異なっています。

東京リージョンの場合、前者はイメージ毎に $0.11、後者はスキャン実行毎に $0.01 となっています。

手動スキャンはできる?

従来のイメージスキャンでは、スキャンを手動で実行することができましたが、拡張スキャンでは(少なくとも現時点では)手動スキャンができないようです。

When your private registry has enhanced scanning enabled, all repositories matching the scan filters are scanned using enhanced scanning only. Any repositories that don't match a filter will have a Manual scan frequency, but won't be scanned. Manual scans using enhanced scanning isn't supported.

EventBridgeに発行されるイベントに変更はある?

スキャン実行時にEventBridgeに発行されるイベントが変更されます。

従来のイメージスキャンはECRからイベントが発行されていましたが、拡張スキャンではInspector2からイベントが発行されることになり、イベントの内容・形式も異なります。

さらに、スキャン実行のイベントに加えて、スキャンによって検出された脆弱性(Findings)に関するイベントが1件ごとに発行されるようです。

下記は、EventBridgeでイベントパターン{"source": ["aws.inspector2"]}を指定して実際に取得できたイベントのサンプルです。

{"source": ["aws.inspector"]}では検知できないので、ご注意ください。

スキャン実行のイベント

{
    "version": "0",
    "id": "5bc0f75d-c328-76d2-825d-84808004952e",
    "detail-type": "Inspector2 Scan",
    "source": "aws.inspector2",
    "account": "123456789012",
    "time": "2021-12-01T08:39:40Z",
    "region": "ap-northeast-1",
    "resources": [
        "arn:aws:ecr:ap-northeast-1:123456789012:repository/test-scan-hoge"
    ],
    "detail": {
        "scan-status": "INITIAL_SCAN_COMPLETE",
        "repository-name": "arn:aws:ecr:ap-northeast-1:123456789012:repository/test-scan-hoge",
        "finding-severity-counts": {
            "CRITICAL": 0,
            "HIGH": 18,
            "MEDIUM": 9,
            "TOTAL": 27
        },
        "image-digest": "sha256:1f327b1059ece690069edcde4984ee6b71f1a9ea57f21619548b2f6d4a4a7292",
        "image-tags": [
            "latest"
        ]
    }
}

Finsingsのイベント

{
    "version": "0",
    "id": "5dd54816-cbf4-54c8-a953-0ec9e3aa0424",
    "detail-type": "Inspector2 Finding",
    "source": "aws.inspector2",
    "account": "123456789012",
    "time": "2021-12-01T08:38:55Z",
    "region": "ap-northeast-1",
    "resources": [
        "arn:aws:ecr:ap-northeast-1:123456789012:repository/test-scan-hoge/sha256:1f327b1059ece690069edcde4984ee6b71f1a9ea57f21619548b2f6d4a4a7292"
    ],
    "detail": {
        "awsAccountId": "123456789012",
        "description": "A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the getvar_s function",
        "findingArn": "arn:aws:inspector2:ap-northeast-1:123456789012:finding/90dc732d458b49f4eda4a232e26ed86f",
        "firstObservedAt": "Dec 1, 2021, 8:38:55 AM",
        "inspectorScore": 7.2,
        "inspectorScoreDetails": {
            "adjustedCvss": {
                "adjustments": [],
                "cvssSource": "NVD",
                "score": 7.2,
                "scoreSource": "NVD",
                "scoringVector": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
                "version": "3.1"
            }
        },
        "lastObservedAt": "Dec 1, 2021, 8:38:55 AM",
        "packageVulnerabilityDetails": {
            "cvss": [
                {
                    "baseScore": 6.5,
                    "scoringVector": "AV:N/AC:L/Au:S/C:P/I:P/A:P",
                    "source": "NVD",
                    "version": "2.0"
                },
                {
                    "baseScore": 7.2,
                    "scoringVector": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
                    "source": "NVD",
                    "version": "3.1"
                }
            ],
            "referenceUrls": [
                "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/6T2TURBYYJGBMQTTN2DSOAIQGP7WCPGV/",
                "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/UQXGOGWBIYWOIVXJVRKHZR34UMEHQBXS/"
            ],
            "source": "NVD",
            "sourceUrl": "https://nvd.nist.gov/vuln/detail/CVE-2021-42382",
            "vendorCreatedAt": "Nov 15, 2021, 9:15:00 PM",
            "vendorSeverity": "HIGH",
            "vendorUpdatedAt": "Nov 29, 2021, 6:43:00 PM",
            "vulnerabilityId": "CVE-2021-42382",
            "vulnerablePackages": [
                {
                    "arch": "X86_64",
                    "epoch": 0,
                    "name": "busybox",
                    "packageManager": "OS",
                    "release": "r20",
                    "sourceLayerHash": "sha256:e519532ddf75bafbbb0ad01d3fb678ef9395cd8554fa25bef4695bb6e11f39f1",
                    "version": "1.31.1"
                }
            ]
        },
        "remediation": {
            "recommendation": {
                "text": "Update all packages in the vulnerable packages section to their latest versions."
            }
        },
        "resources": [
            {
                "details": {
                    "awsEcrContainerImage": {
                        "architecture": "amd64",
                        "imageHash": "sha256:1f327b1059ece690069edcde4984ee6b71f1a9ea57f21619548b2f6d4a4a7292",
                        "imageTags": [
                            "latest"
                        ],
                        "platform": "ALPINE_LINUX_3_12",
                        "pushedAt": "Dec 1, 2021, 8:38:29 AM",
                        "registry": "123456789012",
                        "repositoryName": "test-scan-hoge"
                    }
                },
                "id": "arn:aws:ecr:ap-northeast-1:123456789012:repository/test-scan-hoge/sha256:1f327b1059ece690069edcde4984ee6b71f1a9ea57f21619548b2f6d4a4a7292",
                "partition": "N/A",
                "region": "N/A",
                "type": "AWS_ECR_CONTAINER_IMAGE"
            }
        ],
        "severity": "HIGH",
        "status": "ACTIVE",
        "title": "CVE-2021-42382 - busybox",
        "type": "PACKAGE_VULNERABILITY",
        "updatedAt": "Dec 1, 2021, 8:38:55 AM"
    }
}

ただし、スキャン頻度の設定を変更した場合のイベントについては、ECRから発行されます。下記はAWS公式ドキュメントからそのまま引用したものです。

スキャン頻度設定変更イベント

{
	"version": "0",
	"id": "0c18352a-a4d4-6853-ef53-0ab8638973bf",
	"detail-type": "ECR Scan Resource Change",
	"source": "aws.ecr",
	"account": "123456789012",
	"time": "2021-10-14T20:53:46Z",
	"region": "us-east-1",
	"resources": [],
	"detail": {
		"action-type": "SCAN_FREQUENCY_CHANGE",
		"repositories": [{
				"repository-name": "repository-1",
				"repository-arn": "arn:aws:ecr:us-east-1:123456789012:repository/repository-1",
				"scan-frequency": "SCAN_ON_PUSH",
				"previous-scan-frequency": "MANUAL"
			},
			{
				"repository-name": "repository-2",
				"repository-arn": "arn:aws:ecr:us-east-1:123456789012:repository/repository-2",
				"scan-frequency": "CONTINUOUS_SCAN",
				"previous-scan-frequency": "SCAN_ON_PUSH"
			},
			{
				"repository-name": "repository-3",
				"repository-arn": "arn:aws:ecr:us-east-1:123456789012:repository/repository-3",
				"scan-frequency": "CONTINUOUS_SCAN",
				"previous-scan-frequency": "SCAN_ON_PUSH"
			}
		],
		"resource-type": "REPOSITORY",
		"scan-type": "ENHANCED"
	}
}

継続的にスキャンする場合、スキャンが実行されるタイミングは?

新たなCVEが脆弱性データベースに追加されたタイミングで、継続的スキャンを有効化している全てのリポジトリに対してスキャンが実行されます。

Automated rescans are triggered for container images based on whether you use the continual or on-push option in your Enhanced scanning settings. Whenever Amazon Inspector adds a new CVE to its database, all eligible containers images in your configured Amazon ECR repositories are scanned in response.

コンテナイメージの継続的なスキャンと脆弱性管理が容易に!

継続的なスキャンを実行したい場合、従来は自前で仕組みを組むなどの工夫が必要でしたが、拡張スキャンによって導入が容易になりました!

さらに、InspectorがSecurity Hubなど他のAWSセキュリティサービスとも統合していることにより、脆弱性管理の手間も大きく省けるのではないかと思います。

従来のスキャンでプッシュ時の自動スキャンを有効化しているものの、検出された脆弱性に対応できていなかったり、修復できているのかどうか把握できていなかったり、といったように適切な脆弱性管理ができていないケースも多いのではないかと思います。

拡張スキャンを利用することで、検出された脆弱性を継続的にモニタリングし、修復されたのか否かを容易に確認でき、脅威に対して適切に管理し対応することが可能になります。

イメージスキャンはコンテナセキュリティにおける一部分ではあるものの、AWSのマネージドサービスだけで十分に対応できるとなれば安全なコンテナ運用にも大いに繋げられるため、ぜひご活用ください!

以上、コンサル部のとばち(@toda_kk)でした。