本ページはプロモーションが含まれています

Docker

Dockerの脆弱性診断方法|Trivy・Grype使い方

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

Dockerイメージの脆弱性診断・スキャンは、TrivyやGrypeといったOSSツールを使えば数分で始められます

この記事では、脆弱性が生まれる仕組みから、Trivy・Grypeの導入手順、CI/CDパイプラインへの自動組み込み、検出後のトリアージ(優先順位づけ)までを一気通貫で解説します。

私自身、Dockerを業務で使い始めたころ、古いベースイメージを使い続けた結果、セキュリティ監査で大量の脆弱性を指摘され、対応に奔走した経験があります。

当時はスキャンツールも今ほど手軽ではありませんでした。

「作ったDockerイメージ、セキュリティは大丈夫だろうか」「TrivyとGrype、結局どちらを選べばいいのか」——そうした疑問に、実際のコマンド例とCI/CD設定例を交えて答えていきます。

この記事でわかること

  • TrivyとGrypeの導入手順と使い分け
  • CI/CDパイプラインへの脆弱性スキャンの組み込み方
  • 検出された脆弱性のトリアージ(優先順位づけ)と対処法

Dockerの脆弱性診断(スキャン)とは?

Dockerの脆弱性診断(スキャン)とは何かを示す図解

Dockerの脆弱性スキャンとは、Dockerイメージに含まれるOSのパッケージや、インストールされたライブラリなどに、脆弱性がないかチェックする仕組みです。

あわせて読む

イメージをビルドした時点では安全でも、時間が経つにつれて新たな脆弱性が見つかることは日常茶飯事。

スキャンは、それらの脅威をいち早く発見するための「健康診断」のようなものです。

なぜDockerイメージに脆弱性が生まれるのか

Dockerイメージに脆弱性が生まれる主な理由は3つあります。

  1. ベースイメージの脆弱性FROM ubuntu:20.04 や FROM alpine:3.18 のように、元となるOSイメージ自体に脆弱性が含まれている場合があります。
  2. 追加したパッケージの脆弱性apt install や pip install などで追加したミドルウェアやライブラリに、古いバージョン特有の脆弱性が潜んでいるケースです。
  3. アプリケーションコードの依存ライブラリ開発したアプリケーションが利用しているライブラリ(例: Node.jsのnpmパッケージ)に脆弱性がある場合も、イメージの一部となります。
あわせて読む

Dockerイメージは一度作成すると中身が固定されますが、脆弱性情報は日々更新されます。

つまり、昨日まで安全だったイメージが、今日には危険になっている可能性があるのです。

脆弱性スキャンの目的と重要性

脆弱性スキャンの目的は、攻撃者に悪用される前に、イメージ内の既知の脆弱性を特定し、事前に対策を講じることにあります。

コンテナ環境では、同じイメージから多数のコンテナが起動されることが一般的。

もし、その大元となるイメージに深刻な脆弱性があれば、被害は一気に拡大してしまいます。

スキャンは、コンテナ環境を守るための最初の、そして最も重要な防衛ラインなのです。

脆弱性を放置するとどうなる?

脆弱性を放置することは、家に鍵をかけずに外出するようなものです。

具体的には、以下のような深刻な事態を招く恐れがあります。

  • リモートコード実行: 攻撃者がコンテナを乗っ取り、内部で不正なプログラムを実行する。
  • 情報漏洩: コンテナ内や、コンテナがアクセスできるデータベースから機密情報が盗まれる。
  • サービス停止(DoS): コンテナを停止させられ、サービスが提供できなくなる。
  • ランサムウェアの踏み台: コンテナが暗号化され、身代金を要求されたり、他のシステムへの攻撃拠点として悪用されたりする。

ビジネスの信用失墜はもちろん、顧客情報の漏洩などが発生すれば、金銭的な被害や法令違反に問われるリスクも抱えることになります。

Dockerで脆弱性を診断・スキャンする主な方法

Dockerイメージの脆弱性を診断・スキャンする主な方法を示す図解

Dockerイメージの脆弱性をスキャンするには、いくつかの方法があります。手軽さや運用のしやすさが異なるため、目的に合わせて選びましょう。

Docker Hubの自動スキャン機能

Docker Hubのスキャン機能は現在Docker Scoutに完全移行しており、旧docker scan時代の機能は廃止されています。

