docker scout cves コマンドを使って脆弱性を見つける方法

DockerBeginner
オンラインで実践に進む

はじめに

この実験では、docker scout cves コマンドを効果的に使用して、Docker イメージおよび関連アーティファクト内の脆弱性を特定する方法を学びます。まず、Docker イメージ内の脆弱性を直接分析し、脆弱性のあるイメージを取得し、Trivy などのセキュリティスキャナを使用して潜在的な問題を見つける方法を実演します。

その後、docker save で作成した tarball および OCI ディレクトリからの脆弱性分析方法を探索し、docker scout cves コマンドがさまざまな形式に対応している柔軟性を示します。最後に、脆弱性レポートを SARIF JSON ファイルにエクスポートしてさらに処理する方法、および関連する EPSS スコア付きで脆弱性を表示して修復作業の優先順位を決める方法を学びます。

Docker イメージの脆弱性を分析する

このステップでは、Trivy を使用して Docker イメージ内の脆弱性を分析する方法を学びます。Trivy は包括的かつ汎用性の高いセキュリティスキャナです。オペレーティングシステムのパッケージ(Alpine、RHEL、CentOS、Debian、Ubuntu など)やアプリケーションの依存関係(Bundler、Composer、npm、yarn など)の脆弱性を検出することができます。また、Trivy はコンテナイメージ、ファイルシステム、Git リポジトリなど、さまざまなスキャン対象をサポートしています。

まず、分析に使用する脆弱性のある Docker イメージを取得しましょう。いくつかの脆弱性が知られている library/ubuntu:18.04 イメージを使用します。

docker pull library/ubuntu:18.04

イメージが取得され、ダウンロードされていることを示す出力が表示されるはずです。

18.04: Pulling from library/ubuntu
...
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04

イメージを取得したので、次に Trivy をインストールする必要があります。LabEx 環境には Trivy が事前にインストールされていないため、公式の GitHub リポジトリから最新のリリースをダウンロードしてインストールします。

wget https://github.com/aquasecurity/trivy/releases/download/v0.50.1/trivy_0.50.1_Linux-64bit.deb

このコマンドは Trivy の Debian パッケージをダウンロードします。次のような出力が表示されるはずです。

--2023-10-27 08:00:00--  https://github.com/aquasecurity/trivy/releases/download/v0.50.1/trivy_0.50.1_Linux-64bit.deb
Resolving github.com (github.com)... 140.82.113.4
Connecting to github.com (github.com)|140.82.113.4|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/140000000/...?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=... [following]
--2023-10-27 08:00:00--  https://objects.githubusercontent.com/github-production-release-asset-2e65be/140000000/...
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 50000000 (48M) [application/octet-stream]
Saving to: ‘trivy_0.50.1_Linux-64bit.deb’

trivy_0.50.1_Linux-64bit.deb 100%[=================================================>]  47.68M  --.-MB/s    in 0.5s

2023-10-27 08:00:01 (95.3 MB/s) - ‘trivy_0.50.1_Linux-64bit.deb’ saved [50000000/50000000]

次に、dpkg を使用してダウンロードしたパッケージをインストールします。

sudo dpkg -i trivy_0.50.1_Linux-64bit.deb

インストールプロセスを示す出力が表示されるはずです。

Selecting previously unselected package trivy.
(Reading database ... 100000 files and directories currently installed.)
Preparing to unpack trivy_0.50.1_Linux-64bit.deb ...
Unpacking trivy (0.50.1) ...
Setting up trivy (0.50.1) ...

Trivy をインストールしたので、library/ubuntu:18.04 Docker イメージの脆弱性をスキャンすることができます。

trivy image library/ubuntu:18.04

Trivy はイメージのスキャンを開始します。脆弱性データベースをダウンロードし、イメージのレイヤーを分析するため、数秒かかる場合があります。進行状況を示す出力が表示され、その後、見つかった脆弱性の詳細レポートが表示されます。

