2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今日から始めるセキュリティシフトレフト on AWS ④AWS CodeBuildとAWS Security Hubで効率良く脆弱性管理をする

Last updated at Posted at 2024-10-26

はじめに

セキュリティシフトレフト記事第四弾。

前回は、アプリケーションのSASTツールをどのようにAWS CodeBuild上で使うのが良いのかを検証した。

今回は、第二回の記事の内容に戻り、Trivyによって検出した脆弱性に関連した情報をAWS Security Hubを送り、問題管理を行えるようにしていく。AWS CodeBuildのバッチビルドの構成はそのままに、Trivyを動作させるビルド部分のみを変更するため、第二回の記事の内容を参照しておいていただきたい。

脆弱性のあるDockerfileの準備

今回は、あえて脆弱性を仕込んだDockerfileを作って検知までしてみたいため、以下のようなDockerfileを準備する。Dockerfile内でnginx.confを差し替えていないので、実際の運用ができるものではないが、サンプルのため細かいことは気にしないでいただきたい。

FROM public.ecr.aws/nginx/nginx:1.27

RUN apt-get update \
  && apt-get install --no-install-recommends -y curl=7.88.1-10+deb12u7 \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

HEALTHCHECK CMD /usr/bin/curl http://localhost/

WORKDIR /

CMD ["nginx", "-g", "daemon off;"]

AWS Security Hubの有効化

AWS Security Hubを以下のように有効化する。
aws_securityhub_accountはその名の通り、アカウント全体の設定なので、既に有効化されている場合は特に作成する必要はない。

なお、AWS Security Hubはスキャン単位で課金されるため、今回はスキャンする量を減らすためにenable_default_standards = falseを設定しているが、実際の運用時には必要なセキュリティチェックは有効にしておこう。

Security Hub の価格は、セキュリティチェックの数、検出結果の取り込みイベントの数、1 か月あたりに処理されるルール評価の量という 3 つの観点から設定されます。

resource "aws_securityhub_account" "example" {
  enable_default_standards = false
  auto_enable_controls     = false
}

AWS Security HubとTrivyを統合する

さて、Security Hubを有効化したら次はTrivyのレポートを受けられる状態にする。
他のプロダクトと統合する際は、Terraformのaws_securityhub_product_subscriptionのリソースを使用する。

具体的にどんなプロダクトと統合可能かの全容は以下のAWS公式のユーザーガイドに記載されている。

Trivyについても記載されているので、その値をproduct_arnに設定する。

resource "aws_securityhub_product_subscription" "example" {
  depends_on = [aws_securityhub_account.example]

  product_arn = "arn:aws:securityhub:${data.aws_region.current.name}::product/aquasecurity/aquasecurity"
}

AWS CodeBuildのIAM権限設定

今回、AWS Security Hubに情報を送信するにあたり、AWS CodeBuildのサービスロールにsecurityhub:BatchImportFindingsの権限付与が必要になるため、忘れず設定しておこう。

# (前略)
  statement {
    effect = "Allow"

    actions = [
      "securityhub:BatchImportFindings",
    ]

    resources = [
      "*",
    ]
  }
# (後略)

AWS CodeBuildのBuildspecの設定

次に、AWS CodeBuildのBuildspecを準備していく。
第二回で作成したBuildspecは以下の通り簡易なものであったが、これを書き換えていく。その際、ハマりどころがいくつかあるので、ポイントを抑えて説明していく。

21_trivy.yml
version: 0.2

env:
  variables:
    IMAGE_NAME: "container_image"
    IMAGE_TAG : "1.0"
    TRIVY_PATH: "/usr/bin/trivy"

