✏️

Dockerコンテナの静的解析と脆弱性スキャン:調査・実験

に公開

はじめに

昨今は開発中にDockerで環境を作ることが多くなっています。
しかしながら実際にベストプラクティスに準拠した記載や、脆弱性のないコンテナイメージを作成するのにはハードルがあります。
今回は、そのハードルを下げるためのチェックツールについて調査します。

実験環境:

  • Docker Desktop 4.46.0 (204649)
  • macOS 15.4.1
  • 2 GHz クアッドコアIntel Core i5

今回の調査対象は以下の通りです。

名称 チェック対象 チェック内容 備考
hadolint Dockerfile ベストプラクティスLint VS Code拡張・CI連携あり
Dockle Image ベストプラクティス & CIS Docker Image ベンチマーク準拠の設定/内容チェック CVEデータベース照合などのセキュリティチェックは対象外
Trivy Dockerfile/Image CVE脆弱性 / 設定 / Secrets / ライセンスのチェック リポジトリやVMを対象としたチェックもあり
Snyk Image CVE脆弱性、独自の脆弱性チェック アプリやリポジトリの脆弱性も可能
Docker Scout Image CVE脆弱性 Docker Desktopにプリインストール
GUIから操作可能
DockerDX Dockerfile Lint/補完/ヒント VS Code拡張機能

hadolint

hadolintはDockerfileのリンターとして動作し、ベストプラクティスに準拠した記載を補助します。
具体的にチェックするルールについてはRulesを参照してください。

GitHubの状況

  • Star: 11.5K
  • 最終コミット: 2025/09/22
    2025/09/25時点

使用例

macOSにインストールする場合

# macOsにインストール
brew install hadolint
# Dockerfileを指定して実行
hadolint Dockerfile 

その他のOSにインストールする場合は Install を参照

dockerコンテナを利用してチェック

docker run --rm -i hadolint/hadolint < ./Dockerfile

対象のDockerfile

