ECRにあるDockerイメージをTrivyでスキャンするツールを作ってみた


前置き

AWS ECSでDockerを本番運用する際に脆弱性チェックするためのツールを作りました!
そのツールの内容と使い方を説明していきます。リポジトリはこちら

ツール説明

開発動機

AWS ECSを本番運用する際に脆弱性を持続的にチェックするツールがなかったので開発しました。
有料であればあるのかもしれませんが、金銭的コストがかかるので自作することにしました。

使用言語・ソフトウェア

  • Python3.7
  • Pipenv
  • Docker
  • Trivy

Pythonライブラリ

  • requests
  • boto3

機能

イメージの取得

ECRからDockerイメージを取得するためにBoto3を使っています。
ECRへのログインは環境変数に認証データをセットしてあれば自動でログインしてくれます。ログインが成功すれば、指定したAWSアカウントのECRにあるDockerイメージを全て取得します。現段階ではタグによって取得するイメージのバーションを制限できますが、イメージ名では制限できません。
あと、ソースを読んでもらえればわかりますが所々でコマンドを使っています。これはおいおいSDKに置き換えて行きたいと思っています。

脆弱性スキャン

脆弱性スキャンにはタイトル通り、Trivyを使わせていただきました。
Trivyといえば、先日aquasecurityに買収されたニュースがありましたね。個人で開発したOSSが買収されるなんて夢がありますよね

Slack通知

Dockerイメージを脆弱性スキャンした結果をSlackへ通知します。今回はSlack APIではなく、Requestsを使ってSlackへPOSTしています。また、メッセージのレイアウトにはBlocksを採用しました。色をつけるために従来のattachmentsも使っていますが・・・
Slack通知の内容は、イメージ名・パッケージ(ソフトウェア)名・脆弱性の説明・深刻度・ID・参考リンクとなっています。
見た目はこんな感じです⬇️

Referenceで変な感じに改行されていますが、これはSlackに表示される時にこんな感じになってしまいました。<-原因がわからん

使い方

このツールはDockerイメージを用意しているのでDockerがインストールされている環境であれば簡単に試すことができます。
GitHub AcitonsとCLIで実行する方法を説明します。

GitHub Actions

GitHub Actionsで毎日9時に定期実行する例を紹介します。

.github/workflows/scan.yml
on:
  schedule:
    - cron: '0 9 * * *'
name: Scan Docker Image
jobs:
  scan:
    name: Scan
    runs-on: ubuntu-18.04
    steps:
      - name: scan images
        uses: docker://iscream/ecranner
        env:
          AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: 'ap-northeast-1'
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
          SLACK_CHANNEL: '#random'

      # jobの成否を通知
      - name: slack notification
        uses: homoluctus/slatify@master
        if: always()
        with:
           type: ${{ job.status }}
           channel: '#random'
           job_name: ':trivy: *Scan Image*'
        env:
           SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

CLI

.envファイルの作成

値は自身の環境に合わせて変更してください。

.env
TZ=Asia/Tokyo
AWS_ACCOUNT_ID=xxxxxx
AWS_ACCESS_KEY_ID=xxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxx
AWS_DEFAULT_REGION=ap-northeast-1
SLACK_WEBHOOK=xxxxxx
SLACK_CHANNEL=#random

実行

docker pull iscream/ecranner
docker run --rm --env-file ./.env --privileged iscream/ecranner

おわりに

ECSに限らずDockerを本番運用する際にはセキュリティには十分に気をつけたいものですよね。Trivyの他にもOSSではDockleというDockerfileのベストプラクティスに沿っているかチェックするツールもあります。様々なツールを駆使してセキュリティを確保していきましょう。

あとツールに関してですが、今回はPythonで書きましたがGoで書き直そうかと思います。ついでにコマンドを実行しているところもSDKで置き換えていくつもりです。
それでは