phases:
  install:
    commands:
      # install Trivy
      - VERSION=$(curl --silent https://api.github.com/repos/aquasecurity/trivy/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
      - rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.rpm
  build:
    commands:
      - docker build . -t ${IMAGE_NAME}:${IMAGE_TAG}
      - ${TRIVY_PATH} image --quiet --exit-code 1 ${IMAGE_NAME}:${IMAGE_TAG} 

変更後のBuildspecの全体像

変更後のBuildspecは以下の通りとなる。phases.build以前は変える必要がないのでそのままにして良い。

21_trivy.yml
# (前略)
  build:
    commands:
      - docker build . -t ${IMAGE_NAME}:${IMAGE_TAG}
      # Settings are required to reference the AWS_ACCOUNT_ID environment variable in Trivy's ASFF template.
      - AWS_ACCOUNT_ID=$(echo ${CODEBUILD_BUILD_ARN} | cut -f 5 -d :)
      - ${TRIVY_PATH} image
        --no-progress
        --db-repository public.ecr.aws/aquasecurity/trivy-db:2
        --java-db-repository public.ecr.aws/aquasecurity/trivy-java-db:1
        --format template
        --template "@/usr/local/share/trivy/templates/asff.tpl"
        --output /tmp/tmp-report.asff
        --severity HIGH
        --ignore-unfixed
        --exit-code 1
        ${IMAGE_NAME}:${IMAGE_TAG} 
  post_build:
    commands:
      # Send report to AWS Security Hub on build failure
      - |
        if [ $CODEBUILD_BUILD_SUCCEEDING != "1" ]; then
          jq '.Findings' /tmp/tmp-report.asff > /tmp/report.asff
          aws securityhub batch-import-findings --findings file:///tmp/report.asff --region ${AWS_DEFAULT_REGION}
        fi

Trivyのレポート形式をASFFに指定する

Trivyのレポートの形式は以下のページで詳細が書かれている。

ここに

If Trivy is installed using rpm then default templates can be found at /usr/local/share/trivy/templates .

と書いてある通り、ASFFのテンプレートは/usr/local/share/trivy/templates/asff.tplに置かれている。GitHubにもあるので、参考までにリンクを貼っておく。

気を付けなければいけないのは、このテンプレート内でAWS_REGIONAWS_ACCOUNT_IDの二つの環境変数を参照していることだ。
AWS_REGIONはAWS CodeBuildのデフォルト環境変数で、「AWS CodeBuildを実行しているリージョン」が設定されてくるので、何も設定しなくて良い(もちろん、AWS CodeBuildとAWS Security Hubを別リージョンで動かしている場合は変更が必要)。
AWS_ACCOUNT_IDはデフォルト環境変数になっていないため、AWS_ACCOUNT_ID=$(echo ${CODEBUILD_BUILD_ARN} | cut -f 5 -d :)で値を取り出して設定をしておく(AWS CodeBuildに環境変数で渡しても良いが、クロスアカウントでない限りはこちらの方が簡単だろう)。

Trivyのデータベース更新のレジストリ変更

Trivyのデフォルトの脆弱性情報のデータベースはghcr.ioであり、AWS CodeBuildから何も指定せずに動作させると、GitHub側のRateLimitにぶつかってしまいうまく動作しない(しかも、このエラーログがRateLimitと分かるログでないので、ハマるとつらい)。
ということで、ECR Public GalleryのレジストリURLを--db-repository--java-db-repositoryに設定しておこう。--no-progressオプションを付けるとDB更新の進捗が表示されなくなる。

重要度等の設定

すべての修正をしているとキリがないので、HIGHかCRITICAL以上のものを管理対象としよう。
これは--severity HIGHで設定可能だ。
また、修正されていない脆弱性を表示されてもつらいだけなので、--ignore-unfixedのオプションを使い、FIX済みで未適用のもののみAWS Security Hubに送信するようにする。

post_buildの設定

最後に、aws securityhub batch-import-findingsで、出力したASFFを送信する。
.FindingsのJSON要素のみ必要であるため、jqコマンドで編集をしている。

これで、準備は完了だ。

いざ、動かす!

terraform applyしたらしばらくビルドの完了を待って、AWS Security Hubのコンソールを見てみよう。
以下の手順で、Trivyのレポートに絞って確認することができる。

①「統合」を選択
②検索ボックスで「Aqua」を検索
③「結果を参照」のリンクを押す

キャプチャ1.png

上記を行うと、以下のように検出された脆弱性の一覧を確認することができる(今回はHIGH以上は1件のみであった)。

キャプチャ2.png

「検出結果」のリンクを押下することで、より詳細な情報を確認が可能だ。
リソースのタブの「詳細」を開くことで、現在どのバージョンのパッケージを利用していて、パッチするためには何を指定すれば良いかもここから分かる。

image.png

指摘されているとおり、Dockerfileでlibheifのパッチ済みバージョンを追加インストールしよう。

Dockerfile
FROM public.ecr.aws/nginx/nginx:1.27

RUN apt-get update \
  && apt-get install --no-install-recommends -y curl=7.88.1-10+deb12u7 \
+ && apt-get install --no-install-recommends -y libheif-dev=1.15.1-1+deb12u1 \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

HEALTHCHECK CMD /usr/bin/curl http://localhost/

WORKDIR /

CMD ["nginx", "-g", "daemon off;"]

これで、再度AWS CodeBuildを実行すると、今度は指摘がなく正常終了するはずだ。
エラーが出なくなったら、AWS Security Hub上のステータスもちゃんと更新をしておこう。

キャプチャ4.png

これで、より効率的に脆弱性管理をできるようになった!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?