Trivy on Ubuntu — コンテナイメージ・コード脆弱性スキャンの使い方

セキュリティ

この記事のポイント

  • Trivy は trivy image <IMAGE> の一行でコンテナイメージの脆弱性を検出できます
  • コンテナイメージだけでなく trivy fs でソースコードや requirements.txt も検査できます
  • Ubuntu 24.04 への apt インストールは公式リポジトリを追加するだけで完了します(Trivy 0.71.0 を実測確認)
  • python:3.8-slim には CRITICAL 9件を含む計324件の脆弱性が存在することを実測で確認しました

コンテナで何かアプリを動かしていると、「このDockerイメージって安全なのかな?」と気になることがありますよね。ベースイメージのバージョンが古かったり、ライブラリに既知の脆弱性(CVE:公開された脆弱性に割り振られる識別番号)が含まれていたりするケースは珍しくありません。

そんなときに活躍するのが Trivy(トリビー)です。Aqua Security が開発したオープンソースの脆弱性スキャナーで、コンテナイメージ・ファイルシステム・Gitリポジトリ・設定ファイルなど幅広い対象に対応しています。コマンド一発でスキャンできるシンプルさも人気の理由です。

この記事では Ubuntu 24.04 LTS への Trivy のインストールから、実際にコンテナイメージをスキャンして脆弱性を検出するまでを、2026年6月14日に Docker 公式イメージ上で実際に実行した結果をもとに解説します。架空のコマンド出力ではなく、すべて手元で動かした本物の数字です。

動作確認済み環境

Ubuntu 24.04.4 LTS(Noble Numbat、公式 Docker イメージ)/ Trivy 0.71.0 / スキャンは aquasec/trivy:0.71.0 コンテナで実行。macOS・WSL2 上の Docker でも同様の手順で動作します。

目次

  1. Trivy とは?脆弱性スキャナーの役割
  2. Ubuntu 24.04 に Trivy をインストールする
  3. コンテナイメージをスキャンする
  4. 実測:複数イメージの脆弱性を比較した結果
  5. ファイルシステム・コードをスキャンする
  6. 出力形式と重大度フィルタリング
  7. よくあるエラーと解決策
  8. まとめ

Trivy とは?脆弱性スキャナーの役割

Trivy は Aqua Security が OSS として公開している脆弱性スキャナーです。GitHub のスター数は 3.6万以上(執筆時点で約36,400)で、CI/CD パイプラインへの統合にも広く使われています。

「脆弱性スキャナー」というと難しく聞こえますが、やっていることはシンプルです。イメージやコードに含まれるパッケージのバージョンを読み取って、既知の CVE データベースと照合するだけです。古いバージョンに既知の脆弱性があれば、それを一覧で教えてくれます。

Trivy の主要スキャンモード一覧(概念図)
Trivy の主要スキャンモード一覧(概念図)

Trivy が対応している主なスキャン対象は以下の通りです。

  • trivy image <IMAGE>:Docker などのコンテナイメージ
  • trivy fs <PATH>:ローカルのファイルシステム(ソースコード・requirements.txt 等)
  • trivy repo <GIT_URL>:Git リポジトリ(GitHub など)
  • trivy config <PATH>:Terraform・Kubernetes・Dockerfile などの設定ファイル

この記事では最もよく使う trivy imagetrivy fs を中心に解説します。

Ubuntu 24.04 に Trivy をインストールする

Trivy は Aqua Security の公式 apt リポジトリからインストールするのが推奨です。実際に ubuntu:24.04 の公式 Docker イメージ(24.04.4 LTS)で手順を実行して確認しました。

手順1:前提パッケージをインストールする




ubuntu@linuxlab: ~
$ sudo apt-get update
$ sudo apt-get install -y wget gnupg ca-certificates
Setting up wget …
Setting up gnupg …
Setting up ca-certificates …

手順2:Trivy の apt リポジトリを追加する

公式の署名鍵を /usr/share/keyrings/ に置き、リポジトリを sources.list.d に追加します。




ubuntu@linuxlab: ~
$ wget -qO – https://aquasecurity.github.io/trivy-repo/deb/public.key \
| gpg –dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
$ echo “deb [signed-by=/usr/share/keyrings/trivy.gpg] \
https://aquasecurity.github.io/trivy-repo/deb generic main” \
| sudo tee /etc/apt/sources.list.d/trivy.list
deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main

手順3:Trivy をインストールして動作確認する

リポジトリを更新してからインストールします。実測では apt-cache policy の Candidate が 0.71.0 と表示され、そのままインストールできました。




ubuntu@linuxlab: ~
$ sudo apt-get update && apt-cache policy trivy
trivy:
Installed: (none)
Candidate: 0.71.0
$ sudo apt-get install -y trivy
0 upgraded, 1 newly installed, 0 to remove and 5 not upgraded.
Setting up trivy (0.71.0) …
$ trivy –version
Version: 0.71.0
Ubuntu 24.04 で Trivy インストールを実測したターミナルログ
Ubuntu 24.04 で Trivy インストールを実測したターミナルログ