Docker Hubリポジトリと連携したPush時の自動スキャンは、Docker Scoutの機能として提供されています。

リポジトリと連携させるだけで手軽にスキャン結果を確認できるのがメリットです。

ただし、無料プランではスキャン回数に制限があったり、より詳細な分析やCI連携には有料プランが必要になったりします。

docker scout コマンドの使い方(旧docker scanの後継)

docker scan コマンドは2023年4月13日にサポートが終了しており、現在のDocker Desktopでは利用できません。

後継のdocker scoutコマンドに置き換わっています。

docker scout cves your-image:tag

docker scanは内部的にSnykというセキュリティ企業の脆弱性データベースを利用していましたが、docker scoutはDocker独自のスキャンエンジンを採用しています。

ローカル環境で開発中のイメージを手軽にチェックできるのが大きな利点です。

ただし、CI/CDパイプラインに組み込んで本格的に自動化しようとすると、Docker Hubアカウントとの連携やスキャン回数の制限を考慮する必要があります。

OSSツールを使ったスキャン(Trivy, Clair, Grypeなど)

現在、多くの開発現場で主流となっているのが、オープンソース(OSS)のスキャンツールを利用する方法です。

代表的なツールとして、Trivy(トリビー)Grype(グライプ)Clair(クレア)などがあります。

Trivy・Grype・Clairなどのツールは、手元のPCやCI/CDサーバー上で自由に実行でき、カスタマイズ性も高いのが特徴です。

スキャン対象もDockerイメージに限りません。OSや設定ファイル(IaC)まで多岐にわたり、総合的なセキュリティチェックが可能です。

代表的な脆弱性スキャンツール比較

Trivy・Grypeなど代表的な脆弱性スキャンツールの比較を示す図解

ここでは、特に人気のあるOSSツール「Trivy」と「Grype」を中心に、その特徴と導入手順を紹介します。

Trivyの特徴と導入手順

Trivyは、Aqua Security社が開発するオープンソースの脆弱性スキャナです。

  • 特徴:
    • シンプル: インストールが簡単で、コマンドも直感的。
    • 高速: スキャン速度が非常に速い。
    • 多機能: Dockerイメージのほか、OSパッケージ、言語ライブラリ、Kubernetes設定ファイル、Dockerfileのベストプラクティスなど、スキャン対象が豊富。
  • 導入手順(macOSの例): Homebrewを使えば簡単にインストールできます。brew install trivy
  • 基本的な使い方: スキャンしたいイメージ名を指定するだけです。trivy image your-image:tag

Grypeの特徴と導入手順

Grypeは、Anchore社によって開発されているスキャンツールです。

  • 特徴:
    • シンプルで高速: Trivyと同様に、使いやすく高速なスキャンが可能です。
    • SBOM連携: Syftというツール(Grypeに内包)と連携し、イメージのソフトウェア部品表(SBOM)を生成・スキャンする流れに強い。
    • 高精度: 脆弱性の検出精度にも定評があります。
  • 導入手順(macOSの例): こちらもHomebrewでインストール可能です。brew install grype
  • 基本的な使い方: Grypeもイメージ名を指定するだけでスキャンが実行されます。grype your-image:tag

Anchore・Clairとの違い

ツール開発元位置づけ特徴
TrivyAqua SecurityOSSスキャナシンプル・高速・多機能でDockerイメージ以外も幅広くスキャン可能
GrypeAnchoreOSSスキャナSyftとのSBOM連携に強く、検出精度に定評
Anchore EnterpriseAnchore企業向け商用版Grypeの機能に加え、高度なポリシー管理・GUIダッシュボード・SBOM管理を搭載
ClairCoreOS(現Red Hat)OSSスキャナ(老舗)コンテナレジストリ「Quay」等で標準採用。TrivyやGrype登場前のデファクトスタンダードだが導入・運用はTrivy・Grypeより複雑

どのツールを選ぶべきか?用途別のおすすめ

ツールの選択は「Trivy」か「Grype」の2択で問題ありません。

  • 手軽に・幅広くスキャンしたい: Trivyをおすすめします。Dockerイメージ以外のスキャン対象(IaC設定ファイルなど)も豊富で、これ一つで多くのセキュリティチェックをカバーできます。
  • シンプルさとSBOM連携を重視: Grypeも良い選択です。Syftと組み合わせてSBOM(ソフトウェア部品表)を管理・運用していく流れを重視するなら、Grypeが適しています。

