話題の記事

【超待望アップデート】ECRに対する脆弱性スキャン機能が提供されました

待望と言って良いアップデートです。ECRのイメージに対する脆弱性スキャン機能がマネージドで提供されました。まずは、皆さんのコンテナワークロードにおけるイメージの脆弱性スキャン実施してみて足元を振り返ってみてはいかがでしょうか?
2019.10.28

「俺はこの日を待ち望んでいた…ほんまやで…」

本日、非常に重大なアップデートがECRに舞い降りてきました。なんと、ECRに対するイメージスキャンが実装されたとのことです!

コンテナセキュリティを考えるにあたり、一番最初に気をつけておきたい点がそのコンテナイメージで導入したパッケージに対する脆弱性の混入。今まででも、aquasecurity/trivyや、goodwithtech/dockleなど、フリーで利用できる優秀なツールは存在していましたが、それぞれCI/CDパイプラインへの組み込みなどは独自の仕組みの構築が必要か、もしくは有償のaquaなどのコンテナセキュリティ製品の導入が必須でした。

今回、AWSのECRに対して、AWSマネージドな仕組みで脆弱性スキャンを実行する仕組みがリリースされたので、まずは早速触ってみた様子をお届けいたします。コンテナセキュリティ対策の足固めとして、まずは皆さんのECRリポジトリ、軒並みスキャンしてみてはいかがでしょうか?使い方は非常に簡単。

AWSフルマネージド脆弱性スキャンきたか…!!

  ( ゚д゚) ガタッ
  /   ヾ
__L| / ̄ ̄ ̄/_
  \/   /

ECRのイメージに対する脆弱性スキャンとは?

公式ドキュメントはこちらで公開されています。ここでは、主要な特徴についてまとめてみます。

Image Scanning - Amazon ECR

Amazon ECRのイメージスキャンによって、作成したコンテナイメージへの脆弱性の混入を特定することが可能です。脆弱性スキャン対象の元となっているのは、coreos/clair: Vulnerability Static Analysis for Containersという、オープンソースプロジェクトです。

イメージスキャン方法は?

手動でECRのリポジトリを特定してスキャンする方法と、ECRへのプッシュをトリガーに自動でスキャンする方法の2種類があります。

イメージスキャン完了の通知は?

ECRのスキャン完了後、CloudWatch Eventsがコールされるので、それを拾うことでスキャン後の各種アクションを実行することが可能です。詳細はこちら。

イメージスキャンにかかる料金は?

料金に係る記載がドキュメントのどこにもなく、また特に課金されている様子もないので、恐らく完全無料かと思われます。ホントかな?すげぇ。ECRの料金全般についてのドキュメントはこちら。

実際にECRにあるイメージの脆弱性スキャンしてみた

というわけで、実際にスキャンしてみました。スキャン対象は、なんとなく脆弱性がてんこ盛りに思える以下のイメージです。

クライアントにpullします。

$ docker pull piesecurity/apache-struts2-cve-2017-5638

今回のスキャン用に新しく、ECRリポジトリを作成します。リポジトリ名はecr-scan-sampleとします。

$ aws ecr create-repository --repository-name ecr-scan-sample
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:629895769338:repository/ecr-scan-sample",
        "registryId": "629895769338",
        "repositoryName": "ecr-scan-sample",
        "repositoryUri": "629895769338.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-scan-sample",
        "createdAt": 1572245308.0,
        "imageTagMutability": "MUTABLE"
    }
}

先程、プルしたイメージを作成したECRリポジトリにプッシュします。

$ $(aws ecr get-login --no-include-email --region ap-northeast-1)
$ docker tag piesecurity/apache-struts2-cve-2017-5638 629895769338.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-scan-sample:latest
$ docker push 629895769338.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-scan-sample:latest

Webコンソールを確認すると、リポジトリecr-scan-sampleに当該イメージがアップロードされているのが確認できます。