Version: 0.71.0」と表示されれば成功です。2026年6月14日時点で apt リポジトリが配布していた最新版は 0.71.0 でした。

Docker でインストールせずに使う方法もある

Ubuntu に直接インストールしなくても、docker run --rm aquasec/trivy image <IMAGE> でそのまま使えます。実はこの記事のスキャンも、すべて aquasec/trivy:0.71.0 コンテナを使って実行しました。ホストを汚したくない場合やサクッと試したい場合に便利です。

コンテナイメージをスキャンする

インストールできたら、まずコンテナイメージをスキャンしてみましょう。コマンドは非常にシンプルです。




ubuntu@linuxlab: ~
$ trivy image python:3.8-slim

初回実行時は CVE データベースを自動ダウンロードするため少し時間がかかります(筆者の環境では数十秒〜数分でした)。2回目以降は ~/.cache/trivy/ のキャッシュを使うので速くなります。

Trivy の公式ドキュメントにもスキャン対象ごとの詳しい使い方がまとまっています。

Trivy 公式ドキュメントのコンテナイメージスキャン解説ページ
Trivy 公式ドキュメントのコンテナイメージスキャン解説ページ

スキャンが完了すると、検出された脆弱性の件数と一覧が表示されます。実際に python:3.8-slim をスキャンした結果が次の図です。

python:3.8-slim をスキャンした実測結果
python:3.8-slim をスキャンした実測結果

今回スキャンした python:3.8-slim(Debian 12.7 ベース)では、CRITICAL 9件・HIGH 47件を含む計324件の脆弱性が検出されました。CRITICAL に分類された脆弱性の中には、次のような深刻なものが含まれていました。

  • CVE-2026-42010libgnutls30 の認証バイパス(ユーザー名に含まれるNUL文字による偽装)
  • CVE-2026-31789openssl / libssl3 のヒープバッファオーバーフロー(巨大なX.509証明書の処理、32bit環境で危険)
  • CVE-2025-6965libsqlite3-0 の整数切り捨て(Integer Truncation)

古いバージョンのイメージを使い続けることのリスクが、数字としてはっきり見えてきますね。

実測:複数イメージの脆弱性を比較した結果

「どのイメージが安全で、どのイメージが危ないのか」を知るために、4種類の公式イメージを同じ条件(trivy image --scanners vuln)でまとめてスキャンしました。

複数コンテナイメージの脆弱性件数比較(実測)
複数コンテナイメージの脆弱性件数比較(実測)

結果をまとめると次のようになります。

イメージ ベースOS CRITICAL HIGH MEDIUM LOW 合計
alpine:3.18 Alpine 3.18.12 0 0 0 0 0
ubuntu:24.04 Ubuntu 24.04 0 1 37 13 51
ubuntu:22.04 Ubuntu 22.04 0 1 32 28 61
python:3.8-slim Debian 12.7 9 47 130 137 324

実測で特に印象的だったのは alpine:3.18 がゼロ件だったことです。Alpine Linux はセキュリティ重視の軽量ディストリビューションとして設計されており、最小限のパッケージしか含まないため OS パッケージの既知CVEが非常に少ないことが、改めて数字で確認できました。なお合計には UNKNOWN 重大度を含むため、python:3.8-slim の324件には UNKNOWN 1件が含まれています。

python:3.8-slim の脆弱性 重大度別内訳(実測)
python:3.8-slim の脆弱性 重大度別内訳(実測)

一方、python:3.8-slim は Debian Bookworm(12.7)をベースにしていますが、Python 3.8 は2024年10月にサポートが終了しており、ベースに含まれる OS パッケージにも多数のCVEが残っています。本番環境で使い続けるのは避けた方がよいでしょう。

著者アイコン
著者アイコン

「MEDIUM や LOW は無視していい?」とよく聞かれます。今すぐ全部の対応が難しいなら、まず CRITICAL と HIGH に絞って対応するのが現実的です。trivy image --severity CRITICAL,HIGH <IMAGE> でフィルタリングできますよ。

ファイルシステム・コードをスキャンする

Trivy はコンテナイメージだけでなく、ローカルのソースコードディレクトリや依存関係ファイルもスキャンできます。

①Pythonプロジェクトをスキャンする

requirements.txt(または Pipfile.lock)を含むプロジェクトなら、ディレクトリを指定するだけで自動検出してスキャンしてくれます。今回は意図的に古いバージョンを書いた requirements.txt を用意して、実際にスキャンしてみました。




ubuntu@linuxlab: ~/myproject
$ cat requirements.txt
django==3.2.0
requests==2.25.1
Flask==1.1.1
PyYAML==5.3
Jinja2==2.11.2
$ trivy fs –scanners vuln .
requirements.txt (pip)
Total: 43 (CRITICAL: 8, HIGH: 16, MEDIUM: 18, LOW: 1)
requirements.txt のファイルシステムスキャン結果(実測)
requirements.txt のファイルシステムスキャン結果(実測)

