言語を切り替える
テーマを切り替える

Dockerイメージセキュリティスキャンと修正:Trivy実践チュートリアルとCI/CD統合ガイド

"緑盟科技(NSFOCUS)の2018年3月の研究レポートによると、Docker Hubから無作為に抽出したイメージの4分の3以上(76%)に既知のセキュリティ脆弱性が存在しました。"

— NSFOCUS Research Report

2021年12月10日未明、監視モニターの警告グラフが跳ね上がったのを見て、私は手にしたコーヒーをこぼしそうになりました。運用グループチャットは騒然としており、誰かがCVE番号を投稿しました:CVE-2021-44228。後に技術界を震撼させた「Log4Shell」脆弱性です。

さらに深刻だったのは、我々の十数個のマイクロサービスが、この脆弱性を含むベースイメージを使用していたことでした。その夜、チーム全員で緊急のイメージ更新と再デプロイを行い、徹夜で作業しました。事後分析でボスが放った一言に全員が沈黙しました。「なぜ自分たちが使っているイメージの脆弱性を誰も知らなかったんだ?」

これは多くのチームが抱える痛点です。NSFOCUSの研究によれば、Docker Hub上のイメージの76%に既知の脆弱性があります。あなたが使っている python:3.9nginx:latest にも、気づかないだけで数十個のCVEが潜んでいるかもしれません。

この記事では、私が2年間の本番運用で学んだ、以下のノウハウを共有します:

  • Trivyなどのツールを使ってDockerイメージの脆弱性を高速スキャンする方法
  • 単に「バージョンアップ」するだけではない、体系的な脆弱性修正手法
  • GitHub ActionsやGitLab CIなどのCI/CDパイプラインへの自動スキャン統合

Dockerイメージのセキュリティ脅威の全貌

そもそも何が危ないのか?

「イメージなんてただのパッケージでしょ?」と思っていませんか? 実際にスキャンしてみると、脅威はいくつかのカテゴリに分かれます。

  1. OSパッケージ脆弱性: AlpineやUbuntuなどのベースイメージに含まれる OpenSSL, glibc, curl などのシステムライブラリの脆弱性です。
  2. アプリケーション依存関係の脆弱性: Pythonの pip や Node.jsの npm で入れたライブラリの脆弱性。Log4jもこれに該当します。
  3. 設定ミスと機密情報の漏洩: DockerfileにDBパスワードを直書きしたり、.git ディレクトリを消し忘れたり、rootユーザーで実行したりするケースです。
  4. サプライチェーン攻撃: Docker Hubにある一見無害なイメージに、マイニングツールやバックドアが仕込まれているケースです。

なぜDocker Hubを盲信してはいけないのか?

「公式」タグが付いていても、それが最新とは限りません。python:3.9 タグが付いたイメージが半年前にビルドされたものであれば、その間のOSパッチは当たっていません。Docker Hub上のイメージは品質がバラバラで、統一された監査基準もありません。

私の原則はこれです:「Docker Hubからプルしたイメージは、公式であっても必ずスキャンしてから使う」。

スキャンツールの選択:Trivy一択の理由

Trivy: 最も推奨されるOSSツール

市場にはSnyk, Clair, Anchoreなど多くのツールがありますが、私はTrivyを強く推奨します。理由は「使いやすさ」と「機能」のバランスが絶妙だからです。

  • 高速: 数百MBのイメージでも数秒〜十数秒で終わります。
  • 多機能: OSパッケージ、アプリ依存ライブラリ、設定ミス(IaC)、秘密鍵検出、ライセンス違反までチェックできます。
  • 統合済み: GitHub ActionsやHarborなどの主要プラットフォームですでに統合されています。

Trivy実践チュートリアル

インストールと基本操作

Macなら brew install trivy 一発です。Linuxならバイナリを落とすだけです。

# Docker Hubのイメージをスキャン
trivy image python:3.9

# ローカルでビルドしたイメージをスキャン
trivy image myapp:latest

実践的なオプション

実務では、すべての脆弱性を見る必要はありません。ノイズを減らしましょう。

重要度でフィルタリング:

trivy image --severity HIGH,CRITICAL nginx:latest

CI/CDでは CRITICAL(深刻)と HIGH(高)だけに対応するのが現実的です。

修正済みのみ表示:

trivy image --ignore-unfixed redis:latest

まだパッチが出ていない脆弱性を知らされても対応しようがありません。このオプションで「今直せるもの」に集中できます。

CI/CD用(エラーステータスを返す):

trivy image --exit-code 1 --severity CRITICAL myapp:latest