どちらも優秀なツールで機能面での差は縮まっています。まずは両方を試し、出力結果の見やすさで選ぶことをおすすめします。

脆弱性診断・スキャンの実践手順

Dockerイメージの脆弱性診断・スキャンを実践する手順を示す図解

ここでは、Trivyを例にして、実際にイメージをスキャンし、結果をどう読み解き、対処するかを具体的に見ていきます。

Dockerイメージをビルドする

まず、スキャン対象となる簡単なDockerイメージをビルドします。

例として、古いPythonイメージを使ったDockerfileを用意します(Python 3.9は2025年10月にセキュリティサポートが終了しているため、実運用では3.12以降を推奨します)。

Dockerfile

# 意図的に古いバージョンを指定
FROM python:3.9-slim-buster

RUN pip install flask==2.0.0

CMD ["flask", "run"]

このファイルがあるディレクトリで、以下のコマンドを実行しイメージをビルドします。

docker build -t my-vulnerable-app:1.0 .
あわせて読む

スキャンコマンドを実行する

ビルドしたイメージをTrivyでスキャンします。

trivy image my-vulnerable-app:1.0

コマンドを実行すると、Trivyが脆弱性データベースとイメージ内のパッケージを照合し、結果がターミナルに表形式で出力されます。

結果レポートの見方と危険度の判断

スキャン結果には、以下のような情報が含まれています。

Total: 120 (UNKNOWN: 0, LOW: 50, MEDIUM: 40, HIGH: 25, CRITICAL: 5)

┌───────────────────┬──────────────┬──────────┬───────────────────┬───────────────┬───────────────────────────────────┐
│ Library           │ CVE ID       │ Severity │ Installed Version │ Fixed Version │ Title                             │
├───────────────────┼──────────────┼──────────┼───────────────────┼───────────────┼───────────────────────────────────┤
│ glibc             │ CVE-2022-23219 │ CRITICAL │ 2.28-10           │ 2.28-10+deb10u1 │ glibc: stack overflow in ...      │
├───────────────────┼──────────────┼──────────┼───────────────────┼───────────────┼───────────────────────────────────┤
│ openssl           │ CVE-2023-0286 │ HIGH     │ 1.1.1n-0+deb10u2  │ 1.1.1n-0+deb10u3 │ openssl: X.400 address type ...   │
├───────────────────┼──────────────┼──────────┼───────────────────┼───────────────┼───────────────────────────────────┤
│ flask             │ CVE-2023-37314 │ MEDIUM   │ 2.0.0             │ 2.2.3         │ flask: Werkzeug debug pin ...     │
└───────────────────┴──────────────┴──────────┴───────────────────┴───────────────┴───────────────────────────────────┘

注目すべきポイント:

  • Total (集計): 脆弱性の総数と、重大度(Severity)別の内訳。
  • Severity (重大度): CRITICAL (致命的), HIGH (高), MEDIUM (中), LOW (低) の4段階(+ UNKNOWN)。
  • CVE ID: 脆弱性ごとの世界共通の識別番号。
  • Installed Version: イメージに含まれているパッケージのバージョン。
  • Fixed Version(修正バージョン): ここが最重要です。この脆弱性が修正されたパッケージのバージョンが示されています。

危険度の判断は、まずCRITICALHIGHの脆弱性に注目します。これらは攻撃に悪用されやすく、早急な対処が必要です。

検出された脆弱性の対処法(パッケージ更新・ベースイメージ変更)

