🐭

【Docker】コンテナイメージの脆弱性診断をGithub Actionsで実行させてみた | Offers Tech Blog

2022/09/26に公開

概要

こんにちは、Offers を運営している株式会社 overflow の Software Engineer(主戦場はフロントエンド)の Kazuya です。今回は、Docker コンテナイメージの脆弱性診断を Github Actions で実行させる方法を紹介します。
Docker を構築してみたけど、セキュリティ面が大丈夫か不安に感じる方もいると思います。今回はそんな悩みを解消できるかも(?)しれないので、ぜひ最後までご付き合いください。

はじめに

本記事では、Next.js×Docker の脆弱性診断を Github Actions で実行させる方法を紹介します。今回紹介するものは一例であり最適な実装でない可能性がありますので、予めご理解の上、参考にしていただけると幸いです。

また、今回使用するコンテナイメージについては、こちら の記事で紹介しているものを使用します。本記事を参考にする際にはこちらも合わせてご確認ください。

実現したいこと

今回実現したいことは、自身で構築した Docker のコンテナイメージに脆弱性がないかテストするというものです。ローカルでも検証はしていますが、より堅牢性を高めると同時に自動的に検証できる仕組みを作りたいと考え、今回の実装にトライしました。

使用するツール

今回は、コンテナイメージのセキュリティ診断ツール「Dockle」を使用します。ビルドしたコンテナイメージ内の脆弱性に対して警告や対処法などを提案してくれます。導入方法や詳しい使い方は以下のページをご参照ください。

https://qiita.com/tomoyamachi/items/bb6ac5788bb734c91282

なぜ Dockle を採用したか

なぜ、数あるツールの中から「Dockle」を採用したかですが、理由は以下のとおりです。

  • Github Actions への導入コストが低い
  • チェック項目の範囲が広い
  • hadolintTrivy のチェック項目も内包

使用するプラグイン

dockle-action

Github Actions 上で Dockle を実行できるプラグイン
https://github.com/erzz/dockle-action

action-slack-notify

Github Actions の成功可否を Slack に通知するプラグイン
https://github.com/rtCamp/action-slack-notify

実装方法

Github Actions の発火条件を設定する

今回は、Docker のコンテナイメージのテストのため、Docker に関するファイルが変更された時のみ実行するようにしておきます。(前述の条件以外で発火させてしまうと、テストの実行時間が増加してしまうため、必要な場合だけ発火するようにしています)
上記を踏まえて、Github Actions の YAML に書き起こすと以下の通りになります。

docker_test.yml
name: Docker Test
on:
  push:
    branches-ignore:
      - main
      - development
    paths:
      - Dockerfile

Docker のコンテナイメージをビルドする

発火条件を設定したので、次にジョブを設定していきます。まずは、テストをする Docker のコンテナイメージを用意する必要があるので、ビルドしていきます。テストする際にはコンテナ名が必要になるため、環境変数でコンテナ名を共通化させています。

docker_test.yml
name: Docker Test
on:
  push:
    branches-ignore:
      - main
      - development
    paths:
      - Dockerfile
+ env:
+   DOCKER_IMAGE_TAG: 'docker-image'

+ jobs:
+   build:
+     runs-on: ubuntu-latest
+     steps:
+       - name: checkout
+         uses: actions/checkout@v3
+
+       - name: docker-build
+         run: |
+           docker build -f Dockerfile -t ${{ env.DOCKER_IMAGE_TAG }} .

Dockle を実行して脆弱性を診断する

コンテナイメージのビルドが完了したら、Dockle で脆弱性を診断していきます。前述で環境変数に設定したコンテナ名を dockle-action の引数に渡します。なお、今回は脆弱性が fatal に該当するものが存在する時にテストが落ちるように設定しています。この部分は、必要に応じて変更してもらえると良いと思います。

docker_test.yml
name: Docker Test
on:
  push:
    branches-ignore:
      - main
      - development
    paths:
      - Dockerfile