深刻な脆弱性が見つかった場合、コマンドがエラー終了(exit code 1)します。これでビルドを失敗させ、危険なイメージのデプロイを阻止できます。

脆弱性の体系的な修正方法

1. 適切なベースイメージを選ぶ

脆弱性を「直す」より「避ける」方が賢明です。Alpine Linuxは小さいですが、互換性問題もあります。最近のおすすめは Googleの Distroless です。

# Pythonアプリ用
FROM gcr.io/distroless/python3

# Node.jsアプリ用
FROM gcr.io/distroless/nodejs

Distrolessにはシェルもパッケージマネージャもありません。つまり、ハッカーが侵入してもコマンドを実行する手段がほとんどなく、攻撃対象領域(Attack Surface)が極小化されます。

2. ベースイメージの更新

FROM python:3.9 ではなく FROM python:3.9.18 のように具体的に指定し、定期的に最新のパッチバージョンに上げましょう。「latest」タグは便利ですが、中身がいつのものかわからないため、本番環境では避けるべきです。

3. Dockerfileでのパッケージ更新

ベースイメージが古くても、ビルド時にOSパッケージを最新化できます。

FROM ubuntu:22.04
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

4. アプリ依存ライブラリの更新

requirements.txtpackage.json のバージョンを上げます。ただし、破壊的変更(Breaking Changes)には注意してください。

CI/CDへの統合:自動化されたゲートキーパー

GitHub Actions

.github/workflows/docker-scan.yml を作成します。

name: Docker Security Scan
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .
      
      - name: Run Trivy scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'myapp:${{ github.sha }}'
          format: 'table'
          exit-code: '1'
          ignore-unfixed: true
          severity: 'CRITICAL,HIGH'

これで、コードをプッシュするたびに自動スキャンが走り、深刻な脆弱性があればマージをブロックできます。

Harborによる二重防御

企業で利用されるコンテナレジストリ Harbor には、Trivyが内蔵されています。「プッシュ時に自動スキャン」を有効にし、「重大な脆弱性があるイメージのプルを禁止」するポリシーを設定すれば、CI/CDをすり抜けたイメージも水際で阻止できます。

まとめ:完璧を目指さず、運用で回す

  1. 今日中に: ローカルにTrivyを入れて、自社の主要イメージをスキャンしてみる。
  2. 今週中に: CRITICALな脆弱性だけでも修正(ベースイメージ更新)する。
  3. 来週以降: CI/CDに組み込み、自動化する。

セキュリティは一度きりのイベントではなく、継続的なプロセスです。スキャンを日常業務に組み込むことで、枕を高くして眠れるようになります。

Dockerイメージセキュリティスキャン完全フロー

TrivyのインストールからCI/CD統合、修正までのステップバイステップガイド

⏱️ Estimated time: 2 hr

  1. 1

    Step1: Trivyのインストール

    macOSなら `brew install trivy`、LinuxならGitHub Releasesからバイナリを取得してインストールします。初回実行時にDBをダウンロードします。
  2. 2

    Step2: 現状のスキャン

    `trivy image myapp:latest` で現在のイメージをスキャンし、脆弱性の現状を把握します。
  3. 3

    Step3: 重要度によるフィルタリング

    `--severity HIGH,CRITICAL --ignore-unfixed` オプションを使い、修正可能かつ危険度の高い脆弱性に絞ってリストアップします。
  4. 4

    Step4: 脆弱性の修正

    ベースイメージを最新版(またはDistroless)に変更し、OSパッケージとアプリ依存ライブラリを更新して再ビルドします。
  5. 5

    Step5: CI/CDへの組み込み

    GitHub ActionsなどにTrivyステップを追加し、`mid` `exit-code 1` を設定して、脆弱性がある場合にビルドを失敗させるようにします。

FAQ

Docker Hubの公式イメージなら安全ですか?
いいえ、必ずしも安全ではありません。公式イメージでも更新頻度によっては古いパッケージが含まれていることがあります。使用前には必ずスキャンすることを推奨します。
Trivyで大量の脆弱性が見つかりました。どうすればいいですか?
まずは `--ignore-unfixed` で修正パッチが存在しないものを除外し、`--severity CRITICAL,HIGH` で重要度の高いものに絞り込んでください。それらを優先的に対応し、ベースイメージの変更(AlpineやDistrolessへの移行)も検討してください。
CI/CDでスキャンすると時間がかかりますか?
Trivyは非常に高速で、通常のスキャンは数秒から数十秒で完了します。CI/CDパイプライン全体の時間に与える影響は軽微です。

4 min read · 公開日: 2025年12月18日 · 更新日: 2026年1月22日

コメント

GitHubアカウントでログインしてコメントできます

関連記事