メインコンテンツへスキップ
友田 陽大
Amazon GuardDuty 本番運用
セキュリティ
AWS
GuardDuty
運用設計
Terraform

GuardDuty の誤検知とノイズを抑える運用:Suppression Rule・信頼 IP リスト・脅威リストの正しい使い分け

Amazon GuardDuty のノイズ・誤検知を本番品質で抑えるチューニング実装ガイド。Suppression Rule(既知ノイズの自動アーカイブ)・信頼 IP/エンティティリスト(既知の正規ソースから finding を出さない)・脅威リスト(既知の悪性ソースから finding を出す)の3つの道具を、症状→正しい道具のマッピングで使い分けます。抑制された finding は Security Hub/S3/Detective/EventBridge に届かず、Extended Threat Detection の相関材料にもならない——広すぎる抑制が Critical な攻撃シーケンスを丸ごと不可視化する罠と、reactive・スコープ最小・IaC 中心の運用ルールを、Terraform/CLI の実コードで解説します。

公開日
読了時間
32分
著者
友田 陽大
シェア
目次

「GuardDuty を入れたらアラートが鳴りやまない。で、全部ミュートしました」——AWS のセキュリティ運用を相談される場で、わりと聞く台詞です。

そして、これはたいてい危険な一手です。脆弱性スキャナの定期 portscan、bastion への SSH ブルートフォース、オンプレ GW 経由の通信——確かに正規の運用が finding を量産し、ダッシュボードは赤く埋まります。けれど「うるさいから型ごと消す」をやると、その finding が本来束ねるはずだった Critical な攻撃シーケンスまで、一緒に消えています。ノイズは対応の敵ですが、間違ったチューニングは攻撃そのものを隠す——これがこの記事の通底するテーマです。

この記事は、GuardDuty 本番設計のピラー記事の7章「誤検知とノイズを抑える」を、単独で一本書けるだけの深さに掘り下げるスポークです。GuardDuty のチューニングには道具が3つあり、それぞれ役割がまったく違います。この使い分けを間違えると、ノイズも減らず・コストも減らず・むしろ検知能力だけが削れる、という最悪が起きます。逆に正しく使い分ければ、**「対応すべき finding だけが残り、攻撃の文脈は失われない」**運用になります。題材として、私がマルチアカウント AWS 上のサーバーレス決済プラットフォームで IAM・可観測性・DR を横断実装した経験——実際の金銭・カーボンクレジット・地域通貨を扱うため、「ノイズに埋もれて本物の侵害を見逃す」ことが許されなかった——という視点も交えます。

この記事のルール:Suppression Rule・信頼リスト・脅威リストの仕様・制限・挙動は AWS 公式ドキュメント(2026年6月時点) に基づきます。リストの上限・対応形式・適用範囲は改定されるため、本番投入前に必ず公式の最新情報を確認してください。そしてもう一つの鉄則——チューニングは絶対に「本物の攻撃を見えなくする」方向に倒してはいけません。抑制は reactive に(繰り返し誤検知だと確認できたものだけ)・スコープを最小に・コンソールのクリックではなく IaC で(レビュー可能・再現可能に)行います。


0. メンタルモデル:3つの道具・3つの仕事

設計を始める前に、3つの道具がそれぞれ別の問題を解いていることを一行で固定します。混同が、ほぼすべての事故の原因です。

GuardDuty のチューニング道具は3つ。「既知の無害な finding パターン」を消すのが Suppression Rule、「既知の正規ソース」から finding を出さないのが信頼リスト、「既知の悪性ソース」から finding を出すのが脅威リスト。」

道具解く問題何に効くか公式の挙動
Suppression Rule(抑制ルール)正規運用が生む既知の finding パターンがうるさいfinding 型 + 絞り込み属性にマッチする新規 finding を自動アーカイブフィルタ条件にマッチした新規 finding を archive。Security Hub/S3/Detective/EventBridge に送らない
信頼 IP / エンティティリスト(Trusted list)既知の正規ソース(自社固定 IP・監視 SaaS)からの通信で finding が出る載せた IP/ドメインからの活動について finding を生成しないtrusted に載った entry については finding を生成しない
脅威リスト(Threat list)自前で「悪性」と判断したソースを検知したい載せた IP/ドメイン/ハッシュへの活動で finding を生成するthreat に載った entry に関わる活動で finding を生成する

3つの違いを、もう一段はっきりさせます。

  1. Suppression Rule は「finding の側」を見る。 「この型の finding が、この条件で出たら、それは無害だからアーカイブ」という後段のフィルタです。たとえば「Recon:EC2/Portscan が、自社脆弱性スキャナの AMI から出たら無害」。GuardDuty は finding をいったん生成してからアーカイブします(だから後述のとおり、解析コストは変わりません)。
  2. 信頼リストは「ソースの側」を見る。 「この IP/ドメインは信頼できるから、そもそも finding を生成しない」という前段のフィルタです。たとえば「自社の固定 egress IP からの通信は finding にしない」。
  3. 脅威リストは信頼リストの裏返し。 「この IP/ドメイン/ハッシュは悪性だから、関わったら finding を生成する」。自前の脅威インテリジェンスを GuardDuty の検知に持ち込む道具です。