実際にスキャンしてみると、django==3.2.0 には CVE-2021-35042QuerySet.order_by() 経由のSQLインジェクション)をはじめ複数の CRITICAL が含まれており、PyYAML==5.3 には CVE-2020-1747FullLoader 使用時の任意コマンド実行)、Flask==1.1.1 には CVE-2023-30861(永続セッションクッキーの漏洩リスク)が検出されました。依存ライブラリの古いバージョンがいかに危険か、よく分かります。

②Node.js / npm プロジェクトをスキャンする

package-lock.jsonyarn.lock を持つ Node.js プロジェクトも、同じく trivy fs でスキャンできます。




ubuntu@linuxlab: ~/nodeapp
$ trivy fs –scanners vuln .
package-lock.json (npm)
# 検出された脆弱性が重大度別に一覧表示される

requirements.txtpackage-lock.jsonpom.xmlgo.sum など、主要な言語のロックファイルを自動判別してくれるのが便利なところです。

出力形式と重大度フィルタリング

①重大度でフィルタリングする

大量の結果が出てきて見づらい場合は、--severity オプションで絞り込みます。




ubuntu@linuxlab: ~
$ trivy image –severity CRITICAL,HIGH python:3.8-slim
python:3.8-slim (debian 12.7)
Total: 56 (HIGH: 47, CRITICAL: 9)

先ほどの全件スキャンと突き合わせると、324件のうち CRITICAL 9件・HIGH 47件(合計56件)だけが残り、まず対応すべき脆弱性が一目で分かります。

②JSON 形式で出力して自動処理する

CI/CD パイプラインや他のツールと連携する場合は、JSON 形式で出力するのが便利です。実際、この記事の集計も --format json の出力を解析して作りました。




ubuntu@linuxlab: ~
$ trivy image –format json –output result.json python:3.8-slim
# result.json に脆弱性の詳細がJSON形式で保存される
$ cat result.json | python3 -c “import json,sys; d=json.load(sys.stdin); print(len(d[‘Results’]))”
2

③GitHub Actions / CI/CD に組み込む

Trivy は公式の GitHub Actions が提供されており、プルリクエストのたびに自動スキャンさせることができます。GitHub リポジトリ(スター3.6万超)からも、対応の活発さがうかがえます。

Trivy 公式 GitHub リポジトリ(aquasecurity/trivy)
Trivy 公式 GitHub リポジトリ(aquasecurity/trivy)



.github/workflows/trivy.yml
– name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ‘python:3.8-slim’
format: ‘sarif’
exit-code: ‘1’ # CRITICAL 検出時にCIを失敗させる
severity: ‘CRITICAL,HIGH’

exit-code: '1' を設定しておくと、CRITICAL が検出された場合に CI を失敗させて本番デプロイをブロックできます。セキュリティゲートとして機能させるのに効果的です。

よくあるエラーと解決策

①「unable to initialize an image source」が出る

指定したイメージ名が間違っているか、Docker デーモンが起動していない場合に出るエラーです。




ubuntu@linuxlab: ~
FATAL image scan error: unable to initialize an image source
$ docker ps # Dockerが動いているか確認
$ trivy image nginx:latest # タグ指定で再試行

②初回スキャンがとても遅い

初回は CVE データベースをダウンロードするので時間がかかることがあります。2回目以降はキャッシュが効くので速くなります。キャッシュは ~/.cache/trivy/ に保存されます。CI で毎回ダウンロードしたくない場合は、このディレクトリをキャッシュ対象にしておくと高速化できます。

③「certificate signed by unknown authority」が出る

プロキシ環境やVPN環境で証明書の検証に失敗する場合があります。




ubuntu@linuxlab: ~
$ trivy image –insecure nginx:latest # 自己署名証明書環境での回避策(本番非推奨)

注意

--insecure は開発・テスト環境での一時的な回避策です。本番環境では証明書を適切に設定してから使いましょう。

まとめ

今回は Ubuntu 24.04 LTS に Trivy 0.71.0 をインストールし、実際にコンテナイメージとファイルシステムをスキャンした結果を紹介しました。

  • Trivy は公式リポジトリを追加して sudo apt-get install trivy を実行するだけで Ubuntu 24.04 に簡単にインストールできます
  • コンテナイメージのスキャンは trivy image <IMAGE> の一行で完結します
  • 実測では python:3.8-slim に CRITICAL 9件を含む計324件の脆弱性を確認。alpine:3.18 はゼロ件でクリーンでした
  • ソースコードの依存関係(requirements.txt 等)は trivy fs でスキャンでき、django 3.2.0 などに CRITICAL が見つかりました
  • CI/CD に組み込む場合は exit-code 1 と severity CRITICAL,HIGH でデプロイゲートとして機能させるのがおすすめです

定期的にイメージをスキャンして脆弱性をキャッチする習慣をつけると、セキュリティリスクを早期に発見できるようになります。まずは今使っているコンテナイメージに対して trivy image を一度実行してみてください。

VPS 上で本格的なコンテナ環境を構築したい場合は、以下の記事も参考にしてください。

[LINK_X_ARTICLE]

コメント

タイトルとURLをコピーしました