CTOの原口です。
弊社ではコンテナのCI/CDとして主にAWS CodePipeline (AWS CodeBuild)を利用していますが、コンテナの脆弱性診断ツールとして「Trivy」を利用しています。
Trivyとは、オープンソースのコンテナイメージの脆弱性診断ツールです。非常にシンプルに利用できるため CI に組み込んで使う用途に最適です。弊社ではビルドされたコンテナに対して、Trivyでスキャンした結果、CRITICALレベルの脆弱性があった場合はビルドフローをストップするようにしています。
本日はそんな「Trivy」が最近 CodeBuild にて頻繁に実行エラーを出すようになったお話です。
CodeBuildにてTrivyが頻繁に実行エラーを出すようになった
CodeBuildで実行中、頻繁に以下のエラーが出るようになりました。
1[Container] Running command trivy image --no-progress --ignore-unfixed --security-checks vuln --severity CRITICAL --exit-code 0 $AWS_ECR_REPO:latest
2INFO [vulndb] Need to update DB
3INFO [vulndb] Downloading vulnerability DB...
4INFO [vulndb] Downloading artifact... repo="ghcr.io/aquasecurity/trivy-db:2"
5ERROR [vulndb] Failed to download artifact repo="ghcr.io/aquasecurity/trivy-db:2" err="OCI repository error: 1 error occurred:\n\t* GET https://ghcr.io/v2/aquasecurity/trivy-db/manifests/2: TOOMANYREQUESTS: retry-after: 153.601µs, allowed: 44000/minute\n\n"
6FATAL Fatal error init error: DB error: failed to download vulnerability DB: OCI artifact error: failed to download vulnerability DB: failed to download artifact from any source
脆弱性スキャンを実行する際に脆弱性データベースの更新をしようとしていますが、そのリポジトリである ghcr.io/aquasecurity/trivy-db に接続しようとしてTOOMANYREQUESTSとあるので「リクエストしすぎ」というエラーのようです。
今までこのエラーが出ることは稀で、起こった際もパイプラインをリトライすれば問題なく進んでいたのですが、今では問題のない事の方が珍しいレベルになってきたので対策をする事にします。
エラーになった原因
ご存知(?)の通り、CodeBuildをVPCモードで動かさない場合は、AWS東京リージョンでの共有の2つほどのIPを利用するため、IPベースのrate limitにかかったのではないかと思います。
なのでTrivyというよりは根本としては「CodeBuildがGithubのコンテナレジストリ「ghcr.io」のrate limit にひっかかってしまう」という事ですね。
rate limit対策
Docker Hubのrate limit問題にもあったような対策が考えられます。
- CodeBuildをVPCで動かす
- githubにログインする事でrate limitの制約を抜ける
- ECRリポジトリからコンテナイメージを取得する
CodeBuildをVPCで動かす場合、インターネットに出るにはNAT Gatewayが必要ですし、GithubにログインするにはTOKENが必要だったりといろいろ面倒です。
ですので今回はECRリポジトリを利用する方法で対応したいと思います。
trivy-dbをGHCRではなくECRを利用する対策
今回、ビルドしたコンテナは最終的にECRへpushするためECRログインを実行していますしECR関連のIAMロールも与えています。そのためECRであればなんとなく基本的にrate rimitの制限は受けないと考えられます。またAWSサービス同士だし大丈夫じゃないかな、と・・・(ソースなし)
1aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ECR_DOMAIN
※今回はdocker pullが行われているわけではないのでecrへのログインは必須ではなさそうです
trivyの公式ドキュメント を見ていると ECRのpublic gallary にもTrivyの各種コンテナイメージが公式に存在しますのでこちらを利用する事とします。
trivy image コマンドでは脆弱性データベースリポジトリの変更を引数で行う事ができます。
ですので以下のような変更を行えば問題がなくなりました。
1trivy image \
2--ignore-unfixed \
3--scanners vuln \
4--severity CRITICAL \
5$YOUR_IMAGE:latest
↓
1trivy image \
2--db-repository public.ecr.aws/aquasecurity/trivy-db \
3--java-db-repository public.ecr.aws/aquasecurity/trivy-java-db \
4--ignore-unfixed \
5--scanners vuln \
6--severity CRITICAL \
7$YOUR_IMAGE:latest
環境によっては java-db-repository は不要かと思います。
この状態で実行すると、ログにECRリポジトリを利用した事がでてきます。
1INFO Adding schema version to the DB repository for backward compatibility repository="public.ecr.aws/aquasecurity/trivy-db:2"
2INFO Adding schema version to the DB repository for backward compatibility repository="public.ecr.aws/aquasecurity/trivy-java-db:1"
3INFO [vulndb] Need to update DB
4INFO [vulndb] Downloading vulnerability DB...
5INFO [vulndb] Downloading artifact... repo="public.ecr.aws/aquasecurity/trivy-db:2"
6INFO [vulndb] Artifact successfully downloaded repo="public.ecr.aws/aquasecurity/trivy-db:2"
いったんはこちらで TOOMANYREQUESTS の問題が解決できました。