env:
  DOCKER_IMAGE_TAG: 'docker-image'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v3

      - name: docker-build
        run: |
          docker build -f Dockerfile -t ${{ env.DOCKER_IMAGE_TAG }} .

+     - name: run-dockle
+       uses: erzz/dockle-action@v1
+       with:
+         image: ${{ env.DOCKER_IMAGE_TAG }}
+         exit-code: 1
+         failure-threshold: fatal

実行結果を Slack に通知させる

ここに関しては特にやらなくてもいいですが、やっておくと Github で確認しなくてもテストの実行結果を確認できるため余力があれば対応してみてください。必要なものは Slack の WebHook URL のみです。直接 YAML 上に書くのはセキュリティ的に良くないため、必ず Github Action のシークレットを活用しましょう。

docker_test.yml
name: Docker Test
on:
  push:
    branches-ignore:
      - main
      - development
    paths:
      - Dockerfile
env:
  DOCKER_IMAGE_TAG: 'docker-image'
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v3

      - name: docker-build
        run: |
          docker build -f Dockerfile -t ${{ env.DOCKER_IMAGE_TAG }} .

      - name: run-dockle
        uses: erzz/dockle-action@v1
	with:
	  image: ${{ env.DOCKER_IMAGE_TAG }}
	  exit-code: 1
	  failure-threshold: fatal

+     - name: slack-notification-success
+       if: ${{ success() }}
+	uses: rtCamp/action-slack-notify@v2
+	env:
+	  SLACK_COLOR: good
+	  SLACK_TITLE: 'Success to Docker Test :rocket:'
+	  SLACK_MESSAGE: ':closed_book: ${{ github.repository }}'

+     - name: slack-notification-failure
+       if: ${{ failure() }}
+       uses: rtCamp/action-slack-notify@v2
+       env:
+         SLACK_COLOR: danger
+         SLACK_TITLE: 'Failure to Docker Test :boom:'
+         SLACK_MESSAGE: ':closed_book: ${{ github.repository }}'
完成品
docker_test.yml
name: Docker Test
on:
  push:
    branches-ignore:
      - main
      - development
    paths:
      - Dockerfile
env:
  DOCKER_IMAGE_TAG: 'docker-image'
   SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v3

      - name: docker-build
        run: |
          docker build -f Dockerfile -t ${{ env.DOCKER_IMAGE_TAG }} .

      - name: run-dockle
        uses: erzz/dockle-action@v1
	with:
	  image: ${{ env.DOCKER_IMAGE_TAG }}
	  exit-code: 1
	  failure-threshold: fatal

      - name: slack-notification-success
        if: ${{ success() }}
	uses: rtCamp/action-slack-notify@v2
	env:
	    SLACK_COLOR: good
	  SLACK_TITLE: 'Success to Docker Test :rocket:'
	  SLACK_MESSAGE: ':closed_book: ${{ github.repository }}'
            
      - name: slack-notification-failure
	if: ${{ failure() }}
	uses: rtCamp/action-slack-notify@v2
	env:
	  SLACK_COLOR: danger
	  SLACK_TITLE: 'Failure to Docker Test :boom:'
	  SLACK_MESSAGE: ':closed_book: ${{ github.repository }}'

まとめ

今回は、Docker コンテナイメージの脆弱性診断を GithubAction で実行させる方法について紹介しました。セキュリティを考慮した環境構築は WEB アプリケーション開発をする上で、非常に重要な部分の 1 つです。苦手意識を持つ人も多いと思いますが、本記事で少しでも理解を深めることができていれば幸いです。

いいねしていただけると記事執筆の励みになりますので、参考になったと思った方は是非よろしくお願いします!

関連記事

https://zenn.dev/offers/articles/20220523-component-design-best-practice
https://zenn.dev/offers/articles/20220418-what-is-bff-architecture
https://zenn.dev/offers/articles/20220519-thinking-about-dark-mode

Offers Tech Blog

Discussion