Dockerイメージセキュリティスキャンと修正:Trivy実践チュートリアルとCI/CD統合ガイド
"緑盟科技(NSFOCUS)の2018年3月の研究レポートによると、Docker Hubから無作為に抽出したイメージの4分の3以上(76%)に既知のセキュリティ脆弱性が存在しました。"
2021年12月10日未明、監視モニターの警告グラフが跳ね上がったのを見て、私は手にしたコーヒーをこぼしそうになりました。運用グループチャットは騒然としており、誰かがCVE番号を投稿しました:CVE-2021-44228。後に技術界を震撼させた「Log4Shell」脆弱性です。
さらに深刻だったのは、我々の十数個のマイクロサービスが、この脆弱性を含むベースイメージを使用していたことでした。その夜、チーム全員で緊急のイメージ更新と再デプロイを行い、徹夜で作業しました。事後分析でボスが放った一言に全員が沈黙しました。「なぜ自分たちが使っているイメージの脆弱性を誰も知らなかったんだ?」
これは多くのチームが抱える痛点です。NSFOCUSの研究によれば、Docker Hub上のイメージの76%に既知の脆弱性があります。あなたが使っている python:3.9 や nginx:latest にも、気づかないだけで数十個のCVEが潜んでいるかもしれません。
この記事では、私が2年間の本番運用で学んだ、以下のノウハウを共有します:
- Trivyなどのツールを使ってDockerイメージの脆弱性を高速スキャンする方法
- 単に「バージョンアップ」するだけではない、体系的な脆弱性修正手法
- GitHub ActionsやGitLab CIなどのCI/CDパイプラインへの自動スキャン統合
Dockerイメージのセキュリティ脅威の全貌
そもそも何が危ないのか?
「イメージなんてただのパッケージでしょ?」と思っていませんか? 実際にスキャンしてみると、脅威はいくつかのカテゴリに分かれます。
- OSパッケージ脆弱性: AlpineやUbuntuなどのベースイメージに含まれる OpenSSL, glibc, curl などのシステムライブラリの脆弱性です。
- アプリケーション依存関係の脆弱性: Pythonの
pipや Node.jsのnpmで入れたライブラリの脆弱性。Log4jもこれに該当します。 - 設定ミスと機密情報の漏洩: DockerfileにDBパスワードを直書きしたり、
.gitディレクトリを消し忘れたり、rootユーザーで実行したりするケースです。 - サプライチェーン攻撃: 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.txt や package.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をすり抜けたイメージも水際で阻止できます。
まとめ:完璧を目指さず、運用で回す
- 今日中に: ローカルにTrivyを入れて、自社の主要イメージをスキャンしてみる。
- 今週中に: CRITICALな脆弱性だけでも修正(ベースイメージ更新)する。
- 来週以降: CI/CDに組み込み、自動化する。
セキュリティは一度きりのイベントではなく、継続的なプロセスです。スキャンを日常業務に組み込むことで、枕を高くして眠れるようになります。
Dockerイメージセキュリティスキャン完全フロー
TrivyのインストールからCI/CD統合、修正までのステップバイステップガイド
⏱️ 目安時間: 2 時間
- 1
ステップ1: Trivyのインストール
macOSなら `brew install trivy`、LinuxならGitHub Releasesからバイナリを取得してインストールします。初回実行時にDBをダウンロードします。 - 2
ステップ2: 現状のスキャン
`trivy image myapp:latest` で現在のイメージをスキャンし、脆弱性の現状を把握します。 - 3
ステップ3: 重要度によるフィルタリング
`--severity HIGH,CRITICAL --ignore-unfixed` オプションを使い、修正可能かつ危険度の高い脆弱性に絞ってリストアップします。 - 4
ステップ4: 脆弱性の修正
ベースイメージを最新版(またはDistroless)に変更し、OSパッケージとアプリ依存ライブラリを更新して再ビルドします。 - 5
ステップ5: CI/CDへの組み込み
GitHub ActionsなどにTrivyステップを追加し、`mid` `exit-code 1` を設定して、脆弱性がある場合にビルドを失敗させるようにします。
FAQ
Docker Hubの公式イメージなら安全ですか?
Trivyで大量の脆弱性が見つかりました。どうすればいいですか?
CI/CDでスキャンすると時間がかかりますか?
4 min read · 公開日: 2025年12月18日 · 更新日: 2026年4月20日
Docker 実践ガイド
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
DockerでNginx構築完全ガイド:設定ファイルのマウントからHTTPS化まで
「設定を変えたのに反映されない」トラブルを解決。DockerでNginxを動かす際の正しいconfマウント方法、SSL証明書(Let's Encrypt)の自動更新、そしてDocker Composeを使ったリバースプロキシ設定までを徹底解説。
第 24 / 32 記事
次の記事
Docker安全認証:コンテナをrootで実行しないための完全実践ガイド
Dockerコンテナをデフォルトのrootで動かすのは深刻なセキュリティリスクです。コンテナ脱出の仕組みから、DockerfileでのUSER命令、--userパラメータ、Capabilitiesによる権限管理、AppArmor設定まで、本番環境レベルのセキュリティ対策を解説します。
第 26 / 32 記事
関連記事
Dockerfile入門ガイド:ゼロから作る最初のDockerイメージ(実例付き)
Dockerfile入門ガイド:ゼロから作る最初のDockerイメージ(実例付き)
Docker vs 仮想マシン:5分でわかる性能差と選び方
Docker vs 仮想マシン:5分でわかる性能差と選び方
Dockerインストール完全ガイド2025:Permission Deniedから成功までの全手順
コメント
GitHubアカウントでログインしてコメントできます