1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECRの脆弱性スキャン通知が多すぎる問題を改善した話

1
Last updated at Posted at 2026-08-30

はじめに

Amazon ECR で管理しているコンテナイメージに対して Inspector v2 が脆弱性スキャンを継続的に実施している。スキャン結果はメールで通知しているが、通知が多すぎてノイズとなっていた。本記事では、その原因を整理し、どのように改善したかをまとめる。

最初の構成

アーキテクチャ

ECR push
  → Inspector v2 スキャン
    → EventBridge
      → SNS → メール通知

EventBridge ルール(EventPattern)

{
  "source": ["aws.inspector2"],
  "detail-type": ["Inspector2 Finding"],
  "detail": {
    "severity": ["MEDIUM", "HIGH", "CRITICAL"],
    "resources": {
      "type": ["AWS_ECR_CONTAINER_IMAGE"]
    }
  }
}

Dockerfile(各イメージ共通)

FROM amazonlinux:2023

RUN dnf -y update && \
    dnf -y install squid && \
    dnf clean all

ビルド手順(手動)

aws ecr get-login-password --region ap-northeast-1 | docker login ...
docker build -t denga-gss-cnw-ecr-repository:squid-0.1 .
docker tag ...
docker push ...

課題

課題①:最新イメージを取得しても脆弱性が検知される

ECR のスキャン結果で「修正可能」列が Yes になっているにもかかわらず、リビルドしても脆弱性が解消されない事象が発生した。

原因は Amazon Linux 2023 の releasever(リポジトリバージョン)がデフォルトで固定されている点にある。
dnf -y update だけでは最新のセキュリティパッチが適用されず、パッチ済みのバージョンが存在するにもかかわらず脆弱性が残ったままになる。

また、docker build でキャッシュが使われると、古いベースイメージのレイヤーが再利用されるため、--no-cache --pull を指定しないと最新パッケージが取得されない。

課題②:新規脆弱性発生時に既存の脆弱性も含めて全件通知される

Inspector v2 は脆弱性1件につき1つの EventBridge イベントを発行する。
そのため、新規 CVE が1件発見された場合でも、既知の脆弱性を含む全件が個別に通知され、大量のメールが届く。
例:既存 11件 + 新規 1件 → 12通のメール。

対応済みの CVE も含めて毎回全件通知されるため、どれが本当に新しい脆弱性なのか判別しにくい。

課題③:古いバージョンのイメージも脆弱性が指摘される

イメージは世代管理しており、例えば squid-0.8(旧版)と squid-0.9(現行)が ECR に共存している。
ECS では squid-0.9 のみを使用しているが、Inspector v2 はプッシュ済みのイメージを継続的にスキャンするため、使われていない squid-0.8 の脆弱性も通知され続ける。


現在の改善内容

改善①-1:Dockerfile に ARG RELEASEVER を追加(課題①への対応)

Amazon Linux 2023 では、パッケージリポジトリのバージョンを releasever(例: 2023.6.20250817)で管理している。
デフォルトではビルド時点の releasever が固定されるため、最新のセキュリティパッチを確実に取得するには明示的に指定する必要がある。

ARG RELEASEVER

RUN dnf -y update --releasever=${RELEASEVER} && \
    dnf -y install squid && \
    dnf clean all

改善①-2:build.sh を作成(課題①への対応)

最新 releasever の自動取得と --no-cache --pull によるビルドを標準化。

#!/bin/bash
VERSION="$1"
IMAGE_TAG="squid-${VERSION}"

RELEASEVER=$(docker run --rm amazonlinux:2023 bash -c \
  "rpm -q --qf '%{VERSION}\n' system-release 2>/dev/null && \
   dnf install -y 'dnf-command(check-release-update)' 2>/dev/null && \
   dnf check-release-update 2>&1" | \
  grep -oP '2023\.\d+\.\d+' | sort | tail -1)

echo "RELEASEVER: ${RELEASEVER}"
echo "IMAGE_TAG:  ${IMAGE_TAG}"