イメージを選択すると、「スキャン」ボタンがアクティブになるのでクリックします。

ステータスが進行中になります。

しばらくすると、ステータスが完了となり、脆弱性スキャン結果への詳細がリンクとして表示されます。

詳細をクリックすると、このイメージに含まれる脆弱性の一覧がCVEベースで表示されます。リンクは全てCVEデータベースへのリンクになっており、脆弱性の重要度で、並び替えができるようになってます。

イメージプッシュ時の自動スキャン設定

ECRに対して、イメージをプッシュしたときに自動的にスキャンする設定が追加されています。既存のリポジトリを選択した状態で、「編集」ボタンをクリックすると、「リポジトリの編集画面」に遷移します。ここに、「プッシュ時にスキャン」という項目が追加されており、これを有効にしておくと、ECRにイメージをプッシュするたびに自動で、脆弱性スキャンが実行されるというわけです。

AWS CLIによる各種操作

AWS CLIでも、上記操作は一通り実施可能です。CI/CDとかに組み込んだり自動化するにあたっては、こっちのほうがやりやすいでしょう。

AWS CLIの最新化

AWS CLIで最新機能試すときのお作法ですが、まずは最新版にしておきましょう。

自分の環境では、以下のバージョンを利用しています。

$ aws --version
aws-cli/1.16.268 Python/3.6.4 Darwin/18.7.0 botocore/1.13.4

自動スキャンがONになっているECRリポジトリを作成する

イメージスキャンが無料であるならば、自動スキャンをオフにする理由が無い!スキャン自体はイメージプッシュ後非同期で実行されるようなので、正直デフォルトONでも良いかと思ったりしますね。リポジトリ作成するcreate-repositoryコマンドに、scanOnPushプロパティが増えてました。こんなコマンドで作成できます。

$ aws ecr create-repository --repository-name ecr-autoscan-repository --image-scanning-configuration scanOnPush=true
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:629895769338:repository/ecr-autoscan-repository",
        "registryId": "629895769338",
        "repositoryName": "ecr-autoscan-repository",
        "repositoryUri": "629895769338.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-autoscan-repository",
        "createdAt": 1572339130.0,
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": true
        }
    }
}

ちなみに、AWS CLIのドキュメントみていると、正式なオプション名は--image-scanning-configurationとなってます。

既存のECRに対してコンテナ自動スキャンをONに設定する

専用のコマンド、put-image-scanning-configurationが追加されています。

利用例はこちら。

$ aws ecr put-image-scanning-configuration --repository-name ecr-autoscan-repository --image-scanning-configuration scanOnPush=true
{
    "registryId": "629895769338",
    "repositoryName": "ecr-autoscan-repository",
    "imageScanningConfiguration": {
        "scanOnPush": true
    }
}

ECRの中のイメージをスキャンする

専用のコマンド、start-image-scanが増えています。

利用例はこちら。

$ aws ecr start-image-scan --repository-name ecr-scan-sample --image-id imageTag=latest
{
    "registryId": "629895769338",
    "repositoryName": "ecr-scan-sample",
    "imageId": {
        "imageDigest": "sha256:0e50bbb560068a88500da4fcd56264d3e0e386317efe2f3256f33baaba0ddf54",
        "imageTag": "latest"
    },
    "imageScanStatus": {
        "status": "IN_PROGRESS"
    }
}

スキャン結果の取得

専用のコマンド、describe-image-scan-findingsが追加されてます。

利用例はこちら。

$ aws ecr describe-image-scan-findings --repository-name ecr-scan-sample --image-id imageTag=latest

このコマンドで、脆弱性スキャンの結果をJSONで取得できます。長いので抜粋したのを一部掲載します。見つかった脆弱性について、CVE番号であったりとか、関連する情報に対するURI、重要度、関係する属性などが一通り網羅されているので、スキャン結果を解析して次の処理につなげたいなど、このJSONをパースして使う感じになります。