脆弱性が検出されたら、Fixed Version(修正バージョン)情報を元に対処します。

  1. パッケージの更新(Fixed Versionがある場合): Dockerfile を修正し、脆弱性が修正されたバージョンがインストールされるようにします。
    • OSパッケージ (例: glibc, openssl) の場合:RUN apt-get update && apt-get upgrade -y のようなコマンドをDockerfileの後半(RUN命令の前)に追加し、OSパッケージを最新にします。
    • ライブラリ (例: flask) の場合:RUN pip install flask==2.2.3 のように、Fixed Version(またはそれ以上)のバージョンを明示的に指定します。
  2. ベースイメージの変更: OSパッケージに大量の脆弱性がある場合、apt-get upgradeで対応するとイメージサイズが肥大化したり、依存関係が壊れたりすることがあります。その場合は、ベースイメージ自体をより新しいものに変更するのが最も効果的です。Dockerfile# NG: FROM python:3.9-slim-buster (Debian 10) # OK: FROM python:3.9-slim-bookworm (Debian 12) FROM python:3.9-slim-bookworm # ... 以降は同じ 多くの場合、これだけでOSレベルの脆弱性の大部分は解消されます。
  3. 対処が難しい場合(Fixed Versionがない等): 修正バージョンがまだ提供されていない場合や、業務上どうしても古いバージョンを使う必要がある場合は、その脆弱性のリスクを評価し、trivyの.trivyignoreファイルで特定の脆弱性をスキャン対象から除外(=リスクを許容)する判断も必要になります。

CI/CDパイプラインにスキャンを組み込む方法

CI/CDパイプラインにDockerの脆弱性スキャンを組み込む方法を示す図解

脆弱性スキャンは、手動でたまに実行するだけでは不十分です。

CI/CDパイプラインに組み込み、コードが変更されるたびに自動でスキャンを実行する仕組みが不可欠。

GitHub Actionsでの自動スキャン設定例

GitHub Actions(GitHubActions)では、Trivyが公式のアクション(aquasecurity/trivy-action)を提供しており、簡単に導入できます。

.github/workflows/security.yml といったファイルを作成し、以下のように記述します。

name: Docker Image Scan

on:
  push:
    branches: [ "main" ]
  pull_request:

jobs:
  build_and_scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Build an image
        run: docker build -t my-vulnerable-app:latest .

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@v0.36.0
        with:
          image-ref: 'my-vulnerable-app:latest'
          format: 'table'
          # CRITICALかHIGHの脆弱性が見つかったらビルドを失敗させる
          exit-code: '1'
          ignore-unfixed: true
          severity: 'CRITICAL,HIGH' 

この設定のポイントは、severity: 'CRITICAL,HIGH'exit-code: '1' です。

この設定により、深刻な脆弱性が1件でも見つかったら、ビルド(ワークフロー)が自動的に失敗します。

深刻な脆弱性を含んだイメージがレジストリにPushされる、あるいは本番環境にデプロイされる。そうした事態を水際で防げます。

GitLab CI/CDでの導入方法

GitLab CI/CDは、標準機能として強力なコンテナスキャンを搭載しています。

.gitlab-ci.yml にテンプレートをインクルードするだけで、スキャンが実行されるようになります。

stages:
  - build
  - test

include:
  - template: Jobs/Build.gitlab-ci.yml
  - template: Security/Container-Scanning.gitlab-ci.yml

# ビルドジョブ (Container-Scanningが参照するために必要)
docker-build:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

GitLabは、マージリクエスト画面でスキャン結果を分かりやすく表示してくれるため、開発者が脆弱性を認識しやすくなるメリットがあります。

自動化で見落としを防ぐポイント

自動化でスキャンの見落としを防ぐには、以下の2点が重要です。

  1. ビルドのたびにスキャンする: イメージが作られるたびに必ずスキャンを実行します。
  2. 深刻な脆弱性ではビルドを失敗させる: 「警告は出るけどデプロイはできる」状態だと、いずれ見過ごされます。CRITICALHIGHは即時対応が必要なものとして、CI/CDプロセスを止める勇気が求められます。

セキュリティレベルを高めるための運用の工夫

Dockerのセキュリティレベルを高めるための運用の工夫を示す図解

ツールを導入して自動化するだけでは、セキュリティは万全になりません。継続的な「運用」が求められます。

スキャン結果を定期的にレビューする

CI/CDでのスキャンは「開発時」のチェックです。それに加え、「本番稼働中」のイメージも定期的に(例: 週に一度)再スキャンする仕組みが必要です。

稼働開始時には見つかっていなかった新しい脆弱性が、日々発見されているためです。定期スキャンで新たな脅威を検知し、対応計画を立てる必要があります。

脆弱性のトリアージ(優先度づけ)方法

スキャンを実行すると、特に古いイメージでは100件以上の脆弱性が見つかります。これらすべてに即時対応するのは現実的ではありません。