この3点を押さえると、チューニングは 「①ノイズの正体は『finding パターン』か『ソース』か → ②パターンなら抑制・ソースなら信頼リスト → ③自前で検知を足したいなら脅威リスト」 という分岐に整理できます。そして全体を貫く制約が——どれを使っても、本物の攻撃(特に Extended Threat Detection が束ねる多段攻撃)を見えなくしてはいけないこと。順に深掘りします。


1. Suppression Rule(抑制ルール)の深掘り:何が起き、何が起きないか

最も誤解の多い道具がこれです。「抑制=finding を消す」と思っていると、消えていないものまで消えたつもりになる——そこが事故の入口です。

1.1 抑制ルールの正体は「action = ARCHIVE のフィルタ」

公式の定義はシンプルです。Suppression Rule とは、フィルタ属性と値の組み合わせ(criteria)で、マッチした新規 finding を自動的にアーカイブするルールです。GuardDuty のフィルタ機能そのものを、actionARCHIVE にして使うと抑制ルールになります(Terraform の aws_guardduty_filter でいう action = "ARCHIVE")。

公式が明示する「2条件パターン」が、設計の基本形です。第1条件に finding 型、第2条件にスコープを絞る属性(AMI・タグ・IP など)を置きます。これは偶然ではなく、公式の推奨例がすべてこの形です。

# 抑制ルールは「action=ARCHIVE のフィルタ」。CLI/API では create-filter で作る。
# 公式の2条件パターン: ①finding 型 + ②スコープを絞る属性。
# 例: 自社の脆弱性スキャナ(特定 AMI)が出す Recon:EC2/Portscan だけを抑制する。
aws guardduty create-filter \
  --detector-id "$DETECTOR_ID" \
  --name "suppress-portscan-from-vuln-scanner" \
  --action ARCHIVE \
  --rank 1 \
  --finding-criteria '{
    "Criterion": {
      "type": { "Equals": ["Recon:EC2/Portscan"] },
      "resource.instanceDetails.imageId": { "Equals": ["ami-0a7a207083example"] }
    }
  }'

フィルタの仕様(公式・要点):1つのフィルタには最低1・最大50の属性を指定でき、Equals/NotEquals は1属性あたり最大50値異なる属性どうしは AND、同一属性の複数値は AND/OR で評価されます。つまり上の例は「型が Portscan かつ AMI が一致」の AND——だからスコープが狭く絞られる。これが「型だけ」の危険な抑制との決定的な差です。

1.2 「抑制された finding」に何が起き、何が起きないか(最重要の事実)

ここが本章の核心です。公式の挙動を正確に押さえないと、運用を誤ります。

抑制された finding に起きないこと(送られない/起動しない)抑制された finding に起きること(残る)
AWS Security Hub CSPM に送られないfinding 自体は生成される(解析は止まらない)
Amazon S3 にエクスポートされない**archived(アーカイブ済み)**として保存される
Amazon Detective に送られないGuardDuty 内に90日間保存され、その間いつでも閲覧可能
Amazon EventBridge に送られない(=自動対応も発火しない)コンソールの Archived か、API ListFindingsservice.archived = true で参照可能
Malware Protection for EC2 のマルウェアスキャンを起動しない(= ETD の相関材料にはならない。3章で詳述)

公式の表現をそのまま借りれば——「抑制された finding は AWS Security Hub CSPM・Amazon S3・Amazon Detective・Amazon EventBridge に送られない。Malware Protection for EC2 を有効化していても、抑制された finding はマルウェアスキャンを起動しない」。一方で**「GuardDuty は抑制ルールにマッチしても finding を生成し続け、ただし自動的に archived としてマークする。archived な finding は90日間 GuardDuty に保存され、その期間いつでも閲覧できる」**。

この非対称が、抑制の本質です。「通知・連携の経路からは外れるが、データとしては消えていない」。だから——

# 抑制で消したつもりの finding を、archived として掘り起こして監査する。
# service.archived = true が「抑制された(またはユーザーがアーカイブした)finding」の母集合。
aws guardduty list-findings \
  --detector-id "$DETECTOR_ID" \
  --finding-criteria '{ "Criterion": { "service.archived": { "Equals": ["true"] } } }'

設計への含意:抑制は「ダッシュボードと通知を静かにする」道具であって、「検知を止める」道具ではありません。finding は90日残るので、「実は抑制で消していた中に本物が紛れていなかったか」を後から監査できます。ただし——次章で見るとおり、Extended Threat Detection はこのアーカイブ済みを相関材料にしないため、「残っているから安全」とは言い切れません。

1.3 マルチアカウントでは「管理者だけ」が抑制を作れる

公式の Note は明確です——マルチアカウント環境では、GuardDuty 管理者(委任管理者)だけが抑制ルールを作成できます。メンバーアカウントの担当者が勝手にノイズを消すことはできません。これは統制上むしろ望ましい挙動です:「誰がどの検知を消したか」が委任管理者アカウントに一元化され、レビューと監査の対象を1か所に絞れます。組織での委任管理者の立て方はマルチアカウント統制のスポーク記事で扱います。