{
    "imageScanFindings": {
        "findings": [
            {
                "name": "CVE-2019-3462",
                "description": "Incorrect sanitation of the 302 redirect field in HTTP transport method of apt versions 1.4.8 and earlier can lead to content injection by a MITM attacker, potentially leading to remote code execution on the target machine.",
                "uri": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-3462",
                "severity": "HIGH",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "1.6.3ubuntu0.1"
                    },
                    {
                        "key": "package_name",
                        "value": "apt"
                    }
                ]
            },
            {
                "name": "CVE-2018-16864",
                "description": "An allocation of memory without limits, that could result in the stack clashing with another memory region, was discovered in systemd-journald when a program with long command line arguments calls syslog. A local attacker may use this flaw to crash systemd-journald or escalate his privileges. Versions through v240 are vulnerable.",
                "uri": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2018-16864",
                "severity": "HIGH",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "237-3ubuntu10.3"
                    },
                    {
                        "key": "package_name",
                        "value": "systemd"
                    }
                ]
            },
            {
                "name": "CVE-2018-16865",
                "description": "An allocation of memory without limits, that could result in the stack clashing with another memory region, was discovered in systemd-journald when many entries are sent to the journal socket. A local attacker, or a remote one if systemd-journal-remote is used, may use this flaw to crash systemd-journald or execute code with journald privileges. Versions through v240 are vulnerable.",
                "uri": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2018-16865",
                "severity": "HIGH",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "237-3ubuntu10.3"
                    },
                    {
                        "key": "package_name",
                        "value": "systemd"
                    }
                ]
            },
            {
                "name": "CVE-2016-1585",
                "description": "In all versions of AppArmor mount rules are accidentally widened when compiled.",
                "uri": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2016-1585",
                "severity": "MEDIUM",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "2.12-4ubuntu5"
                    },
                    {
                        "key": "package_name",
                        "value": "apparmor"
                    }
                ]
            },
        ],
        "imageScanCompletedAt": 1572344124.0,
        "vulnerabilitySourceUpdatedAt": 1572309959.0,
        "findingSeverityCounts": {
            "HIGH": 3,
            "INFORMATIONAL": 15,
            "LOW": 75,
            "MEDIUM": 100
        }
    },
   "registryId": "629895769338",
    "repositoryName": "ecr-scan-sample",
    "imageId": {
        "imageDigest": "sha256:0e50bbb560068a88500da4fcd56264d3e0e386317efe2f3256f33baaba0ddf54",
        "imageTag": "latest"
    },
    "imageScanStatus": {
        "status": "COMPLETE",
        "description": "The scan was completed successfully."
    }
}

ヨゴザンスですな!

「マネージドな仕組みで脆弱性スキャンができることの純粋な喜びに満ちあふれている!」

自分が導入しようとしているイメージの脆弱性をスキャンしておくのは、コンテナセキュリティ対策において、その足固めとして一番基本中の基本と言えます。本来は、この脆弱性スキャンした結果に対して、組織としてのポリシーを設定して「無視してよい脆弱性、CI/CDを必ず止めてリリースさせてはだめな脆弱性」まで踏み込んだ運用がコンテナセキュリティには求められます。

まだそこまでの機能はマネージドの仕組みとして対応されていないようですが、まずは今みなさんが運用されているイメージに対して、どのような脆弱性が潜んでいるのか理解するところから初めてみてはいかがでしょうか。脆弱性試験自体は非常に簡単に実施できます。

みなさんのコンテナワークロードを、セキュリティ観点で見直すきっかけとなれば良いですね。それでは、今日はこのへんで。濱田(@hamako9999)でした。

(参考)コンテナセキュリティ対策一般について

以前、書いた記事ですが、コンテナセキュリティ一般として必要なものがなにか、それらのドキュメントとフリーで利用できるツールをまとめた記事を公開しています。改めてこちらも参考にしていただければと思います。