FROM fukamachi/sbcl:latest
RUN apt-get update && apt-get install -y --no-install-recommends git patch && rm -rf /var/lib/apt/lists/*
WORKDIR /app
ARG GIT_REF=89178b1ae0373313db86d895c4c7265407bd3c40
RUN git clone https://github.com/jeffshrager/IPL-V.git .
RUN git fetch origin ${GIT_REF} --depth=1
RUN git checkout -qf ${GIT_REF}
COPY src/j100-h5-stop.patch /app/j100-h5-stop.patch
RUN patch -p0 < /app/j100-h5-stop.patch 

警告例

-:1 DL3007 warning: Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
-:2 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
-:6 DL3059 info: Multiple consecutive `RUN` instructions. Consider consolidation.
-:7 DL3059 info: Multiple consecutive `RUN` instructions. Consider consolidation.

設定ファイル

yaml形式でチェック方法を設定できます。

# 無視するエラーが設定可能
ignored:
  - DL3000
  - SC1010
# 出力レベルの調整が可能
failure-threshold: warning
# エラーレベルの変更が可能
override:
  error:
    - DL3001
    - DL3002
  warning:
    - DL3042
    - DL3033
  info:
    - DL3032
  style:
    - DL3015
# 信頼するリポジトリを選べる
trustedRegistries:
  - docker.io
# LABELが設定されているかを調べる
strict-labels: true
label-schema:
  org.opencontainers.image.source: url
  org.opencontainers.image.version: semver
  org.opencontainers.image.revision: hash

設定ファイルは特定のフォルダに配置するか、--config引数で設定できます。

hadolint --config=./.hadolint.yaml ./Dockerfile; echo $?
  • failure-threshold
    • 出力が抑制されるわけでなく、最後のエラーコードをどうするかの設定
    • 前述のサンプルではecho $?が1を出すか0を出すかの判断基準
  • trustedRegistries
    • ここで指定したリポジトリ以外からFROMした場合はエラーとなる。
    • リポジトリ単位なので、公式のイメージのみを取得するという使い方はできない
  • strict-labels
    • trueの場合、label-schemaに記載していないラベルの使用を認めない
  • label-schema

詳細はConfigureを参照してください。

エラー無視の方法

  • configでignoredを設定する
  • コマンドライン引数で--ignoreを使用する。これは複数設定できる
  • Dockerfileにコメントを付与する

行ごとに設定する方法

...
# hadolint ignore=DL3059,DL3060
RUN git fetch origin ${GIT_REF} --depth=1
...

ファイル全体を設定する方法

# hadolint global ignore=DL3059,DL3060
FROM fukamachi/sbcl:latest
...

VS Codeとの連携

Michael Lin氏のhadolintでVS Codeとの連携が可能です。
https://marketplace.visualstudio.com/items?itemName=exiasr.hadolint

その他のEditorについてはINTEGRATION.mdを参照してください。

所見

ツールとしてシンプルでわかりやすいです。
また、実行速度にもストレスを感じないため、無条件で導入して問題ないツールかと思います。

Dockle

Dockleはコンテナイメージに対してBest PracticeCISベンチマークに基づく設定のチェックを実施します。

具体的にチェックする内容については Checkpoint Detailsを参照してください。

GitHubの状況

  • Star: 3.1K
  • 最終コミット: 2025/01/06
    2025/09/25時点

使用例

macOSにインストールする場合

# macOsにインストール
brew install goodwithtech/r/dockle
# image:tagを選択してイメージをチェックする。
# Docker Desktopの場合はdockerデーモンへの接続情報を--hostで渡す必要がある
dockle --host unix://$HOME/.docker/run/docker.sock iplv-iplv:latest

他のOSにインストールする場合は Installation を参照してください。

dockerコンテナを利用してチェック

docker run -v ~/.docker/run/docker.sock:/var/run/docker.sock --rm goodwithtech/dockle iplv-iplv:latest

警告例:

 iplv-iplv:latest
WARN    - CIS-DI-0001: Create a user for the container
        * Last user should not be root
WARN    - DKL-DI-0006: Avoid latest tag
        * Avoid 'latest' tag
INFO    - CIS-DI-0005: Enable Content trust for Docker
        * export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO    - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
        * not found HEALTHCHECK statement
INFO    - CIS-DI-0008: Confirm safety of setuid/setgid files
        * setuid file: urwxr-xr-x usr/bin/newgrp
        * setuid file: urwxr-xr-x usr/bin/chsh
        * setgid file: grwxr-xr-x usr/bin/expiry
        * setuid file: urwxr-xr-x usr/bin/chfn
        * setuid file: urwxr-xr-x usr/bin/mount
        * setuid file: urwxr-xr-x usr/bin/gpasswd
        * setgid file: grwxr-xr-x usr/sbin/unix_chkpwd
        * setuid file: urwxr-xr-x usr/bin/umount
        * setgid file: grwxr-xr-x usr/bin/chage
        * setuid file: urwxr-xr-x usr/bin/su
        * setuid file: urwxr-xr-x usr/bin/passwd
INFO    - DKL-LI-0003: Only put necessary files
        * Suspicious directory : app/.git

エラー無視の方法

--ignore引数を使うか、DOCKLE_IGNORES環境変数を使うか、.dockleignoreファイルを使います。

# --ignore引数の利用例(-iでも可)
% dockle --host unix://$HOME/.docker/run/docker.sock --ignore CIS-DI-0001 --ignore CIS-DI-0006 iplv-iplv:latest
or
% dockle --host unix://$HOME/.docker/run/docker.sock -i CIS-DI-0001 -i CIS-DI-0006 iplv-iplv:latest

# DOCKLE_IGNORES環境変数の例
DOCKLE_IGNORES=CIS-DI-0001,CIS-DI-0006 dockle --host unix://$HOME/.docker/run/docker.sock iplv-iplv:latest 

# 例: CIS-DI-0001を無視するファイルの例
% cat .dockleignore
CIS-DI-0001

所見

ECRやGCRなどのクラウド上のリポジトリに対してもチェックできる点が魅力です。

一方、トラブル時の対応が難しい場面もあります。たとえば、以下のエラーが発生したケースは--hostを付与するか、docker起動時に-vを使用してdocker daemon hostを設定する必要がありますが、この回答にたどりつくまで時間がかなりかかりました。

2025-09-25T22:49:19.524+0900    DEBUG   There is no .dockleignore file
2025-09-25T22:49:19.524+0900    DEBUG   Skipped update confirmation
2025-09-25T22:49:19.524+0900    DEBUG   Start assessments...
2025-09-25T22:49:22.093+0900    FATAL   unable to initialize a image struct:
    github.com/goodwithtech/deckoder/extractor/docker.newDockerExtractor
        /home/runner/go/pkg/mod/github.com/goodwithtech/deckoder@v0.0.6/extractor/docker/docker.go:73
  - failed to initialize source:
    github.com/goodwithtech/deckoder/extractor/image.NewImage
        /home/runner/go/pkg/mod/github.com/goodwithtech/deckoder@v0.0.6/extractor/image/image.go:86
  - reading manifest latest in docker.io/library/iplv-iplv: requested access to the resource is denied

他のイメージをチェックするツールとの兼ね合いで採用を検討するのが望ましいと思います。

Trivy

TrivyはコンテナイメージやGitリポジトリなどを対象に脆弱性や誤った設定などをチェックします。

チェック対象

チェック内容

GitHubの状況

  • Star: 29.1K
  • 最終コミット: 2025/09/25
    2025/09/25時点

使用例

macOSにインストールする場合

brew install trivy

# Dockerファイルの設定を確認
trivy config Dockerfile

# Imageのチェック (vuln,secretのみチェックする)
trivy image iplv-iplv:latest
# 全部チェック
trivy image --scanners vuln,misconfig,secret,license iplv-iplv:latest

configの出力例

imageの出力例

その他のOSにインストールする場合は Installing Trivy を参照してください。

dockerコンテナを利用してチェック

docker run -v ~/.docker/run/docker.sock:/var/run/docker.sock --rm aquasec/trivy image --scanners vuln,misconfig,secret,license iplv-iplv:latest

レポート

--severityフラグを使用することでレポートの対象のエラーを調整できます。

HIGHとCRITICALのみレポートする

trivy image --severity HIGH,CRITICAL iplv-iplv:latest

-fフラグを使用して以下のいずれかの形式で出力が可能です。

  • table
  • json
  • template
  • sarif
  • cyclonedx
  • spdx
  • spdx-json
  • github
  • cosign-vuln

JSONでレポートする

trivy image -f json iplv-iplv:latest

-oフラグを使用してレポートの出力先を指定できます。

JSONファイルで結果を保存する

trivy image -f json -o test.json iplv-iplv:latest

詳細は以下を参照してください。
Reporting

所見

コンテナイメージだけのチェックだけでなく幅広い箇所のチェックを実施しています。
今回調査した時間内では調べきれないほどの多機能で特に、CloudFormationのチェックや設定ミスについて自由にカスタマイズしたルールを作れる点には魅力を感じます。

Snyk

Snykは商用のセキュリティチェックツールです。アプリ開発時にコードの脆弱性チェックとしては素晴らしいツールですが、それだけでなくコンテナイメージの脆弱性チェックも可能です。

ユーザー登録を行うことで、無料枠で一定回数テストがおこなえます。詳細は以下を参照してください。
https://snyk.io/jp/plans/

使用例

snyk-cliをインストールします

snyk authコマンドを使用して認証を実施します

snyk container testコマンドを利用してコンテナのテストを実施します。

# DOCKER_HOSTにdockerのデーモンを指定してsnyk containerを実行
DOCKER_HOST=unix://$HOME/.docker/run/docker.sock snyk container test iplv-iplv:latest

詳細はContainer test
を参照してください。

実行例

GitHubの状況

  • Star: 5.2K
  • 最終コミット: 2025/09/25
    2025/09/25時点

所見

アプリの脆弱性のチェックと合わせて使用を検討する価値があります。
料金については料金プランを参照してください。

Docker Scout

Docker ScoutはDocker社公式の脆弱性チェックツールです。
Docker Desktopを使用する場合はプリインストールされています。

Docker Desktopからの実行例

Docker DesktopのDocker Scoutタブを選択します。
その後、イメージを選択して「Analyze image」ボタンを押下します。

脆弱性チェックの結果が出力されます。

View packages のリンクを辿ると詳細が出力されます。

CUIからの実行例

# 脆弱性の要約
docker scout quickview
# 詳細
docker scout cves

quickviewの出力例

cvesの出力例

所見

Docker Desktopを使用している場合は、プリインストールされていて、GUI上からチェックできるのが強みかと思います。

DockerDX

DockerDXはDocker社公式のVS Codeの拡張機能で、lint機能やコード保管をおこなってくれます。

詳細は以下のページを参照してください。
https://www.docker.com/ja-jp/blog/docker-dx-extension-for-vs-code/
https://www.docker.com/ja-jp/blog/docker-dx-extension-for-vs-code-update/

所見

リリース直後にユーザーから低評価を受けた経緯があります。
勝手にインストールされたり、動作が不安定だったことが原因のようです。
炎上直後の低評価を削除するという力技で現在の評価は3にまで回復しています。

クラウド上のコンテナの脆弱性チェック

AWS ECRやGoogle CloudのArtifact Registryを使用している場合、脆弱性チェック用のサービスが提供されているので使用を検討すべきでしょう。

AWS: ECR

AWSは2種類の脆弱性のスキャンを提供しています。

Basic scanningはOSの脆弱性を中心にチェックします。手動あるいはPush時にスキャンを行います。

Enhanced scanningはAmazon Inspectorと連携して、OS+言語パッケージ脆弱性、継続スキャンや再スキャンを提供します。価格についてはAmazon Inspectorの料金を参照してください。

保存するイメージ数を制限すれば、異常な価格にはならない想定です。

Google Cloud: Artifact Registry

Artifact Analysisの機能としてコンテナ イメージの脆弱性自動スキャンを実施します。

以下のように記載があるので、新しい脆弱性には追従する想定です。

スキャン プロセスは、新しいイメージを Artifact Registry または Container Registry(非推奨)に push するたびに自動的にトリガーされます。脆弱性情報は、新しい脆弱性が発見されるたびに更新されます

参考

まとめ

今回はDockerの品質を確保するためのチェックツールをいくつか調査しました。
おそらく、どれか一つで全てを解決するのは難しいので、いくつかのツールを組み合わせて使用することになるかと思います。

Discussion