2023-10-27T08:00:05.000+0000    INFO    Need to update DB
2023-10-27T08:00:05.000+0000    INFO    Downloading DB...
...
2023-10-27T08:00:10.000+0000    INFO    Detected OS: ubuntu
2023-10-27T08:00:10.000+0000    INFO    Detecting Ubuntu vulnerabilities...
...
library/ubuntu:18.04 (ubuntu 18.04)
===================================
Total: 100 (UNKNOWN: 0, LOW: 50, MEDIUM: 30, HIGH: 15, CRITICAL: 5)

┌───────────────────────────────────────────────────┬─────────────────────────────────┬──────────┬───────────────────┬───────────────────────────────────────────────────────────┐
│                 Library/Package                   │              Vulnerability              │ Severity │ Installed Version │                       Fixed Version                       │
├───────────────────────────────────────────────────┼─────────────────────────────────┼──────────┼───────────────────┼───────────────────────────────────────────────────────────┤
│ apt                                               │ CVE-YYYY-XXXX                   │ HIGH     │ 1.6.12            │ 1.6.14                                                    │
│ ...                                               │ ...                             │ ...      │ ...               │ ...                                                       │
└───────────────────────────────────────────────────┴─────────────────────────────────┴──────────┴───────────────────┴───────────────────────────────────────────────────────────┘

この出力には、見つかった脆弱性の合計が、深刻度(UNKNOWN、LOW、MEDIUM、HIGH、CRITICAL)別にまとめられています。その後、影響を受けるパッケージ、脆弱性 ID(例:CVE-YYYY-XXXX)、深刻度レベル、パッケージのインストールされているバージョン、利用可能な場合は修正バージョンなどの詳細とともに、各脆弱性がリストされます。このレポートを使用すると、Docker イメージのセキュリティ状況を理解し、修復が必要な領域を特定することができます。

docker save で作成した tarball から脆弱性を分析する

このステップでは、tarball ファイルとして保存された Docker イメージから脆弱性を分析する方法を学びます。これは、Docker レジストリやローカルの Docker デーモンに直接利用できないイメージをスキャンする必要がある場合に便利です。ただし、イメージがファイルとして保存されている場合は有効です。

まず、前のステップで取得した library/ubuntu:18.04 Docker イメージを tarball ファイルに保存する必要があります。これには docker save コマンドを使用できます。

docker save library/ubuntu:18.04 -o ubuntu_18.04.tar

このコマンドは、library/ubuntu:18.04 イメージを現在のディレクトリ (~/project) に ubuntu_18.04.tar という名前のファイルとして保存します。-o フラグは出力ファイルを指定します。

イメージのレイヤーが保存されていることを示す出力が表示されるはずです。

The image 'library/ubuntu:18.04' is being saved to a tar file.
...

イメージを tarball として保存したので、Trivy を使用してこのファイルをスキャンできます。再び trivy image コマンドを使用しますが、今回は tarball ファイルをターゲットとして指定します。

trivy image --input ubuntu_18.04.tar

--input フラグは、Trivy にレジストリからイメージを取得したり、名前でローカルイメージをスキャンしたりする代わりに、tarball ファイルからイメージをスキャンするよう指示します。Trivy は ubuntu_18.04.tar ファイルからイメージデータを読み取り、ローカルイメージを直接スキャンするのと同様に脆弱性分析を実行します。

前のステップと同様に、Trivy が tarball からイメージを読み込んでいること、その後の脆弱性スキャンプロセスとレポートを示す出力が表示されます。

2023-10-27T08:05:00.000+0000    INFO    Loading image from ubuntu_18.04.tar...
2023-10-27T08:05:05.000+0000    INFO    Detected OS: ubuntu
2023-10-27T08:05:05.000+0000    INFO    Detecting Ubuntu vulnerabilities...
...
ubuntu_18.04.tar (ubuntu 18.04)
==============================
Total: 100 (UNKNOWN: 0, LOW: 50, MEDIUM: 30, HIGH: 15, CRITICAL: 5)