そこでトリアージ(優先度づけ)が必要になります。

  1. 重大度で絞る: まずはCRITICALHIGHに集中します。
  2. 修正可能性で絞る: Fixed Version(修正バージョン)が提供されているものから対応します。
  3. 公開状況で絞る: インターネットから直接アクセスされるコンテナ(例: Webサーバー)の脆弱性を最優先にします。

CVSS(共通脆弱性評価システム)のスコアや、攻撃の容易さなども考慮し、チーム内で「どれから手をつけるか」を判断するルールを決めておきましょう。

セキュリティベースラインの維持と継続的改善

「私たちのチームは、CRITICALな脆弱性が含まれたイメージの本番投入を絶対に許可しない」

「HIGHの脆弱性は、発見から5営業日以内に修正計画を立てる」

チームとして守るべきセキュリティの最低基準(ベースライン)を定めます。

そして、スキャンツール自体や脆弱性データベースを常に最新の状態に保ち、使用するベースイメージ(例: ubuntu:20.04

2026年8月時点で既にサポート終了済み)も定期的に見直し(例: ubuntu:24.04や最新LTSのubuntu:26.04へ移行)、継続的にセキュリティレベルを改善していく姿勢が大切です。

あわせて読む

よくある質問

Q1. Dockerイメージの脆弱性診断(スキャン)とは何ですか?

A1. Dockerイメージに含まれるOSのパッケージやライブラリに、既知の脆弱性がないかを自動ツールでチェックする仕組みです。TrivyやGrypeなどのOSSツールを使えば数分で実行できます。

Q2. docker scanコマンドはまだ使えますか?

A2. いいえ、docker scanコマンドは2023年4月13日にサポートが終了しています。現在は後継のdocker scoutコマンド、またはTrivy・Grypeなどのオープンソースツールを使用します。

Q3. TrivyとGrype、どちらを使うべきですか?

A3. 手軽さと幅広いスキャン対象(IaC設定ファイル等)を重視するならTrivy、SBOM(ソフトウェア部品表)管理を重視するならGrypeがおすすめです。どちらも高速でシンプルに使えます。

Q4. Dockerの脆弱性スキャンはCI/CDに組み込めますか?

A4. はい。GitHub Actionsなら公式アクション「aquasecurity/trivy-action」、GitLab CI/CDなら標準テンプレート「Security/Container-Scanning.gitlab-ci.yml」を使えば簡単に自動化できます。

Q5. 脆弱性が大量に検出された場合、どこから対処すればいいですか?

A5. まずCRITICALとHIGHの重大度に絞り、次にFixed Version(修正バージョン)が提供されているものから対応します。インターネットに公開されているコンテナの脆弱性を最優先にしましょう。

Q6. 脆弱性スキャンはCI/CD時だけで十分ですか?

A6. 不十分です。稼働開始後に新たな脆弱性が日々発見されるため、本番稼働中のイメージも定期的(例: 週に一度)に再スキャンする運用が必要です。

Q7. 脆弱性を放置するとどうなりますか?

A7. リモートコード実行や情報漏洩、サービス停止、ランサムウェアの踏み台にされるなどの深刻な被害につながる恐れがあります。ビジネスの信用失墜や法令違反のリスクも伴います。

まとめ|Dockerセキュリティを日常的に保つために

Dockerの脆弱性スキャンは、現代のコンテナ開発において必須のプロセスです。

難しく聞こえるかもしれませんが、TrivyやGrypeのような優れたOSSツールのおかげで、誰でも簡単に始められます。

スキャンは「一度きり」ではなく「継続」が鍵

最もお伝えしたいのは、セキュリティは「一度やったら終わり」ではない、ということです。

開発時(CI/CD)のスキャンと、運用時の両輪を回し続けること。そして、検出された脆弱性に対して、優先度をつけながら継続的に対処していくこと。

これがDockerセキュリティの鍵となります。

セキュリティ文化をチーム全体で育てる

脆弱性の対応は、インフラ担当者やセキュリティ担当者だけの仕事ではありません。

開発者自身がDockerfileを書く段階で、より軽量で安全なベースイメージ(distrolessイメージなど)を選択し、スキャン結果を自分ごととして確認する文化がセキュリティレベルを左右します。

ぜひこの記事をきっかけに、Dockerの脆弱性スキャンを「当たり前の開発習慣」としてチームに取り入れてみてください。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

-Docker