1.4 公式の代表的な抑制ユースケース(すべて「型+絞り込み」の2条件)

公式が**「reactive に・繰り返し誤検知だと確認できた finding にのみ作れ」と明記したうえで挙げる、代表ユースケースです。共通点は例外なく「型+スコープ属性」の2条件**であること——型だけで消す例は1つもありません。

ユースケース第1条件(型)第2条件(絞り込み)なぜ無害か
オンプレ GW 経由の egressUnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWSAPI caller IPv4 address(オンプレ GW の IP/CIDR)Outposts や VPC VPN で内向きに抜ける正規構成。複数 IP は条件を追加
脆弱性スキャナの portscanRecon:EC2/PortscanInstance image ID(スキャナの AMI)または Tag自社の脆弱性評価ツールが意図的に portscan している
bastion への SSH ブルートフォースUnauthorizedAccess:EC2/SSHBruteForceInstance tag value(bastion を識別するタグ)bastion は外から叩かれるのが想定挙動
意図的に公開した web サーバRecon:EC2/PortProbeUnprotectedPortInstance tag key(公開サーバを識別するタグ)web サーバは公開ポートを持つのが正常
coredns の DNS 重複(Runtime)Trojan:Runtime/*!DNS 等の DNS 系 Runtime findingExecutable path または Executable SHA-256(DNS サーバ pod のプロセス)K8s は coredns 等が pod として DNS を引くため、pod 側とサーバ pod 側で2重に DNS イベントが出る

最後の coredns のケースだけ補足します。公式によれば、Kubernetes クラスタは coredns のような DNS サーバを pod として動かすため、各 DNS ルックアップにつき2つの DNS イベント(pod 由来とサーバ pod 由来)が記録され、Backdoor:Runtime/C&CActivity.B!DNS などの重複 findingを生みます。これを executablePathexecutableSha256(任意で第3条件に Kubernetes container image)で絞って抑制する——これも「型だけ」ではなくプロセス単位まで絞り込む好例です。

# coredns 由来の DNS finding 重複を、DNS サーバ pod のプロセスに絞って抑制。
# 型だけで消すと本物の C&C 通信まで消える。executableSha256 で「自分の coredns」に限定する。
aws guardduty create-filter \
  --detector-id "$DETECTOR_ID" \
  --name "suppress-coredns-dns-duplicates" \
  --action ARCHIVE \
  --rank 2 \
  --finding-criteria '{
    "Criterion": {
      "type": { "Equals": ["Backdoor:Runtime/C&CActivity.B!DNS"] },
      "service.runtimeDetails.process.executableSha256": { "Equals": ["<your-coredns-sha256>"] }
    }
  }'

2. Suppression Rule を IaC で管理する(Terraform)

コンソールのクリックで抑制ルールを作るのはアンチパターンです。「誰が・いつ・なぜ・どの条件で検知を消したか」がレビューできず、再現もできません。抑制は検知能力を削る変更なので、最もレビューが必要なはずの操作です。だから IaC で。

# 抑制ルール = action = "ARCHIVE" の aws_guardduty_filter。
# action の許容値は "ARCHIVE"(抑制)か "NOOP"(通常フィルタ)。
# 公式の2条件パターンを criterion 2つで表現する。
resource "aws_guardduty_filter" "suppress_scanner_portscan" {
  name        = "suppress-portscan-from-vuln-scanner"
  detector_id = aws_guardduty_detector.this.id
  action      = "ARCHIVE" # ← これが「フィルタ」を「抑制ルール」にする
  rank        = 1         # フィルタの適用順(小さいほど先に評価)

  # なぜ消すかを description に必ず残す(レビューと棚卸しのための監査証跡)。
  description = "Vuln scanner (AMI ami-0a7a2070...) intentionally port-scans; benign. Reactive, scoped by imageId."

  finding_criteria {
    # 第1条件: finding 型を1つに固定(型を丸ごと広く消さない)。
    criterion {
      field  = "type"
      equals = ["Recon:EC2/Portscan"]
    }
    # 第2条件: スキャナの AMI に限定(ここが無いと全 Portscan を消す危険な抑制になる)。
    criterion {
      field  = "resource.instanceDetails.imageId"
      equals = ["ami-0a7a207083example"]
    }
  }
}

このコードの設計判断を明示します。

  • action = "ARCHIVE" が抑制の本体。 Terraform の aws_guardduty_filteraction"ARCHIVE"(抑制)か "NOOP"(保存はするがアーカイブしない通常フィルタ)の2択です。抑制したいなら ARCHIVE
  • criterion は必ず2つ以上。 公式パターンどおり「型+絞り込み」。type だけの criterion 1つで終わらせると、それは「型を丸ごと消す」最も危険な抑制になります(3章の罠)。
  • description に「なぜ・reactive である根拠」を残す。 抑制は検知を削る操作なので、レビュー時に「これは本当に繰り返し誤検知だったのか」を判断できる証跡を必ず残します。
  • rank で適用順を意識する。 複数フィルタがあるときの評価順。抑制ルールが意図せず広い finding を巻き込まないよう、スコープの狭いものを意識して管理します。

検証経路(公式):作った抑制ルールが「狙った finding だけ」を消し「それ以外」を消さないことは、create-sample-findings で各型のサンプルを発火させ、service.archived = true に落ちる finding と EventBridge に届く finding を見比べれば検証できます(サンプルは [SAMPLE] 接頭辞と service.additionalInfo.sample = true で見分けられます)。「検証経路を先に作る」原則は、検知を消す変更でこそ効きます。


3. THE 罠:広すぎる抑制が Extended Threat Detection を盲目にする

ここがこの記事で最も重要な一節です。抑制ルールの本当の危険は「ノイズが減りすぎる」ことではなく、**「ノイズと一緒に、攻撃の文脈そのものを消す」**ことにあります。

3.1 公式が明言する挙動

公式の Note を正確に引きます——「攻撃シーケンスのためにイベントを相関する際、Extended Threat Detection はアーカイブされた finding を考慮しない。これには Suppression Rule によって自動的にアーカイブされた finding も含まれる」

つまり、Extended Threat Detection(ETD)が「弱いシグナルを24時間窓で相関して多段攻撃を1つの Critical な攻撃シーケンスに束ねる」仕組みは、抑制でアーカイブした finding を材料に使えません。1章で見たとおり、抑制された finding は90日 GuardDuty に残りますが——「残っている」ことと「相関に使える」ことは別なのです。

3.2 公式が挙げる具体例(EKS の型丸ごと抑制)

公式は具体例まで挙げています——「特定の既知アクティビティを狙うのではなく、EKS クラスタ関連の finding をすべてアーカイブする抑制ルールを作ると、GuardDuty は『脅威アクターがコンテナを悪用 → 特権トークンを取得 → 機密リソースにアクセス』という攻撃シーケンスを、それらの finding を使って検知できなくなる」

これを絵にすると、こうです。

                              ┌─ 個別 finding A(弱いシグナル)─┐
  攻撃の連鎖(多段)─────────────┼─ 個別 finding B(弱いシグナル)─┼─→ ETD が相関 → AttackSequence(Critical 9.0-10.0)
                              └─ 個別 finding C(弱いシグナル)─┘
                                          ▲
       「EKS finding を型ごと全部アーカイブ」する広い抑制ルール
                                          │
                              A・B・C が archived に落ちる
                                          │
                                          ▼
                       ETD はアーカイブ済みを相関材料にしない
                                          │
                                          ▼
              AttackSequence は「材料が無い」ため、二度と束ねられない(不可視化)

誤検知を消したつもりが、最も重大な Critical の多段攻撃を、自分の手で検知不能にしている——これが抑制ルールの罠です。個別 finding は「中くらいの不審な操作」に見えるので、つい広く消したくなる。けれどその一つひとつが、ETD にとっては攻撃シーケンスを束ねる材料なのです。

3.3 公式の推奨と、運用に落とした「やってよい/いけない」

公式は2点を推奨します——①既知の信頼できるアクティビティからのアラートを減らすために抑制ルールは使い続けてよい。②ただし抑制ルールは『GuardDuty に finding を出してほしくない特定の挙動』に絞れ。加えて Best practice として**「reactive に、自分の環境で繰り返し誤検知だと確認できた finding にのみ作れ」**。「念のため先に消しておく」は明確に禁物です。

これを運用ルールに落とすと、こうなります(ETD スポーク記事の監査表と同じ思想です。あちらは ETD 側から、本記事はチューニング側から同じ罠を扱っています)。

✅ やってよい抑制(スコープを絞った)❌ やってはいけない抑制(型を丸ごと)
Recon:EC2/Portscanスキャナの AMI/タグに限定Recon:* を型ごと全アカウントで抑制
UnauthorizedAccess:EC2/SSHBruteForce特定 bastion のタグに限定EKS/S3 関連 finding をリソース無指定で広く抑制
InstanceCredentialExfiltration.OutsideAWSオンプレ GW の固定 IP に限定攻撃シーケンスの材料になり得る型を予防的に抑制

鉄則は「抑制はリソース/IP/タグで絞ったピンポイントに限る。型を丸ごと消すのは、ETD の目を潰す行為」。では「型単位でノイズだけ静かにしたい」ときはどうするか——**答えは『抑制(=アーカイブ=ETD から不可視)』ではなく、EventBridge の通知側フィルタで『通知だけ静かにする』**ことです。EventBridge ルールの severity 数値マッチや型ルーティングで「Slack に流さない」を実現すれば、finding は GuardDuty 内にアクティブなまま残り、ETD の相関材料として生き続けます

使い分けの一行サマリ「検知を消す」なら抑制(ただしピンポイントに)/「通知だけ静かにする」なら EventBridge フィルタ。ノイズ低減の大半は、実は後者で十分です。抑制は「誤検知が構造的に確定している、絞り込めるノイズ」だけに使う最終手段だと考えてください。

3.4 既存の抑制ルールを棚卸しする(監査スクリプト)

「広すぎる抑制が無いか」は定期的に棚卸しすべきです。action = ARCHIVE のフィルタのうち、criterion型(type)だけでリソース絞り込みを持たないものが危険信号です。

# 委任管理者アカウントで実行:全フィルタを列挙し、action=ARCHIVE のものを監査する。
# criterion が type だけ(resource.* / IP / タグ無し)の抑制が「型丸ごと」の危険信号。
DETECTOR_ID="$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)"

for FILTER in $(aws guardduty list-filters --detector-id "$DETECTOR_ID" \
                  --query 'FilterNames[]' --output text); do
  echo "=== ${FILTER} ==="
  aws guardduty get-filter --detector-id "$DETECTOR_ID" --filter-name "$FILTER" \
    --query '{name:Name, action:Action, criterion:FindingCriteria.Criterion}'
done

監査の着眼点actionARCHIVE で、Criterion のキーが type だけのものを探します。特に EKS / S3 / IAM 系を型ごと消している抑制は、対応する攻撃シーケンス(それぞれ AttackSequence:EKS/CompromisedClusterS3/CompromisedDataIAM/CompromisedCredentials)を不可視化している可能性が高い。発見したら、リソース指定で絞り込むか、抑制をやめて通知側フィルタへ移します。


4. 信頼リスト・脅威リストの深掘り:エンティティリストと IP リスト

3つ目・4つ目の道具がリストです。抑制が「finding の側」を見るのに対し、リストは**「ソースの側」**を見ます——「この IP/ドメインからは finding を出さない(信頼)/出す(脅威)」。

4.1 エンティティリスト(推奨)vs レガシー IP リスト

公式は2つの実装を提示し、エンティティリスト(entity list)を推奨しています。

エンティティリスト(推奨)レガシー IP リスト
載せられるものIP アドレス・ドメイン名・SHA-256 ファイルハッシュIP アドレスのみ
権限モデル直接 S3 アクセス + 単一の IAM 権限(複数リージョンで IAM ポリシーサイズを圧迫しない)サービスリンクロール(SLR)。リージョンごとに IAM ポリシー更新が必要
ハッシュ脅威エンティティリストでのみ SHA-256 可(信頼リストには不可)ハッシュ不可

設計への含意:新規構築ならエンティティリスト一択です。レガシー IP リストは IP しか載らず、SLR ベースでリージョン数だけ IAM ポリシーが肥大化します。エンティティリストは単一 IAM 権限で済み、ドメインやハッシュ(脅威リストのみ)も扱えます。公式も移行手順(エンティティリストを追加・アクティベートしてから、対応する IP リストを deactivate/delete)を案内しています。

4.2 リストの制限(公式・正確に)

ここは数字を絶対に発明してはいけないところです。公式が明記する制限を正確に:

制限値(公式)
信頼エンティティリストアカウント×リージョンあたり1つまで
信頼 IP リストアカウント×リージョンあたり1つまで
脅威リスト(エンティティ+IP)アカウント×リージョンあたり最大6つ
IP バージョンIPv4 のみ(IPv6 は非対応)
対象アドレス/ドメイン公開ルーティング可能な(publicly routable)IP/ドメインのみ
ファイル最大サイズ35 MB
反映時間アクティベート/非アクティベート/削除は約15分で完了(場合により最大40分

per-list の entry 数は「公式で要確認」:1つのリストに何件の IP/ドメインを載せられるか、という上限は本ガイドの一覧には書かれていません。公式は「エンティティリストと IP リストでクォータが異なる」とし、詳細をGuardDuty quotasに委ねています。件数の上限が要件に絡む場合は、必ず quotas ページで最新値を確認してください(ここで具体的な数字を書くと、すぐ陳腐化し誤情報になります)。

4.3 適用範囲の違い(DNS に注意)と優先順位

リストには「どの finding に効くか」の範囲があり、エンティティリストと IP リストで違います。ここを取り違えると「DNS の悪性ドメインを IP リストに入れたのに効かない」事故になります。

エンティティリストIP リスト
CloudTrail finding適用適用
VPC Flow Logs finding適用適用
Route 53 Resolver DNS クエリログ finding適用非適用

公式どおり——エンティティリストの entry は CloudTrail・VPC Flow Logs・Route 53 Resolver DNS クエリログの finding に適用される。IP リストの entry は CloudTrail・VPC Flow Logs に適用されるが、DNS クエリログ finding には適用されない。ドメインを扱うなら(DNS に効かせたいなら)エンティティリスト一択である、もう一つの理由です。

優先順位も公式が明記——同じ IP/ドメインを信頼リストと脅威リストの両方に入れた場合、信頼リストが優先されます。GuardDuty は finding を生成しません。意図せず「悪性として登録したのに、別の信頼リストにも入っていて検知されない」という事故を避けるため、信頼と脅威で entry が衝突していないかは管理対象にします。

さらに適用プランの例外——リストは**基盤データソース+保護プランの全体に効きますが、Runtime Monitoring だけは例外(適用されない)**です。Runtime Monitoring のプロセス/システムコール検知は、リストによる信頼/脅威の上書き対象外、と理解しておきます。

4.4 マルチアカウントと「再アクティベート」の運用

2つの運用上の落とし穴があります。

  1. マルチアカウントでは管理者だけがリストを管理。 公式どおり——マルチアカウント環境では、GuardDuty 管理者アカウントだけがリストを管理でき、設定は自動的にメンバーアカウントに適用される。管理者の脅威ソースに載った悪性 IP/ドメインで finding が生成され、管理者の信頼ソースに載ったものでは生成されない、がメンバー全体に効きます。抑制ルールと同じく統制が管理者に一元化されます。
  2. S3 のファイルを編集したら、必ず再アクティベート。 公式の明記——リストの S3 バケット内のエントリを追加・更新したら、リストを再度アクティベートしなければならない。「S3 を上書きしたから自動で反映される」と思い込むと、新しい entry が効いていない状態が(4.2 の15〜40分とあわせて)生まれます。IaC では「S3 オブジェクトの更新」と「リストの再アクティベート」を1つの apply で連動させるのが安全です。

4.5 信頼 IP / 脅威リストを IaC で管理する(Terraform)

エンティティリストは新しい機能のため、2026年6月時点の AWS プロバイダには専用リソースが(まだ)見当たりません——aws_guardduty_ipset(信頼 IP)と aws_guardduty_threatintelset(脅威)は IP リスト/脅威リスト相当です。エンティティリストを Terraform で完全管理したい場合は、専用リソースの有無を必ず最新のプロバイダで確認してください(無ければ S3 オブジェクト+API/CLI で管理し、再アクティベートをパイプラインに組み込む)。ここでは確実に存在する2リソースで示します。

# ── 信頼 IP リスト(aws_guardduty_ipset)──
# 自社の固定 egress IP など「正規ソース」を登録。ここからは finding を生成しない。
# format の許容値: TXT | STIX | OTX_CSV | ALIEN_VAULT | PROOF_POINT | FIRE_EYE
resource "aws_guardduty_ipset" "trusted" {
  detector_id = aws_guardduty_detector.this.id
  name        = "corporate-egress"
  format      = "TXT"
  # S3 上のリストファイル。中身を更新したら activate を打ち直す必要がある(4.4 参照)。
  location    = "https://s3.amazonaws.com/${aws_s3_object.trusted_ips.bucket}/${aws_s3_object.trusted_ips.key}"
  activate    = true # Active にして初めて検知に反映される
}

# ── 脅威リスト(aws_guardduty_threatintelset)──
# 自前で「悪性」と判断した IP を登録。一致すると .Custom メカニズムで finding が出る。
resource "aws_guardduty_threatintelset" "custom_threats" {
  detector_id = aws_guardduty_detector.this.id
  name        = "org-custom-threat-feed"
  format      = "TXT"
  location    = "https://s3.amazonaws.com/${aws_s3_object.threat_ips.bucket}/${aws_s3_object.threat_ips.key}"
  activate    = true
}

# リストファイル本体。content のハッシュが変わると Terraform が差分を検知し、
# 依存する ipset/threatintelset の再 apply(= 再アクティベート)が走るよう構成する。
resource "aws_s3_object" "trusted_ips" {
  bucket  = aws_s3_bucket.sec_config.id
  key     = "guardduty/trusted-ips.txt"
  content = "198.51.100.0/24\n203.0.113.10\n" # IPv4 のみ・公開アドレスのみ
}

再アクティベートを IaC で落とし込む:上のように「S3 オブジェクトの content(または etag)変更 → ipset/threatintelset の再 apply」が連鎖するよう依存を張ると、4.4 の『編集したら再アクティベート』を手作業に頼らず保証できます。手で S3 を上書きして「反映されない」と悩む典型的な事故を、構造で消せます。


5. 決定フレームワーク:症状 → 正しい道具

ここまでの3(+1)道具を、「ノイズの症状」から逆引きできる表にまとめます。チューニングの現場で最初に開くべき早見表です。

症状(ノイズの正体)正しい道具具体策やってはいけない代替
自社スキャナの定期 portscan がうるさいSuppression RuleRecon:EC2/Portscan を AMI/タグで絞って ARCHIVERecon:* を型ごと抑制(ETD を盲目化)
bastion への SSH ブルートフォースが想定挙動Suppression RuleSSHBruteForce を bastion タグで絞って ARCHIVE型ごと抑制
自社の固定 egress IP からの通信で finding が出る信頼リスト該当 IP を信頼エンティティ/IP リストに登録その IP 由来の型を抑制(他ソースまで消える)
監視 SaaS のドメインへの DNS 問い合わせがうるさい信頼エンティティリストドメインを信頼エンティティリストに登録(IP リストは DNS に効かない)信頼 IP リストに入れる(DNS 非適用で効かない)
自前で「これは悪性」と判断した IP/ドメインを検知したい脅威リスト脅威エンティティ/IP リストに登録(.Custom で finding 化)抑制(逆方向の道具)
既知マルウェアのハッシュで検知したい脅威エンティティリストSHA-256 を脅威エンティティリストに登録信頼リスト/IP リスト(ハッシュ非対応)
「型単位でノイズだけ静かにしたい」(攻撃文脈は残したい)EventBridge 通知フィルタ通知ルールの severity/型でフィルタ。finding は GuardDuty に残す抑制(アーカイブ=ETD から不可視)

5.1 コストの誤解を正す(最重要のお金の話)

最後に、最も多い誤解を潰します——「ノイズを抑制すれば GuardDuty が安くなる」は誤りです。

GuardDuty の課金は『解析したログ量』に対して発生します(CloudTrail イベント数・VPC/DNS の GB・vCPU 時間など)。finding の数で課金されるのではありません。だから:

  • Suppression Rule はコストを1円も下げません。 1章のとおり、抑制された finding も生成されています(解析は止まっていない)。アーカイブは「通知経路から外す」だけで、解析量は不変です。
  • 信頼リストも解析量は減りません。 信頼ソースについて finding を生成しないだけで、そのトラフィックのログ解析自体は行われています。finding は減りますが、データは依然として解析され、課金されます。

結論チューニング(抑制・リスト)は「ノイズ削減・誤検知削減・検知精度の調整」の道具であって、「コスト削減」の道具ではありません。GuardDuty のコストを下げたいなら、抑制ではなく保護プランの選定(Runtime Monitoring を重要ワークロードに限定する等)で攻めます——詳しくはコスト最適化のスポーク記事へ。「アラートがうるさい→抑制すれば安くなる」という二重の勘違いを、ここで断ち切ってください。


6. チューニングのランブック:測る → 特定 → 最小スコープで適用 → レビュー

道具と判断軸が揃ったので、繰り返し回せる運用手順に落とします。冪等で・レビュー可能で・IaC 中心、が原則です。

Step 1. 測る(ノイズのベースラインを取る)

まず「何が・どれだけ・どこから」うるさいかを定量化します。感覚で抑制を作らない。

# 直近のアクティブな finding を型別に集計し、ノイズの上位を特定する。
# (ListFindings → GetFindings で型を取得して集計するのが基本。ここは骨子)
aws guardduty list-findings --detector-id "$DETECTOR_ID" \
  --finding-criteria '{ "Criterion": { "service.archived": { "Equals": ["false"] } } }' \
  --query 'FindingIds' --output text
# 取得した finding を GetFindings で型・ソース IP・リソースまで割り、上位ノイズを定量化する。

Step 2. 特定する(「パターン」か「ソース」か、reactive か)

上位ノイズそれぞれについて、0章の分岐で道具を決めます。

  • 同じ finding 型が、特定リソース(AMI/タグ)で繰り返し出る → Suppression Rule(型+絞り込み)。かつ「繰り返し誤検知だと確認できた」reactive な根拠があること
  • 特定の正規ソース IP/ドメインから出ている → 信頼リスト(ドメインや DNS が絡むならエンティティリスト)。
  • 型単位で静かにしたいだけ(攻撃文脈は残す) → 抑制ではなく EventBridge 通知フィルタ。

Step 3. 最小スコープで適用する(IaC)

決めた道具を、可能な限り狭いスコープで IaC に書きます(2章・4.5 のとおり)。抑制なら必ず「型+リソース絞り込み」の2条件、description に reactive の根拠。リストなら S3 更新と再アクティベートを連動。

Step 4. レビューする(ETD を盲目化していないか)

適用後、**「この変更が攻撃シーケンスの材料を消していないか」**を必ず確認します。

  • 3.4 の監査スクリプトで、action=ARCHIVE かつ type だけのフィルタが増えていないか棚卸し。
  • 抑制した型が AttackSequence:* の材料になり得るか(EKS/S3/IAM 系は特に注意)を確認。材料になり得るなら、抑制ではなく通知フィルタに切り替え
  • 信頼/脅威リストで entry の衝突(同じ IP が両方に)が無いか確認(信頼が優先される事故を防ぐ)。

冪等性とレビュー可能性:このランブックは全ステップがコードと CLIで完結します。抑制ルールもリストも Terraform の apply何度流しても同じ状態に収束し(冪等)、plan の差分がそのままレビュー対象になります。「コンソールで誰かがこっそり検知を消していた」という、セキュリティ運用で最悪のサイレント変更を、構造的に排除できます。これは決済基盤で「正しさを注意深さではなく仕組みで担保する」のと同じ発想です。


7. まとめ:GuardDuty チューニング チートシート

迷ったときの早見表です。

  • 道具は3つ・仕事も3つSuppression Rule=既知の無害なfinding パターンを自動アーカイブ/信頼リスト=既知の正規ソースから finding を出さない/脅威リスト=既知の悪性ソースから finding を出す。「パターンか、ソースか」で道具が決まる。
  • 抑制された finding に起きること/起きないこと:Security Hub CSPM・S3・Detective・EventBridge に送られない、Malware Protection for EC2 も起動しない。でも finding は生成されarchived として90日保存(service.archived = true で参照可)。抑制は検知を止めない、通知を止めるだけ
  • 抑制は「型+絞り込み」の2条件で:公式の全ユースケースが型+AMI/タグ/IP/プロセスの2条件。type だけの抑制は最も危険
  • THE 罠(最重要)ETD はアーカイブ済み(抑制で自動アーカイブされたものを含む)finding を相関材料にしない。EKS 等を型ごと消す広い抑制は、AttackSequence:*(Critical 9.0-10.0)を丸ごと不可視化する。抑制は reactive に・特定挙動へ絞る。型単位で静かにしたいだけなら抑制ではなく EventBridge 通知フィルタで。
  • リストはエンティティリストが推奨:IP/ドメイン/SHA-256(ハッシュは脅威リストのみ)・単一 IAM 権限。レガシー IP リストは IP のみ・SLR。信頼エンティティ1+信頼 IP 1、脅威リスト最大6(アカウント×リージョン)。IPv4 のみ・公開アドレス/ドメインのみ・35 MB・編集後は再アクティベート(約15分、最大40分)
  • 適用範囲:エンティティリストは CloudTrail/VPC/DNS に適用、IP リストは CloudTrail/VPC のみ(DNS 非適用)。信頼が脅威に優先。リストは Runtime Monitoring 以外の全プランに適用。
  • マルチアカウント:抑制ルールもリストも委任管理者だけが管理(統制が一元化)。
  • コストの誤解を捨てる抑制も信頼リストも GuardDuty コストを下げない(課金は finding 数ではなく解析量)。コスト削減は保護プラン選定で。
  • ランブック:測る → パターン/ソースを特定(reactive か)→ 最小スコープで IaC 適用 → ETD を盲目化していないかレビュー。コンソールのクリックではなく Terraform/CLI で

GuardDuty のチューニングは「うるさいアラートを黙らせる作業」ではありません。「対応すべき finding だけを残し、攻撃の文脈は一切失わない」という、検知能力を削らずにノイズだけを削る精密な運用です。最大の落とし穴は、ノイズと一緒に Critical な攻撃シーケンスの材料を消してしまうこと。だからこそ——抑制はピンポイントに・reactive に・IaC で、が効きます。

私はマルチアカウントのサーバーレス決済プラットフォームで、実際の金銭・カーボンクレジット・地域通貨を扱う基盤の IAM・可観測性・DR を横断実装し、「正しさ」を運用の注意深さではなくコードの構造と冪等性で担保してきました。GuardDuty のチューニングも同じ思想で設計します——①ノイズをまず定量化し、②パターンかソースかで道具を選び、③最小スコープで IaC に落とし、④ETD を盲目化していないかをレビューで担保する。「全部ミュート」して攻撃まで消す事故を、構造で防ぎます。

「自社の GuardDuty、アラートがうるさいけど何を消していいか分からない」——Suppression Rule・信頼/脅威リストの設計、ETD を盲目化しない抑制の絞り込み、EventBridge 通知フィルタとの使い分け、IaC 化と監査の仕組みまで、一人 ×生成AI(Claude Code)で速く・安全に伴走できます。 要件の整理段階からでも、お気軽にご相談ください。


参考(公式ドキュメント)

  • Suppression rules in GuardDuty — 抑制=自動アーカイブ・送られない先(Security Hub/S3/Detective/EventBridge)・90日保存・service.archived・管理者のみ作成・ETD との相互作用・代表ユースケース(型+絞り込みの2条件)・reactive 推奨
  • Customizing threat detection with entity lists and IP address lists — エンティティリスト(推奨)vs IP リスト・信頼/脅威の上限(1/1/最大6)・IPv4 のみ・公開アドレスのみ・DNS 適用差・信頼優先・再アクティベート(15〜40分)・35 MB・Runtime Monitoring 例外・対応形式
  • Filtering findings in GuardDuty — フィルタ属性 1〜50・Equals/NotEquals 最大50値・属性は AND・type/resource.instanceDetails.imageId/tags.key/tags.value/service.action.awsApiCallAction.remoteIpDetails.ipAddressV4 等の正確な JSON フィールド名・service.archived
  • aws_guardduty_filter (Terraform AWS Provider)actionARCHIVE/NOOP)・rankfinding_criteria { criterion { field, equals/not_equals/... } }
  • aws_guardduty_ipset / aws_guardduty_threatintelset — 信頼 IP リスト/脅威リストの IaC 管理(formatlocationactivate)。エンティティリスト専用リソースの有無は最新プロバイダで要確認
  • GuardDuty quotas — リストごとの entry 件数など、本文に書かれていないクォータの正確な最新値
友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事の実装を、案件として承ります

GuardDuty のコスト最適化・誤検知チューニング監査

課金ドライバーを分解してムダを削り、Suppression Rule・信頼/脅威リストで『攻撃を見落とさずノイズだけを下げる』。請求と検知品質の両方を最適化する監査を提供します。

プロジェクト単位(請負)・技術顧問のどちらにも対応可能です。まずは30分の無料技術相談から。