┌───────────────────────────────────────────────────┬─────────────────────────────────┬──────────┬───────────────────┬───────────────────────────────────────────────────────────┐
│                 Library/Package                   │              Vulnerability              │ Severity │ Installed Version │                       Fixed Version                       │
├───────────────────────────────────────────────────┼─────────────────────────────────┼──────────┼───────────────────┼───────────────────────────────────────────────────────────┤
│ apt                                               │ CVE-YYYY-XXXX                   │ HIGH     │ 1.6.12            │ 1.6.14                                                    │
│ ...                                               │ ...                             │ ...      │ ...               │ ...                                                       │
└───────────────────────────────────────────────────┴─────────────────────────────────┴──────────┴───────────────────┴───────────────────────────────────────────────────────────┘

これは、docker save で作成された tarball をスキャンすることで、Trivy が Docker デーモンにロードされていない Docker イメージでも分析できることを示しています。これは、イメージがファイルとして転送されるワークフローに脆弱性スキャンを統合する柔軟な方法です。

OCI ディレクトリから脆弱性を分析する

このステップでは、Open Container Initiative (OCI) レイアウト形式で保存されたイメージから脆弱性を分析する方法を探ります。OCI イメージ形式仕様は、コンテナイメージのパッケージング標準を定義しています。Skopeo や Buildah などのツールを使用して、この形式のイメージを作成および管理できます。Trivy は、OCI ディレクトリに保存されたイメージを直接スキャンできます。

まず、library/ubuntu:18.04 Docker イメージから OCI ディレクトリを作成する必要があります。これにはコマンドラインユーティリティ skopeo を使用します。skopeo は事前にインストールされていないため、インストールする必要があります。

sudo apt update
sudo apt install -y skopeo

これによりパッケージリストが更新され、skopeo がインストールされます。インストールプロセスを示す出力が表示されます。

Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
...
Setting up skopeo (1.2.3-3) ...

skopeo がインストールされたので、Docker イメージを OCI ディレクトリにコピーできます。~/project ディレクトリに ubuntu_oci という名前のディレクトリを作成し、skopeo copy を使用してイメージをそこにコピーします。

mkdir ubuntu_oci
skopeo copy docker-daemon:library/ubuntu:18.04 oci:ubuntu_oci:18.04

skopeo copy コマンドは、異なるストレージ場所と形式間でイメージを転送するために使用されます。

  • docker-daemon:library/ubuntu:18.04 はソースイメージを指定します。これはローカルの Docker デーモンにある library/ubuntu:18.04 です。
  • oci:ubuntu_oci:18.04 は宛先の形式と場所を指定します。oci: は OCI 形式を示し、ubuntu_oci は OCI イメージが保存されるディレクトリで、18.04 はその OCI ディレクトリ内のイメージのタグです。

コピープロセスを示す出力が表示されます。

Getting image source signatures
Copying blob sha256:...
...
Copying config sha256:...
Writing manifest to image destination
Storing signatures

これで、OCI イメージデータを含む ubuntu_oci という名前のディレクトリができました。このディレクトリの内容を一覧表示して、OCI レイアウトファイルを確認できます。

ls ubuntu_oci

oci-layoutindex.jsonblobs などのファイルとディレクトリが表示されます。

blobs  index.json  oci-layout

最後に、Trivy を使用してこの OCI ディレクトリの脆弱性をスキャンできます。trivy image コマンドを使用し、OCI ディレクトリのパスを指定します。

trivy image oci:ubuntu_oci:18.04

Trivy は oci: プレフィックスを認識し、ubuntu_oci ディレクトリにあるタグ 18.04 のイメージをスキャンします。Docker イメージを直接スキャンするのと同様に、イメージのレイヤーを分析し、見つかった脆弱性を報告します。

