2026年10月9日
この記事をシェア
AMIを外部のAWSアカウントへ共有する。VPCフローログを削除する。MFAなしでコンソールにサインインする。どれも、あるアカウントでは毎週の管理業務で、別のアカウントでは起きただけで調査が必要な操作です。開発用のサンドボックスでAMIを取引先に渡すのは普通のことでも、顧客データを置いた本番アカウントで同じ操作が出たら、まず誰がやったのかを確かめたくなります。
2026年9月4日、AWSはAmazon GuardDutyにCustom Detection Rulesを追加しました。この「アカウントによって意味が変わる操作」を検知するための、任意で有効にするルール群です。この記事では、新機能の中身を一次資料で確認したうえで、どの操作を、どのアカウントで検知し、誰が確認するのかという運用の決め方を、試験運用から本番化、見直しまでの順で書きます。
※2026年10月10日時点の公開情報(AWSの発表、GuardDutyユーザーガイド、CLIリファレンス)に基づきます。僕はこの機能をまだ自分の環境で動かしていません。手元のAWS CLI v1(1.44系)にはこの機能のサブコマンドがまだ入っていなかったため、本文のコマンドはドキュメントから引いたもので、実行結果や画面は載せていません。シナリオに出てくるアカウント構成は説明用の仮想例です。
同じ操作でも、アカウントによって意味が変わる
説明のために、次のような3つのアカウントを持つ組織を考えます。
| 操作 | 開発用サンドボックス | ログ集約アカウント | 本番(顧客データあり) |
|---|---|---|---|
| AMIを外部アカウントへ共有 | 取引先への受け渡しで発生する | 起きない | 起きないはず |
| VPCフローログの削除 | 環境の作り直しで発生する | 起きないはず | 起きないはず |
| IAMユーザーへのAdministratorAccess付与 | 検証で発生することがある | 起きない | 変更管理を通したときだけ |
従来のGuardDutyの検知結果の多くは、既知の悪性IPとの通信や、普段と違う場所からのAPI呼び出しのように、どの環境で起きても怪しいものを対象にしてきました。AWSのドキュメントも、Custom Detection Rulesについて「疑わしいのは、その操作を予定していないアカウントだけ」という種類の活動を拾うためのものだと説明しています。
つまり、この機能で増えるのは検知の種類というより、「このアカウントではこれは起きない」という業務上の想定を、検知の設定として書き込む場所です。想定を書くのは利用者なので、ルールを有効にする前に、アカウントごとの「起きないはずの操作」を言葉にしておく必要があります。
Custom Detection Rulesで決められること、決められないこと
名前に「Custom」と付いていますが、利用者が検知ロジックを書く機能ではありません。ルールはGuardDutyが作って維持し、利用者はそれをどのアカウントで、どのモードで動かすかを決めます。ドキュメントの用語を整理するとこうなります。
| 用語 | 意味 | 利用者が決めること |
|---|---|---|
| ルール(Rule) | GuardDutyが所有・維持する検知。1つの攻撃手法を対象にする | どれを使うか |
| 関連付け(Association) | ルールとアカウントの結びつき。関連付けのないルールは評価されない | どのアカウントに付けるか |
| モード(Mode) | live(検知結果を出す)と dry run(CloudWatchメトリクスだけ出す) | 試すか、本番で使うか |
| 組織設定(Organization configuration) | 委任管理者がメンバーアカウントへ一括で適用する設定 | 対象の含める・除くリスト |
| シグナル(Signal) | ルールに一致した1回の出来事。同じ戦術・サービス・手法のものは1つの検知結果にまとめられる | なし(GuardDutyが集約する) |
検知ロジックは見ることができます。コンソールでルール名を選ぶと詳細タブに条件が表示され、APIでは GetCustomDetectionRule の応答の Definition.Expression にSQLの条件式が入っています。条件の編集や、自前のルールの追加については、ドキュメントとAPIリファレンスを見た範囲では、それにあたる操作は見当たりませんでした。「自分の環境向けに条件を少しだけ変えたい」という要望には、今のところ応えない機能だと考えておくほうが安全です。
対象はCloudTrailの管理イベントだけ
現時点でルールが読むデータはCloudTrailの管理イベントです。EC2やEKS上の挙動を見るRuntime Monitoring、S3のデータイベントを見るS3 Protection、AI Protectionなどの保護プランとは別の機能で、どれかを有効にしたからといって、もう一方が付いてくるわけではありません。
ドキュメントで目立たないものの、運用上は大事な注意が一つあります。CloudTrailのイベントでは、機密になりうるフィールドの値を、送り元のサービスが伏せて記録することがあります。ルールの条件が伏せられたフィールドに依存していると、操作が実際に起きていてもルールは一致しません。ドキュメントは、この機能は検知の仕組みであって完全な監査記録ではない、特定のAPI呼び出しがあったかを確かめるならCloudTrailを見るように、と明記しています。
ルールの例と、MFAルールを読むときの注意
発表時点では35ルール、26種類の検知結果、MITRE ATT&CKの10戦術に対応すると説明されています。ルールは追加・改良されていくので、最新の一覧は ListCustomDetectionRules で確認するのが正式な方法です。ドキュメントの一覧から、冒頭の仮想例に関係するものを抜き出しておきます。
| シグナル名 | 検知結果のタイプ | 重大度 |
|---|---|---|
AMIExternalAccess | Exfiltration:EC2/TransferDataToCloudAccount | HIGH |
EBSSnapshotExternalAccess | Exfiltration:EC2/TransferDataToCloudAccount | HIGH |
VPCFlowLogsDeleted | DefenseImpairment:EC2/DisableOrModifyTools | HIGH |
DNSQueryLogsDeleted | DefenseImpairment:Route53Resolver/DisableOrModifyTools | MEDIUM |
AdminPolicyAttachedToUser | PrivilegeEscalation:IAM/AccountManipulation | HIGH |
IAMAccessKeyCreated | Persistence:IAM/AccountManipulation | LOW |
ConsoleLoginWithoutMFA | InitialAccess:IAM/ValidAccounts | MEDIUM |
注意したいのが ConsoleLoginWithoutMFA です。名前からはコンソールへのサインインが対象だと読めますが、ルートユーザー、IAMユーザー、IAM Identity Centerなどのフェデレーション経由のサインインのうち、どれを条件に含んでいるかは名前だけでは分かりません。アクセスキーを使ったAPI呼び出しは、コンソールサインインではないので、このルールの範囲外と考えるのが自然です。「MFAなしの操作はこれで全部拾える」と受け取らず、有効にする前に Definition.Expression を読んで、自社で使っているサインイン方式が条件に入っているかを確かめてください。
# 重大度HIGHのルールを一覧する(AWS CLI v2の新しい版が必要)
aws guardduty list-custom-detection-rules \
--filters Name=severity,Values=HIGH \
--query 'Rules[].{Id:RuleId,Name:Name,Tactic:Tactic,Service:Service}' \
--output table
# 1つのルールの検知条件(SQL)を読む
aws guardduty get-custom-detection-rule --rule-id <ルールID> \
--query 'Definition.Expression' --output text
上の2つのコマンドは、CLIリファレンスとユーザーガイドの記載に沿って書いたものです。get-custom-detection-rule の引数名は、APIリファレンスの GetCustomDetectionRule から対応させています。僕の環境では実行していません。
dry runで観測するのは、件数と業務上の理由
ルールには2つのモードがあります。liveは一致したら検知結果を出し、期限はありません。dry runは検知結果を出さず、一致した回数をCloudWatchメトリクスとして出すだけで、関連付けから14日で自動的に終わり、ルールは無効の状態に戻ります。
観測表の列を先に決める
dry runのメトリクスが教えてくれるのは「何回一致したか」までです。件数だけ見ていると、「多いから誤検知」「少ないから本番化してよい」という判断になりがちですが、本当に知りたいのは一致した操作それぞれに業務上の理由があったかどうかです。メトリクスが立った日時を手がかりにCloudTrailで該当イベントを引き、次のような表に書き込んでいきます。
| ルール | 対象アカウント | 想定外の操作 | 実行主体 | 変更予定との一致 | 調査担当 |
|---|---|---|---|---|---|
| AMIの外部共有 | 本番 | (例)ModifyImageAttributeで外部アカウントIDを追加 | (例)CI用のIAMロール | (例)変更票あり/なし | (例)インフラ担当 |
| フローログの削除 | ログ集約 | (例)DeleteFlowLogs | (例)IaCのデプロイロール | (例)環境の作り直しと一致 | (例)セキュリティ担当 |
「変更予定との一致」の列が埋まらない行が出たら、そのルールは本番化の候補です。逆に、IaCのデプロイロールのような決まった主体が定期的に引っかかるなら、そのアカウントでは「起きないはずの操作」ではなかったことになります。条件を編集できない以上、対処は対象アカウントから外すか、その操作を別のアカウントへ移すかのどちらかになります。
14日の中に、月に一度の作業を入れる
dry runは14日で終わるので、観測期間の中に夜間バッチ、週次のメンテナンス、四半期ごとの棚卸しなど、普段は起きない作業がどこまで入るかを先に確認します。月次の作業が観測期間から外れていると、本番化した翌週に「毎月の正規作業」で検知が出ます。期限の数日前に、継続(新しいdry runを作り直す)、本番化、停止のどれにするかを決める日を予定に入れておくと、気づいたら無効に戻っていた、という事態を避けられます。
メトリクスがゼロでも、動作確認にはならない
dry runのメトリクスは、ルールが一致したときにだけ出ます。14日間何も出なかったとき、言えるのは「その操作が一度も起きなかった」か「起きたが一致しなかった」のどちらかで、ルールが期待どおりに動くことの確認にはなりません。前の章で書いた伏せられたフィールドの問題もあります。確かめたいなら、検証用のアカウントで、外部への影響がない形で対象の操作を実際に行い、メトリクスと、liveにしたときの検知結果を突き合わせます。
liveにする前に、受け手と自動対応を確かめる
liveにすると、検知結果はGuardDutyのコンソールに出るだけでなく、EventBridgeへ流れ、Security Hubなどの連携先にも送られます。dry runのドキュメントが「検知結果や自動対応を引き起こす前に一致の頻度を測る」と書いているのはこのためです。
前回の記事では、重大度7以上の検知結果をEventBridgeで拾い、Lambdaでアクセスキーの無効化などの封じ込めを行う構成例を書きました。GuardDutyの重大度の区分ではHIGHが7.0〜8.9なので、HIGHのカスタムルールを本番化すると、こうした既存の自動対応ルールの対象にも入るはずです。CI用のロールが正規の作業で引っかかり、そのキーが自動で止まる、ということが起きないように、live化の前に、検知結果のタイプごとに既存の自動対応の条件を確認します。
# dry runで関連付ける(単一アカウント)
aws guardduty create-custom-detection-rule-association \
--rule-id <ルールID> --mode DRY_RUN
# 観測を終えたら live に切り替える
aws guardduty update-custom-detection-rule-association \
--rule-id <ルールID> --mode LIVE
# 今どのルールがどのモードで動いているか
aws guardduty list-custom-detection-rule-associations
update-custom-detection-rule-association の引数は、ユーザーガイドが案内する UpdateCustomDetectionRuleAssociation に対応させて書いたもので、実行はしていません。コンソールでは、ルールを選んで「アクション」から「Enable (Live)」を選びます。
Organizationsで配る前に決めること
AWS Organizationsで複数のアカウントを管理しているなら、GuardDutyの委任管理者アカウントが「組織設定」でメンバーアカウントへルールを配ります。ドキュメントから読み取れる挙動を並べると、設計で迷いやすい点がいくつかあります。
- メンバーアカウントは自分でルールを有効・無効にできない。単一アカウント用の操作を呼ぶと
AccessDeniedExceptionになる - 対象は組織全体か、含める・除くリストで指定する。組織全体を対象にした設定は、後から参加したアカウントにも適用される
- 招待方式でつないだメンバーアカウントは、この一括管理の対象外
- 組織設定を削除しても、すでに作られたメンバー側の関連付けは消えない
特に効いてくるのは2つ目と4つ目です。組織全体を対象にしたdry runは、明日作る新しいアカウントにも適用されます。そして、やめるときに組織設定を消しただけでは、各アカウントのルールは動き続けます。消すときの手順まで含めて、作業記録に残しておく必要があります。
組織全体か、業務区分ごとか
もう一つ、ドキュメントに書かれている制約があります。1つのルールが持てる組織設定はモードごとに1つで、組織全体を対象にした設定(含めるリストを指定しないもの、除くリストだけを指定したもの)がある間は、もう一方のモードの設定を作れず、ConflictException になります。同じルールを「本番アカウントはlive、それ以外はdry run」で同時に動かしたいなら、両方の設定を含めるリストで明示する必要があります。
| 配り方 | 向いている場面 | 気をつけること |
|---|---|---|
| 組織全体(除くリストで例外) | どのアカウントでも起きないはずの操作(組織からの離脱など) | 新規アカウントにも自動で適用される。liveとdry runを同時に持てない |
| 含めるリストで業務区分ごと | 本番だけで想定外の操作(AMIの外部共有など) | アカウントを増やしたときにリストへ足す運用が要る |
除くリストに入れたアカウントは、検知の空白になります。例外にする理由と、いつまで例外にするかを記録し、期限が来たら見直します。理由が「誤検知が多かったから」だけなら、その操作をそのアカウントで行う必要があるのか、という業務側の問いに戻るべきです。
リージョンの扱いも確認が必要です。個々のルールは、対象となるサービスや機能が提供されているリージョンでのみ使えるとドキュメントにあります。GuardDutyのディテクターはリージョンごとに作るものなので、使っているリージョンそれぞれで関連付けの状態を確認してください。組織設定がリージョンをまたいで効くかどうかは、今回確認した範囲のドキュメントには明記がありませんでした。
ルールの変更者と、通知の受け手を対応させる
組織設定を変えられるのは委任管理者アカウントだけです。ということは、ルールを増やす人と、夜中にその検知を受け取る人が別の部署になりがちです。ルールごとに「誰が有効にしたか」「検知は誰に届くか」「その人は対象アカウントの業務を知っているか」を表にしておくと、通知だけが増えて誰も開かない状態を避けやすくなります。マルチアカウントの基本構成はAWS Organizations入門の記事にまとめています。
# 委任管理者アカウントで、本番アカウントだけを対象にdry runを配る
aws guardduty create-custom-detection-rule-org-configuration \
--rule-id <ルールID> --mode DRY_RUN \
--include-account-ids <本番アカウントID>
--include-account-ids の書き方はユーザーガイドの記載に沿っています。値の形式(スペース区切りかどうかなど)は、使っているCLIのヘルプで確認してください。dry runの組織設定は作成から14日で終わり、そこから作られたメンバー側の関連付けも同時に終わります。
単発の検知から、攻撃の流れを追う
liveにしたルールが検知結果を出したとき、その1件だけを見て判断すると、前後の動きを見落とします。AWSのセキュリティブログが8月26日に公開した多段階攻撃の解説も、単独のアラートは1つの出来事しか示さず、複数のサービスのシグナルと自社の業務の文脈を組み合わせて初めて攻撃の流れが見える、という立場で書かれています。
たとえば本番アカウントで Exfiltration:EC2/TransferDataToCloudAccount(AMIの外部共有)が出たとします。調べる順番は次のようになります。
- 検知結果から実行主体(ロールやユーザー)と時刻を確認する
- 同じ主体のCloudTrailイベントを前後数時間さかのぼる。直前にアクセスキーの作成、管理者ポリシーの付与、信頼ポリシーの変更がないか
- ログ設定の変更を確認する。フローログやDNSクエリログの削除、CloudTrail自体の停止がないか
- 共有先のアカウントIDが、取引先など既知のものかを確認する
# 検知結果に出た主体の、前後のイベントを引く(例:ロールのセッション名で絞る)
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=Username,AttributeValue=<セッション名> \
--start-time 2026-10-10T00:00:00Z --end-time 2026-10-10T12:00:00Z \
--query 'Events[].[EventTime,EventName,EventSource]' --output table
2と3で見ている操作の多くは、それ自体がCustom Detection Rulesのルールにもなっています。IAMAccessKeyCreated、AdminPolicyAttachedToRole、IAMRoleTrustPolicyModified、VPCFlowLogsDeleted、DNSQueryLogsDeleted などです。本番アカウントでこれらをまとめてliveにしておけば、調査の入口が複数できます。ただし、イベント履歴(lookup-events)で引けるのは直近90日の管理イベントで、組織の証跡を別に保存していないと、さかのぼれる範囲はそこまでです。
役割を分けて考える
| サービス | 役割 | この記事での使い方 |
|---|---|---|
| GuardDuty(Custom Detection Rules) | 想定外の操作を検知結果にする | アカウントごとに「起きないはずの操作」を登録する |
| Security Hub | 複数サービスの検知結果を集約し、優先度をつけて見せる | 担当者が見る画面をここに集める |
| EventBridge | 検知結果を通知や自動対応へ流す | 受け手と自動対応の条件を検知タイプごとに決める |
| CloudTrail(証跡・イベント履歴) | 操作の記録そのもの | 前後の操作を確かめる。検知が出なくても事実はここで確認する |
GuardDutyにはExtended Threat Detectionという、複数の検知を攻撃の段階として関連付け、攻撃シーケンスの検知結果を出す機能もあります。Custom Detection Rulesの検知結果がこの関連付けの材料に入るかどうかは、今回確認したCustom Detection Rulesのドキュメントには書かれていませんでした。入る前提で運用を組まず、Extended Threat Detection側の仕様で対象を確かめるまでは、上の手順のように人間がCloudTrailで流れを追う前提にしておきます。
最初の運用対象をどう選ぶか
35ルールを全アカウントで一斉にdry runにすることも、ドキュメントにはループ処理の例まで載っていて、技術的には難しくありません。ただ、14日間で全部の一致を観測表に落とせるかというと、担当者が数人の組織では厳しいはずです。僕なら次の条件がそろうところから始めます。
- 日常業務で実行しない操作が、関係者の間ではっきりしている(本番アカウントでのAMI外部共有、ログ集約アカウントでのログ削除など)
- 検知が出たとき、その操作の意味を判断できる担当者がいる
- 既存の自動対応が、そのルールの検知結果でどう動くか分かっている
効果の測り方も、検知件数だけでは足りません。検知のうち実際に調査が必要だった割合、検知から確認までにかかった時間、除くリストや例外の記録を保つ手間。この3つを見ると、ルールを増やすべきか、対象を絞るべきかが判断しやすくなります。ここに置くべき数値は、各組織が自分で測ったものだけです。
料金については、10月10日時点のGuardDutyの料金ページにCustom Detection Rules固有の記載は見当たりませんでした。CloudTrail管理イベントの分析はもともとイベント数に応じた課金です。追加の費用がかかるかどうかは、試験運用の期間中に請求の内訳で確かめるのが確実です。
検知の後には、誰が修復を実行するかという次の問題が来ます。Security Hubの自動修復にどこまで任せられるかは、次の記事で扱う予定です。
確認した資料
- AWS What's New:Amazon GuardDuty adds optional threat detection rules — 2026年9月4日。35ルール、26種類の検知結果、10戦術。商用リージョンとGovCloud(US)で提供。
- GuardDutyユーザーガイド:Custom Detection Rules — 用語、仕組み、伏せられたフィールドの扱い、管理手順、マルチアカウント、検知結果タイプの一覧(2026年10月10日確認)。
- AWS CLIリファレンス:list-custom-detection-rules — フィルターの項目と出力フィールド。
- AWS Security Blog:Detecting multi-stage attacks on AWS — 2026年8月26日。複数サービスのシグナルの関連付けと、Extended Threat Detectionの位置づけ。
- Amazon GuardDuty 料金 — 2026年10月10日確認。
