Trivy の「Misconfiguration Scanning」を使うと Dockerfile の設定ミス(セキュリティ課題やベストプラクティス乖離など)を検出できる❗️今回は Trivy を活用した Dockerfile のスキャンを試した作業ログをまとめる📝
ちなみに Trivy の Misconfiguration Scanning は Terraform, AWS CloudFormation など複数のスキャンをサポートしている.Trivy x Terraform を試した記事は前に公開してあって,Trivy の設定や GitHub Actions ワークフローなどはほぼ同じで OK👌
どんなルールがあるのか
以下の 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
Dockerfile ベストプラクティスに載っている Least Privilege User や Use Copy Over Add などを検出できたり,また Use Apt No Install Recommends などイメージサイズを削減するためのよく知られた Tips なども検出できる💡
さっそく試す
過去に個人的に開発をしたことがあるいくつかの 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
🔗 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
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
🔗 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
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
🔗 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
ちなみに Dockerfile のヘルスチェック機能 (HEALTHCHECK
) に関しては前に検証してブログにまとめてある💡
不要な警告を減らす
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」を使えば簡単に導入できる❗️
1点注意点としては Trivy は警告があってもデフォルトでは exit code 0 を返す.よって GitHub Actions をエラーにするために exit code 1 を返すように設定ファイル trivy.yaml
に exit-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 で動かしたワークフローとまったく同じ👌
hadolint (Haskell Dockerfile Linter)
ちなみに今までは Dockerfile の Linter として hadolint (Haskell Dockerfile Linter) を使っていた.GitHub Actions のワークフローに組み込んで自動化したり,新しく現場に参画したときに Dockerfile を読みながら hadolint を実行して改善の提案をしたり.
2020年頃にブログ記事を書いてるけど,hadolint は Bash の Linter として ShellCheck も同梱されてて,RUN
の警告を検出しやすいという強みはあると思う💬
まとめ
Trivy の Misconfiguration Scanning を使って Dockerfile の設定ミス(セキュリティ課題やベストプラクティス乖離など)を検出してみた❗️便利〜 \( 'ω')/
Dockerfile の Linter なら hadolint もあるけど,Trivy は Misconfiguration Scanning 以外にもたくさん機能があるため「開発組織で使うツールセットを Trivy に統一できる」というメリットがあると思う💬 個人的には Trivy を使えば使うほど機能の幅広さに驚かされていて,今後は Trivy を積極的に導入したいと思っていたりもする❗️どんどん試すぞ〜