Trivy が OCI イメージをスキャンしていることを示す出力と、その後の脆弱性レポートが表示されます。

2023-10-27T08:10:00.000+0000    INFO    Detected OS: ubuntu
2023-10-27T08:10:00.000+0000    INFO    Detecting Ubuntu vulnerabilities...
...
oci:ubuntu_oci:18.04 (ubuntu 18.04)
==================================
Total: 100 (UNKNOWN: 0, LOW: 50, MEDIUM: 30, HIGH: 15, CRITICAL: 5)

┌───────────────────────────────────────────────────┬─────────────────────────────────┬──────────┬───────────────────┬───────────────────────────────────────────────────────────┐
│                 Library/Package                   │              Vulnerability              │ Severity │ Installed Version │                       Fixed Version                       │
├───────────────────────────────────────────────────┼─────────────────────────────────┼──────────┼───────────────────┼───────────────────────────────────────────────────────────┤
│ apt                                               │ CVE-YYYY-XXXX                   │ HIGH     │ 1.6.12            │ 1.6.14                                                    │
│ ...                                               │ ...                             │ ...      │ ...               │ ...                                                       │
└───────────────────────────────────────────────────┴─────────────────────────────────┴──────────┴───────────────────┴───────────────────────────────────────────────────────────┘

これは、Trivy が OCI 形式で保存されたイメージをスキャンする能力を示しており、コンテナイメージの管理とスキャン方法に柔軟性を提供します。

脆弱性レポートを SARIF JSON ファイルにエクスポートする

このステップでは、Trivy が生成した脆弱性レポートを SARIF JSON ファイルにエクスポートする方法を学びます。SARIF (Static Analysis Results Interchange Format) は、静的解析ツールの出力用の標準形式です。SARIF 形式でレポートをエクスポートすることで、脆弱性スキャン結果を CI/CD パイプラインやセキュリティダッシュボードなどの他のツールやワークフローに簡単に統合できます。

再度 library/ubuntu:18.04 Docker イメージをスキャンしますが、今回は Trivy のフォーマットオプションを使用して結果を SARIF 形式で出力し、ファイルに保存します。

trivy image --format sarif --output report.sarif library/ubuntu:18.04

このコマンドを分解してみましょう。

  • trivy image library/ubuntu:18.04: これは指定された Docker イメージをスキャンする標準コマンドです。
  • --format sarif: このフラグは、Trivy に出力を SARIF JSON 形式でフォーマットするよう指示します。
  • --output report.sarif: このフラグは、出力を現在のディレクトリ (~/project) にある report.sarif という名前のファイルにリダイレクトします。

Trivy はスキャンを実行し、結果を指定されたファイルに保存します。コンソールには詳細なレポートは表示されず、進行状況情報のみが表示されます。

2023-10-27T08:15:00.000+0000    INFO    Detected OS: ubuntu
2023-10-27T08:15:00.000+0000    INFO    Detecting Ubuntu vulnerabilities...
...

コマンドが完了すると、~/project ディレクトリに report.sarif という名前のファイルができているはずです。ls コマンドを使用してその存在を確認できます。

ls report.sarif

ファイル名が表示され、ファイルが作成されたことが確認できます。

report.sarif

catless などのコマンドラインツールを使用して、SARIF ファイルの内容を表示することもできます。内容は SARIF 仕様に従った JSON 形式になります。

cat report.sarif

見つかった脆弱性の数に応じて、かなり長い JSON 出力が表示されます。

{
  "version": "2.1.0",
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "Trivy",
          "version": "0.50.1",
          ...
        }
      },
      "results": [
        {
          "ruleId": "CVE-YYYY-XXXX",
          "level": "error",
          "message": {
            "text": "apt: CVE-YYYY-XXXX (HIGH)"
          },
          ...
        },
        ...
      ]
    }
  ]
}

