はじめに
皆さんこんにちはasmgです。今回は、セキュアな状態で、Dockerimageを作成するために、GitHubActions上でtrivyを使いDocker imageの脆弱性診断をやってみたいと思います。
本記事の対象者
本記事は、GitHub Actionsでtrivyを利用したことをない人を対象としています。
また、trivy-actionをとりあえず触りたいと言う人でも触れるような構成で書いていきたいと思います。
本記事のゴール
trivy-actionをGitHub Actions上で動かし、Docker imageの脆弱性診断を行い、GitHub上のSecurityページまたは、issueに情報を記録するところまでをゴールにしたいと考えています。
今回使うもの
ツール類
- GitHub Actions
- 脆弱性診断ツール: trivy
- 公開アクション: trivy-action
脆弱性診断ツール trivyとは?
コンテナイメージ、ファイルシステム、Git リポジトリの脆弱性、および設定の問題を検出するシンプルで包括的なスキャナツール。 Trivyは、 OSパッケージ(Alpine、RHEL、CentOSなど)および言語固有のパッケージ(Bundler、Composer、npm、yarnなど)の脆弱性を検出する。
また、 Terraform、Dockerfile、KubernetesなどのInfrastructure as Code (IaC) ファイルをスキャンし、デプロイメントの攻撃リスクにさらす潜在的な設定問題を検出する。
※https://github.com/aquasecurity/trivy をDeepLで翻訳後要約
注意点
trivy-actionの出力結果をプライベートリポジトリで利用するためには以下のライセンスを契約しておく必要があります。(※1)
- GitHub One ライセンス
https://docs.github.com/en/get-started/learning-about-github/githubs-products#github-one - Enterprise + Code scanning オプションライセンス
https://github.com/features/security#security-prevent
(※1)GitHubのCode Scanningを使ってみる
https://blog.motikan2010.com/entry/2020/10/11/%E3%80%90%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%80%91GitHub%E3%81%AECode_Scanning%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B
実際にやってみる
手順
trivy-actionのドキュメントに乗っている方法をやってみたいと思います。
https://github.com/aquasecurity/trivy-action/blob/master/README.md
trivy-actionのスキャン以下のような方法があります。
- Docker imageをスキャンする
- Github repositoryをスキャンする方法
- プライベートレジストリをスキャンする方法 など...
今回は、"Docker imageをスキャンする" を採用し、Dockerfileをbuild後、imageの脆弱性診断をしていこうと思います。
以下が実際に作成したコード全体になります。
name: docker-build
on:
pull_request:
branches:
- main
types:
- opened
jobs:
step:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: dockerfile build
run : |
docker build -t python_code。
- name: run trivy for docker image
uses: aquasecurity/trivy-action@master
with:
image-ref: 'python_code'
format: 'sarif'
output: 'trivy-results.sarif'
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
トピック:GitHub Actionsの動作条件
実行条件は、main branchにPRが作成された時をトリガーに脆弱性診断を実行したいと思います。
name: docker-build
on:
pull_request:
branches:
- main
types:
- opened
今回は、テストで動かしているためPRを作成した時のみ動作させていますが通常脆弱性診断を行う場合、作成時のみではなく、PRの更新時等にも実行する必要があります。その場合には、typesにsynchronizeを付ける必要があります。
name: docker-build
on:
pull_request:
branches:
- main
types:
- opened
- synchronize
このようなトリガー条件は、読者の皆さんのタイミングで実行させる必要がありますので適宜変更してください。
実行結果
特に問題がない場合(脆弱性を確認できなかった場合)
問題があった場合(脆弱性を確認できた場合)
今回は、 実際に脆弱性のあるライブラリを使って実行してみました。
- 該当ライブラリ: flask==0.12.3
ライブラリ:https://pypi.org/project/Flask/0.12.2/
脆弱性情報:https://snyk.io/vuln/pip:flask
trivy-actionを使ってissueに登録する
GitHub Code scanning上のCode scanning alertに、プライベートリポジトリで通知させる場合ライセンス料が発生します。
なので、公式には書かれていませんが、本記事ではtrivy-actionの出力結果をGitHub Code scanning上のCode scanning alert以外に出力する方法を検討してみました。
Github issueに出力する方法
name: docker-build
on:
pull_request:
branches:
- main
types:
- opened
- synchronize
jobs:
step:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: dockerfile build
run : |
docker build -t python_code .
- name: run trivy for docker image
uses: aquasecurity/trivy-action@master
with:
image-ref: 'python_code'
format: 'table'
output: 'trivy-results.table'
ignore-unfixed: false
exit-code: '1'
vuln-type: 'library'
severity: 'MEDIUM,HIGH,CRITICAL'
- id: trivy_output
name: output_file
if: failure()
run: |
output_data=$(cat ./trivy-results.table)
output_data="${output_data//$'\n'/\\n}"
echo "::set-output name=std_out::$output_data"
- name: create_issue
if: failure()
uses: actions/github-script@v3
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const { GITHUB_SERVER_URL, GITHUB_REPOSITORY, GITHUB_RUN_ID } = process.env
var trivy_output_data = "${{ steps.trivy_output.outputs.std_out }}"
console.log(trivy_output_data);
github.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'Security Alert',
body: "```"+`${trivy_output_data}`+"```",
})
上記のようなワークフローでコードを実行すると、issueに表を出力することができます。
この方法を使うとプライベートリポジトリでも、trivy-actionの出力結果を通知することが可能になると思います。
おまけ:trivyのカスタマイズ方法(input)
trivyの設定は、 GitHub Actionのwith:で設定します。
- name: run trivy for docker image
uses: aquasecurity/trivy-action@master
with:
#ここに設定を入れる
今回は、 重要そうなものだけをピックアップして載せます。
name | Description |
---|---|
scan-type | スキャンタイプを選べる[image/fs] |
format | formatを選べる[table/json/sarif] |
output | 結果をファイルに保存する ex) trivy-results.sarif |
ignore-unfixed | 未修正の脆弱性を無視するかどうかを選ぶ [true/false] |
vuln-type | なんの脆弱性を診断するかを選ぶことができる [os/library] |
severity | スキャンして表示する脆弱性の重大度を選ぶことができる[UNKNOWN/LOW/MEDIUM/HIGH/CRITICAL] |
詳しくは、ドキュメントを参照
https://github.com/aquasecurity/trivy-action/blob/master/README.md
最後に
GitHub Actionsを使って、Docker imageの脆弱性診断を行なって、github上のSecurityページに情報を記録するところまでの流れを実際にやってみました。
今後の課題としては、この脆弱性診断の結果を踏まえてDockerレジストリにimageをpushするなどの条件を加えるなどができると良いと考えています。
最後までご覧いただきありがとうございました。