aws ecr get-login-password --region ap-northeast-1 | \
  docker login --username AWS --password-stdin 643625512109.dkr.ecr.ap-northeast-1.amazonaws.com

docker build --pull --no-cache --build-arg RELEASEVER=${RELEASEVER} -t denga-gss-cnw-ecr-repository:${IMAGE_TAG} .
docker run --rm --entrypoint rpm denga-gss-cnw-ecr-repository:${IMAGE_TAG} -q squid
docker tag denga-gss-cnw-ecr-repository:${IMAGE_TAG} 643625512109.dkr.ecr.ap-northeast-1.amazonaws.com/denga-gss-cnw-ecr-repository:${IMAGE_TAG}
docker push 643625512109.dkr.ecr.ap-northeast-1.amazonaws.com/denga-gss-cnw-ecr-repository:${IMAGE_TAG}

改善②-1:通知を CRITICAL のみに絞る(課題②への対応)

月次でパッチ適用とリビルドを行っているため、MEDIUM / HIGH は運用フロー上でカバーできる。
また MEDIUM / HIGH はノイズになっていたため、EventBridge の severity フィルターを CRITICAL のみに変更した。

{
  "detail": {
    "severity": ["CRITICAL"]
  }
}

改善③-1:Inspector ECR 再スキャン設定の見直し(課題③への対応)

Inspector v2 は以下の2つの期間のいずれか一方を満たしている限り、イメージを継続的にスキャンする:

  • イメージの再スキャン期間:最終使用日またはプル日からの経過日数
  • イメージプッシュ日の期間:ECR へプッシュされてからの経過日数

両方を超過した時点で、Inspector はそのイメージのモニタリングを停止する。

そのため、Inspector コンソールの「スキャン設定」→「コンテナイメージ」→「ECR 再スキャン設定」から期間を短く設定することで、古いバージョン(例: squid-0.8)が一定期間後にスキャン対象から外れ、実質的に現行イメージのみがスキャンされる状態にした。

現在の構成まとめ

ECR push
  → Inspector v2 スキャン(最新イメージのみ対象)
    → EventBridge(CRITICAL のみ)
      → SNS → メール通知(件数分)
脆弱性 通知
CRITICAL あり
HIGH / MEDIUM / LOW なし

さらなる改善案:Lambda + DynamoDB による重複排除

残課題

現在の構成では、Inspector がスキャンを行うたびに CRITICAL の件数分メールが届く。
新規 CVE が1件発見された場合でも、既存の CRITICAL 含む全件が個別に通知されるため、CRITICAL が5件あれば5通来る。

改善アーキテクチャ

ECR push
  → Inspector v2 スキャン
    → Inspector2 Finding イベント(1CVE=1イベント)
      → EventBridge
        → Lambda(重複チェック)
          → DynamoDB(既知CVEの記録)
            → 新規CVEのみ SNS → メール通知

Lambda の処理フロー

  1. Inspector finding イベントを受け取る
  2. CVE ID を取り出す(例: CVE-2026-42533
  3. DynamoDB に「この CVE を通知済みか」を問い合わせる
  4. 未記録 → SNS で通知 + DynamoDB に記録
  5. 記録済み → スキップ(通知しない)

DynamoDB テーブル設計

CVE ID 初回通知日時
CVE-2026-42533 2026-08-27T10:00:00Z
CVE-2026-60005 2026-08-27T10:00:00Z

重複排除キーは CVE ID のみとすることで、どのイメージ・バージョンでも同一 CVE は1回のみ通知される。


まとめ

AWS のサービス仕様上、Lambda なしでの完全な重複排除は不可能。
現実的な改善として以下を実施:

  • Dockerfile: releasever で最新パッチを確実に適用(課題①)
  • build.sh: --no-cache --pull + releasever 自動取得で標準化(課題①)
  • EventBridge: CRITICAL のみに絞って通知件数を削減(課題②)
  • Inspector 再スキャン設定: 古いイメージが一定期間後にスキャン対象外になるよう設定(課題③)

通知の完全な集約・重複排除が必要になった場合は Lambda + DynamoDB の導入を検討する。

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?