1. 構成
| サービス | 役割 | 検出の例 |
|---|---|---|
| GuardDuty | 脅威の検出 | 不審な国からの API 呼び出し、EC2 での仮想通貨マイニング、漏れた認証情報の利用 |
| Inspector | 脆弱性の検出 | EC2・ECR のコンテナイメージ・Lambda のパッケージに含まれる既知の脆弱性(CVE) |
| Security Hub CSPM | 検出結果の集約と設定チェック | 上記 2 つの検出結果と、FSBP・CIS 基準によるリソース設定のチェック結果 |
[ 管理アカウント ] │ 委任管理者に指定(4 章) ▼ [ セキュリティ専用アカウント ] GuardDuty / Inspector / Security Hub の委任管理者 ▲ │ 検出結果(組織内の全アカウント × 全リージョン) │ ├── 管理アカウント └── ワークロード用のアカウント Security Hub(東京に全リージョンを集約) → EventBridge ルール(GuardDuty・MEDIUM 以上) → SNS → メール / Slack(Amazon Q Developer in chat applications)
委任管理者は、管理アカウントの代わりに組織全体のサービスを管理するアカウントです。委任管理者に指定したアカウントから、メンバーアカウントでのサービスの有効化と、検出結果の一括確認ができます。
aws securityhub)と検出結果の形式(ASFF)を使います。新しい Security Hub は CSPM・GuardDuty・Inspector の検出結果をもとに動くため、この構成に後から追加できます。委任管理者は両方で共通です。アカウント ID・メールアドレス・組織 ID は <SECURITY_ACCOUNT_ID> などのプレースホルダで表記しています。
2. セキュリティ専用アカウントを分けるメリット
- 管理アカウントにログインする機会を減らせる。管理アカウントは請求と SCP を扱う、組織で最も権限の強いアカウントです。AWS も、セキュリティサービスの委任管理者には管理アカウント以外を指定することを推奨しています。
- 検出結果をワークロードと別の場所に残せる。ワークロード用のアカウントが侵害されても、検出結果と通知の設定はセキュリティ専用アカウント側に残ります。
- 権限を分けやすい。「検出結果は見られるが、本番環境は操作できない」という権限を、セキュリティ専用アカウントへのアクセス権だけで作れます。
- 確認する場所が 1 か所になる。アカウントやリージョンを切り替えずに、Security Hub の 1 画面で全検出結果を確認できます。
AWS のマルチアカウント構成の指針(AWS Security Reference Architecture)でも、Security OU の下にセキュリティ用のアカウント(Security Tooling)を置く構成が基本です。
3. セキュリティ専用アカウントを作る
3〜4 章は管理アカウントで実行します。
aws organizations create-account \ --email aws-security@example.com \ --account-name moobon-security # State が SUCCEEDED になれば作成完了 aws organizations list-create-account-status --states SUCCEEDED IN_PROGRESS # Security OU を作って移動する aws organizations create-organizational-unit \ --parent-id <ROOT_ID> --name Security aws organizations move-account \ --account-id <SECURITY_ACCOUNT_ID> \ --source-parent-id <ROOT_ID> \ --destination-parent-id <SECURITY_OU_ID>
- メールアドレスはルートユーザーになります。個人ではなく、共有のグループアドレスを使います。
- ワークロード用とは別の OU に置くと、SCP を分けて適用できます。
- ログインは IAM Identity Center(SSO)の Permission Set で行い、ルートユーザーには MFA を設定します。SSO の設定は AWS SSO + AssumeRole の記事を参照してください。
# ~/.aws/config [profile moobon-security] sso_session = moobon-sso sso_account_id = <SECURITY_ACCOUNT_ID> sso_role_name = AdministratorAccess region = ap-northeast-1
4. 委任管理者を指定する
管理アカウントで、3 つのサービスの委任管理者にセキュリティ専用アカウントを指定します。GuardDuty と Inspector はリージョンごとに指定が必要です。
SEC=<SECURITY_ACCOUNT_ID>
# Security Hub(集約リージョンの ap-northeast-1 で実行)
aws securityhub enable-organization-admin-account \
--admin-account-id $SEC --region ap-northeast-1
# GuardDuty と Inspector(全リージョン)
for r in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
aws guardduty enable-organization-admin-account \
--admin-account-id $SEC --region $r
aws inspector2 enable-delegated-admin-account \
--delegated-admin-account-id $SEC --region $r
doneGuardDuty と Security Hub の委任管理者は同じアカウントにします。別々のアカウントにすると、検出結果が正しく集約されないことがあります。
5. GuardDuty を有効化する
5 章以降はセキュリティ専用アカウントで実行します。委任管理者に指定した時点で、セキュリティ専用アカウント自身の GuardDuty は有効になっています。組織内のアカウントをメンバーとして追加します。
# リージョンごとに実行
DET=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text \
--profile moobon-security)
# 組織内のアカウントは招待メールなしで追加できる
aws guardduty create-members \
--detector-id $DET \
--account-details AccountId=<ACCOUNT_ID_1> AccountId=<ACCOUNT_ID_2> \
--profile moobon-security
# RelationshipStatus が Enabled なら完了
aws guardduty list-members --detector-id $DET --profile moobon-security \
--query 'Members[].[AccountId,RelationshipStatus]' --output table新しく作るアカウントも自動で対象にする場合は、自動有効化を設定します。ALL は既存と新規の全アカウント、NEW は新規のアカウントだけが対象です。
aws guardduty update-organization-configuration \ --detector-id $DET \ --auto-enable-organization-members ALL \ --profile moobon-security
6. Inspector を有効化する
Inspector の自動有効化は、設定した後に組織に追加されたアカウントにだけ適用されます。既存のアカウントは別途有効化します。
# 新しく追加されるアカウントを自動で有効化 aws inspector2 update-organization-configuration \ --auto-enable ec2=true,ecr=true,lambda=true \ --profile moobon-security # 既存のアカウントをメンバーにしてスキャンを有効化 for acct in <ACCOUNT_ID_1> <ACCOUNT_ID_2>; do aws inspector2 associate-member --account-id $acct --profile moobon-security done aws inspector2 enable \ --account-ids <ACCOUNT_ID_1> <ACCOUNT_ID_2> \ --resource-types EC2 ECR LAMBDA \ --profile moobon-security
コンソールでは、Inspector の「アカウント管理」画面の「すべてのアカウントをアクティブ化」で同じ操作ができます。
7. Security Hub に集約する
Security Hub を有効にしたアカウントでは、GuardDuty と Inspector の検出結果が自動で Security Hub に送られます。全リージョンの集約と、メンバーの追加を設定します。
全リージョンを東京に集約する
aws securityhub create-finding-aggregator \ --region-linking-mode ALL_REGIONS \ --region ap-northeast-1 --profile moobon-security
東京リージョンが集約リージョンになり、他のリージョンの検出結果も東京で確認できます。8 章の通知ルールはこの集約を前提にしています。
組織内のアカウントをメンバーにする
aws securityhub create-members \
--account-details '[{"AccountId":"<ACCOUNT_ID_1>"},{"AccountId":"<ACCOUNT_ID_2>"}]' \
--profile moobon-security
aws securityhub list-members --only-associated --profile moobon-security \
--query 'Members[].[AccountId,MemberStatus]' --output table設定チェックの基準には、AWS 基礎セキュリティのベストプラクティス(FSBP)と CIS AWS Foundations Benchmark を使っています。アカウントが多い場合は、中央設定(Central configuration)で基準をポリシーとして組織のルートや OU に関連付けると、新しいアカウントにも同じ設定が適用されます。
8. 通知を設定する
通知の対象は、GuardDuty の検出のうち重要度 MEDIUM 以上で、未対応(ワークフローの状態が NEW)のものにしています。Inspector と設定チェックは件数が多いため、通知せずに Security Hub の画面で対応します。
source: aws.guardduty)を直接拾うルールは、ルールを作ったリージョンの検出しか拾えません。東京にだけルールを作ると、他のリージョンの検出は通知されません。Security Hub で全リージョンを東京に集約していれば、Security Hub のイベントを起点にすることで、東京のルール 1 つで全リージョンを拾えます。SNS トピックを作る
# 集約リージョン(ap-northeast-1)で実行 aws sns create-topic --name guardduty-findings-email --profile moobon-security aws sns create-topic --name guardduty-findings --profile moobon-security aws sns subscribe \ --topic-arn arn:aws:sns:ap-northeast-1:<SECURITY_ACCOUNT_ID>:guardduty-findings-email \ --protocol email --notification-endpoint aws-security@example.com \ --profile moobon-security
メール用と Slack 用でトピックを分けています。メール用は EventBridge で本文を整形し、Slack 用は元のイベントをそのまま流します。Slack 用のトピックは、Amazon Q Developer in chat applications(旧 AWS Chatbot)で Slack のチャンネルに接続します。Security Hub のイベントは Amazon Q Developer が整形して投稿します。
各トピックのアクセスポリシーで、events.amazonaws.com からの sns:Publish を許可します。aws:SourceArn でルールを限定する場合は、8 章で作るルールの ARN を指定します。
EventBridge ルールを作る
// pattern.json
{
"source": ["aws.securityhub"],
"detail-type": ["Security Hub Findings - Imported"],
"detail": {
"findings": {
"ProductName": ["GuardDuty"],
"Severity": { "Label": ["MEDIUM", "HIGH", "CRITICAL"] },
"Workflow": { "Status": ["NEW"] },
"RecordState": ["ACTIVE"]
}
}
}aws events put-rule \ --name securityhub-guardduty-medium-plus \ --event-pattern file://pattern.json \ --profile moobon-security aws events put-targets \ --rule securityhub-guardduty-medium-plus \ --targets file://targets.json \ --profile moobon-security
メール本文を整形する
メール用のターゲットには入力トランスフォーマーを設定します。Security Hub の検出結果は detail.findings[0] に入っています。
// targets.json
[
{
"Id": "email",
"Arn": "arn:aws:sns:ap-northeast-1:<SECURITY_ACCOUNT_ID>:guardduty-findings-email",
"InputTransformer": {
"InputPathsMap": {
"acct": "$.detail.findings[0].AwsAccountId",
"region": "$.detail.findings[0].Region",
"sev": "$.detail.findings[0].Severity.Product",
"label": "$.detail.findings[0].Severity.Label",
"type": "$.detail.findings[0].Types[0]",
"title": "$.detail.findings[0].Title",
"desc": "$.detail.findings[0].Description",
"first": "$.detail.findings[0].FirstObservedAt",
"last": "$.detail.findings[0].LastObservedAt",
"id": "$.detail.findings[0].Id"
},
"InputTemplate": "\"【GuardDuty 検知】重要度 <sev>(<label>)\"\n\"アカウント: <acct> リージョン: <region>\"\n\"種類: <type>\"\n\"概要: <title>\"\n\"詳細: <desc>\"\n\"検出結果 ID: <id>\""
}
},
{
"Id": "slack",
"Arn": "arn:aws:sns:ap-northeast-1:<SECURITY_ACCOUNT_ID>:guardduty-findings"
}
]本文に IAM Identity Center のアクセスポータルの URL を入れる場合、#/console?account_id=…&role_name=…&destination=… を付けると、SSO でログインした後に指定したコンソールの画面を開けます。
9. 動作確認
東京以外のリージョンで GuardDuty のサンプル検出を作成し、通知が届くか確認します。
DET=$(aws guardduty list-detectors --region us-west-2 \
--query 'DetectorIds[0]' --output text --profile moobon-security)
# 重要度 MEDIUM のサンプルを 1 件作成
aws guardduty create-sample-findings --region us-west-2 \
--detector-id $DET --finding-types "Recon:EC2/Portscan" \
--profile moobon-security当社の環境では、作成から約 1 分でメールと Slack の両方に届きました。確認後はサンプルの検出をアーカイブします。GuardDuty のイベントを直接拾う古いルールがある場合は、東京の検出が二重に届くため無効化します。
aws guardduty archive-findings --region us-west-2 \ --detector-id $DET --finding-ids <FINDING_ID> \ --profile moobon-security
10. 注意点
- 同じ検出が複数回届くことがある。「Security Hub Findings - Imported」は、検出結果が更新されたときにも送られます。対応を始めたら Security Hub でワークフローの状態を NOTIFIED または RESOLVED に変えると、ルールの条件(NEW)から外れます。
- メンバーの追加はリージョンごと。GuardDuty のメンバーは東京で追加しても他のリージョンには反映されません。全リージョンで
list-membersを確認します。 - 使わないリージョンは SCP で制限する。使わないリージョンでの操作を SCP で拒否すると、監視対象を減らせます。IAM や CloudFront などのグローバルサービスは us-east-1 を使うため、拒否の対象から除外します。
- 費用は無料トライアル中に確認する。GuardDuty と Security Hub CSPM は 30 日、Inspector は 15 日の無料トライアルがあります。期間中にコンソールで月額の見込みを確認し、必要に応じて保護プランやスキャン対象を絞ります。通知の部分(EventBridge・SNS・Amazon Q Developer)の費用はほぼかかりません。
関連リンク
AWS のセキュリティ設定の点検はセキュリティ無料診断、マルチアカウントの設計や GuardDuty・Security Hub を含む運用は AWS 運用保守サービスで承っています。
参考
- AWS Security Hub ユーザーガイド「Central configuration」
- Amazon GuardDuty ユーザーガイド「Managing accounts with AWS Organizations」
- Amazon Inspector ユーザーガイド「Managing multiple accounts with AWS Organizations」
- AWS What's New「AWS Security Hub is now generally available with near real-time risk analytics」(2025年12月)
- AWS Security Reference Architecture(AWS SRA)
よくある質問
Q管理アカウントを委任管理者にしてはいけませんか?
AWS は、セキュリティサービスの委任管理者に管理アカウント以外のアカウントを指定することを推奨しています。管理アカウントは請求や SCP を扱うため、ログインする人と権限を最小限にしておくのが基本です。
Q使っていないリージョンでも GuardDuty を有効にする必要がありますか?
有効にしてください。漏れた認証情報は、利用者が見ていないリージョンでの EC2 起動(仮想通貨マイニングなど)に使われることがあります。費用はデータ量に比例するため、使っていないリージョンではほとんどかかりません。
Q費用はどれくらいかかりますか?
アカウントの規模とログの量で変わります。GuardDuty と Security Hub CSPM は 30 日、Inspector は 15 日の無料トライアルがあり、期間中もコンソールに月額の見込みが表示されます。通知に使う EventBridge(AWS サービスのイベント)と Amazon Q Developer in chat applications は無料で、SNS のメール通知は月 1,000 件まで無料です。
QInspector の検出も通知したほうがよいですか?
有効化した直後は大量の検出が出ることがあり、通知には向きません。Security Hub の画面で重要度順に対応し、通知は GuardDuty の検出に絞るのが現実的です。
Q東京リージョンに GuardDuty の通知ルールを作りましたが、他リージョンの検出が届きません。
GuardDuty のイベントは、検出が発生したリージョンの EventBridge にしか送られません。Security Hub で全リージョンを東京に集約している場合は、通知の起点を Security Hub のイベントに変えると、東京のルール 1 つで全リージョンを拾えます(本文 8 章)。