SARIF 形式でレポートをエクスポートすることは、脆弱性スキャンを自動化されたセキュリティワークフローに統合し、SARIF 標準をサポートするツールを活用する強力な方法です。

EPSS スコア付きで脆弱性を表示する

このステップでは、Trivy を使用して、脆弱性とその Exploit Prediction Scoring System (EPSS) スコアを表示する方法を学びます。EPSS は、脆弱性が実際に悪用される可能性を推定するためのデータ駆動型の取り組みです。脆弱性レポートに EPSS スコアを含めることで、より積極的に悪用される可能性の高い脆弱性に焦点を当てて、修復作業の優先順位を決めることができます。

Trivy は、利用可能な場合、脆弱性の EPSS スコアを取得して表示することができます。これを行うには、--vuln-type os,library フラグを使用して、オペレーティングシステムとライブラリの両方の脆弱性をスキャンするようにする必要があります。Trivy は、特定の CVE に関するデータが利用可能な場合、自動的に出力に EPSS スコアを含めます。

再度 library/ubuntu:18.04 Docker イメージをスキャンしましょう。今回は、OS とライブラリの脆弱性タイプを明示的に要求します。

trivy image --vuln-type os,library library/ubuntu:18.04

--vuln-type os,library フラグは、スキャンする脆弱性のタイプを指定します。デフォルトでは、Trivy はこれらのタイプをスキャンすることが多いですが、このフラグを明示的に含めることで確実になります。Trivy が EPSS データの存在する脆弱性(CVE ID で識別)を見つけると、レポートに EPSS スコアを含めます。

Trivy は前回と同様にスキャンを実行します。出力は最初のスキャンと似ていますが、一部の脆弱性について EPSS スコアの追加の列が表示されることに気づくでしょう。

2023-10-27T08:20:00.000+0000    INFO    Detected OS: ubuntu
2023-10-27T08:20:00.000+0000    INFO    Detecting Ubuntu vulnerabilities...
...
library/ubuntu:18.04 (ubuntu 18.04)
===================================
Total: 100 (UNKNOWN: 0, LOW: 50, MEDIUM: 30, HIGH: 15, CRITICAL: 5)

┌───────────────────────────────────────────────────┬─────────────────────────────────┬──────────┬───────────────────┬───────────────────────────────────────────────────────────┬───────┐
│                 Library/Package                   │              Vulnerability              │ Severity │ Installed Version │                       Fixed Version                       │ EPSS  │
├───────────────────────────────────────────────────┼─────────────────────────────────┼──────────┼───────────────────┼───────────────────────────────────────────────────────────┼───────┤
│ apt                                               │ CVE-YYYY-XXXX                   │ HIGH     │ 1.6.12            │ 1.6.14                                                    │ 0.95  │
│ ...                                               │ ...                             │ ...      │ ...               │ ...                                                       │ ...   │
└───────────────────────────────────────────────────┴─────────────────────────────────┴──────────┴───────────────────┴───────────────────────────────────────────────────────────┴───────┘

出力テーブルに新しい EPSS 列があることに注意してください。この列の値は、対応する脆弱性の EPSS スコアを表し、0 から 1 の範囲です。EPSS スコアが高いほど、次の 30 日間で脆弱性が悪用される確率が高いことを示します。この情報は、どの脆弱性を最初に対処するかの優先順位を決めるために、EPSS スコアの高いものに焦点を当てるのに役立ちます。

脆弱性分析に EPSS スコアを含めることで、単なる深刻度レベルを超えて、リスクと修復に関するより適切な判断を下すことができます。

まとめ

この実験では、汎用的なセキュリティスキャナである Trivy を使用して、Docker イメージの脆弱性を分析する方法を学びました。脆弱性のある Ubuntu イメージを取得し、Trivy をインストールして分析を行いました。この最初のステップでは、稼働中の Docker イメージのセキュリティ上の弱点をスキャンする基本的なプロセスに焦点を当てました。