kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Trivy の Misconfiguration Scanning で Dockerfile の設定ミスを検出しよう

Trivy の「Misconfiguration Scanning」を使うと Dockerfile の設定ミス(セキュリティ課題やベストプラクティス乖離など)を検出できる❗️今回は Trivy を活用した Dockerfile のスキャンを試した作業ログをまとめる📝

aquasecurity.github.io

ちなみに Trivy の Misconfiguration Scanning は Terraform, AWS CloudFormation など複数のスキャンをサポートしている.Trivy x Terraform を試した記事は前に公開してあって,Trivy の設定や GitHub Actions ワークフローなどはほぼ同じで OK👌

kakakakakku.hatenablog.com

どんなルールがあるのか

以下の Vulnerability Database で確認できる.現時点では「26種類」がサポートされている👏

  • Least Privilege User
  • No Dist Upgrade
  • No Duplicate Alias
  • No Healthcheck
  • No Maintainer
  • No Orphan Package Update
  • No Self Referencing Copy From
  • No Ssh Port
  • No Sudo Run
  • Only One Cmd
  • Only One Entrypoint
  • Only One Healthcheck
  • Port Out Of Range
  • Purge Apk Package Cache
  • Purge Dnf Package Cache
  • Purge Microdnf Package Cache
  • Purge Yum Package Cache
  • Purge Zipper Cache
  • Standardise Remote Get
  • Use Apt Auto Confirm
  • Use Apt No Install Recommends
  • Use Copy Over Add
  • Use Slash For Copy Args
  • Use Specific Tags
  • Use Workdir Over Cd
  • User Absolute Workdir

avd.aquasec.com

Dockerfile ベストプラクティスに載っている Least Privilege UserUse Copy Over Add などを検出できたり,また Use Apt No Install Recommends などイメージサイズを削減するためのよく知られた Tips なども検出できる💡

docs.docker.com

docs.docker.com

docs.docker.com

さっそく試す

過去に個人的に開発をしたことがあるいくつかの Dockerfile に対して Trivy を実行してみて,検出された警告を紹介する.ちなみに今回は Trivy 0.45.0 を使う.

$ trivy --version
Version: 0.45.0

Severity(重大度): HIGH

🔗 Least Privilege User

root ユーザーを避けるべし!という警告🛑

HIGH: Last USER command in Dockerfile should not be 'root'

Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.

See https://avd.aquasec.com/misconfig/ds002

avd.aquasec.com

🔗 Use Apt No Install Recommends

apt-get コマンドを使っている場合はイメージサイズを削減するために –no-install-recommends を使おう!という警告🛑

HIGH: '--no-install-recommends' flag is missed: xxx

'apt-get' install should use '--no-install-recommends' to minimize image size.

See https://avd.aquasec.com/misconfig/ds029

avd.aquasec.com

Severity(重大度): MEDIUM

🔗 Use Specific Tags

latest タグを避けるべし!という警告🛑

MEDIUM: Specify a tag in the 'FROM' statement for image 'ubuntu'

When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.

See https://avd.aquasec.com/misconfig/ds001

avd.aquasec.com

🔗 Use Workdir Over Cd

RUN cd xxx のように書くなら WORKDIR を使おう!という警告🛑

MEDIUM: RUN should not be used to change directory: xxx

Use WORKDIR instead of proliferating instructions like 'RUN cd … && do-something', which are hard to read, troubleshoot, and maintain.

See https://avd.aquasec.com/misconfig/ds013

avd.aquasec.com

Severity(重大度): LOW

🔗 Use Copy Over Add

ADD ではなく COPY を使うべし!という警告🛑

LOW: Consider using 'COPY ./ /usr/local/xxx' command instead of 'ADD ./ /usr/local/xxx'

You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files.

See https://avd.aquasec.com/misconfig/ds005

avd.aquasec.com

🔗 No Healthcheck

HEALTHCHECK を追加しよう!という警告🛑

LOW: Add HEALTHCHECK instruction in your Dockerfile

You should add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.

See https://avd.aquasec.com/misconfig/ds026

avd.aquasec.com

ちなみに Dockerfile のヘルスチェック機能 (HEALTHCHECK) に関しては前に検証してブログにまとめてある💡

kakakakakku.hatenablog.com

不要な警告を減らす

Trivy の設定ファイル trivy.yaml を活用すると細かく挙動を制御できる.例えば Trivy で警告する Severity(重大度)の閾値を設定する場合は以下のように書くことで LOW / MEDIUM を無視できて警告を減らせる👏

severity:
  - HIGH
  - CRITICAL

もし特定の警告を無視する場合はまた別の設定ファイル .trivyignore に ID を設定すれば OK👌

AVD-DS-0002

個別に警告を無視する

Dockerfile にインラインコメントとして #trivy:ignore:... と書けば個別に警告を無視できる.以下は例として Least Privilege User の警告を例外的に無視するために #trivy:ignore:AVD-DS-0002 と書いた.

USER root #trivy:ignore:AVD-DS-0002

ちなみに以下のように直前に独立したコメントを書いたらうまく動かなかった💨

#trivy:ignore:AVD-DS-0002
USER root

Trivy を GitHub Actions で動かす

Trivy を GitHub Actions で動かす場合は「trivy-action」を使えば簡単に導入できる❗️

github.com

1点注意点としては Trivy は警告があってもデフォルトでは exit code 0 を返す.よって GitHub Actions をエラーにするために exit code 1 を返すように設定ファイル trivy.yamlexit-code: 1 と書いておく💡

exit-code: 1

severity:
  - HIGH
  - CRITICAL

単純な GitHub Actions ワークフローとしてはこんな感じかとー👀

name: Trivy

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

jobs:
  trivy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Trivy
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: config
          trivy-config: trivy.yaml

実は以下の記事で Trivy の Misconfiguration Scanning を GitHub Actions で動かしたワークフローとまったく同じ👌

kakakakakku.hatenablog.com

hadolint (Haskell Dockerfile Linter)

ちなみに今までは Dockerfile の Linter として hadolint (Haskell Dockerfile Linter) を使っていた.GitHub Actions のワークフローに組み込んで自動化したり,新しく現場に参画したときに Dockerfile を読みながら hadolint を実行して改善の提案をしたり.

github.com

2020年頃にブログ記事を書いてるけど,hadolint は Bash の Linter として ShellCheck も同梱されてて,RUN の警告を検出しやすいという強みはあると思う💬

kakakakakku.hatenablog.com

まとめ

Trivy の Misconfiguration Scanning を使って Dockerfile の設定ミス(セキュリティ課題やベストプラクティス乖離など)を検出してみた❗️便利〜 \( 'ω')/

Dockerfile の Linter なら hadolint もあるけど,Trivy は Misconfiguration Scanning 以外にもたくさん機能があるため「開発組織で使うツールセットを Trivy に統一できる」というメリットがあると思う💬 個人的には Trivy を使えば使うほど機能の幅広さに驚かされていて,今後は Trivy を積極的に導入したいと思っていたりもする❗️どんどん試すぞ〜