カスタマーサクセス部の山﨑です。
今回はIncident Manager を活用してSecurity Hubで検出したインシデントを管理する方法を検証してみました。
- Systems Manager Incident Managerについて
- 今回想定した利用シーン
- 今回の構成
- いざ実装
- Incident Manager でインシデントを見てみる
- Incident Manager でインシデントを分析してみる
- まとめ
Systems Manager Incident Managerについて
概要
Systems Manager Incident Managerは、Systems Manager の中でも「運用管理」に分類される機能でインシデント対応を効率化することができます。例えば、CloudWatchやSecurity Hub等のイベントをトリガーにインシデントを自動検出し、対応チームに通知することができます。
その他にもRunbook(SSM Automation Documents)を用いた対応マニュアルの表示、アクティビティを時系列で記録するタイムライン、関連リソースを表示/管理、インシデントの問題分析を行う機能などがあります。これらの機能により、インシデントの解決、影響を軽減するまでの時間を短縮させ、システム障害やセキュリティインシデントへの迅速かつ組織的な対応を支援します。
守備範囲
上図の通り、Incident Managerは「インシデントの検知〜インシデント後の分析まで」インシデント管理における対応を幅広くカバーしています
全体像
Blackbeltがとてもよく整理されているので、引用しまくっていますが、インシデントが発生してからの流れを端的に述べると以下の通りです。
- インシデントの発生をCloudWatchやEventBridgeで検知し、Incident Managerの対応プランを呼び出す。
- 対応プランに従ってチャット通知/担当者へのエスカレーション(メール/SMS/電話)を行う。
- インシデントはIncident Managerのコンソール画面から詳細を確認することができるため、それらの情報をもとに対応を行う
- インシデントはOpsItemを作成することで管理している
- インシデントが解決したら、OpsItemから「分析」を作成してインシデント分析を行い再発防止等を行う
今回想定した利用シーン
- 複数のAWSアカウントを運用している中規模 / 大規模な組織で、Security Hubの検出結果を専用アカウントに集約している
- Security Hubの検出結果に対する調査/対応を行う運用担当者が複数存在し、人員の入れ替わりも不定期に発生する
- インシデント対応に関するナレッジ管理ができておらず、対応が属人化している
今回の構成
- Security Hub で検出したイベントをトリガーにして、Step Functions のステートマシンを起動させる。
- ステートマシンでは、DynamoDBに記録している Finding ID と ステートマシンが受信したイベントの Finding ID の重複チェックを行う
- Security Hub の定期更新によって同じ Findings が Incident Manager のインシデントとして作成されることを防ぐため
- 重複がないことを確認したら、Incident Manager でインシデントを作成する
- インシデントでは担当者の応対品質を平準化するために、ランブック(SSM Automation Documents)に対応フェーズごとのマニュアルを作成しておく
いざ実装
今回は細かい手順はスキップして、重要な箇所だけをピックアップしてご紹介します。
1. DynamoDBの作成
Security Hub によるセキュリティチェックは、最後にチェックした時間から 12 時間または 24 時間以内に自動的に実行される仕様であり、このチェック間隔は変更できません。
Security Hub のイベントは一意のFinding IDを持っています。したがって、上記チェック間隔でセキュリティチェックが実行された際に同じFinding IDを持つ新しいイベントが発生する可能性があります。その場合、同じFinding IDにも関わらず、Incident Managerが新しいインシデントを作成してしまう恐れがあります。
そこで、今回はDynamoDBにFinding IDを記録しておき、同一のFinding IDに関するイベントであればインシデントを作成しないようにします。Finding IDが必要以上に記録されないよう、DynamoDB作成時にTTLを設定しておくと良いかと思います。
今回は「FindingId」をパーティションキーとしたDynamoDBテーブルを作成しました。
2. Runbook(SSM Automation Documents)の作成
Incident Manager で「対応プラン」を作成する際に「Runbook」を指定することができます。「Runbook」の実態は SSM Automation Documents です。そのため、予め定義した処理を自動で実行することが可能です。「Runbook」を自動化に利用した実装については以下のブログをご覧ください。
この「Runbook」は自動化だけでなく、Incident Manager の画面に手動対応マニュアルを表示させることもできます。今回は「インシデント対応に関するナレッジ管理ができておらず、対応が属人化している」という利用シーンをイメージしているため、画一的な対応を行うためには手動対応マニュアルを表示させるように実装します。
SSM Document のコンソール画面から以下に示す「AWSIncidents-SecurityHubRunbook」を作成します。
AWSIncidents-SecurityHubRunbook(クリックして展開)
description: "This document is intended as a template for an incident response runbook in [Incident Manager](https://docs.aws.amazon.com/incident-manager/latest/userguide/index.html).\n\nFor optimal use, create your own automation document by copying the contents of this runbook template and customizing it for your scenario. Then, navigate to your [Response Plan](https://console.aws.amazon.com/systems-manager/incidents/response-plans/home) and associate it with your new automation document; your runbook is automatically started when an incident is created with the associated response plan. For more information, see [Incident Manager - Runbooks](https://docs.aws.amazon.com/incident-manager/latest/userguide/runbooks.html). \v\n\nSuggested customizations include:\n* Updating the text in each step to provide specific guidance and instructions, such as commands to run or links to relevant dashboards\n* Automating actions before triage or diagnosis to gather additional telemetry or diagnostics using aws:executeAwsApi\n* Automating actions in mitigation using aws:executeAutomation, aws:executeScript, or aws:invokeLambdaFunction\n" schemaVersion: '0.3' mainSteps: - description: | **インシデント内容の把握** * 当インシデントの「関連項目」タブをクリックし、各エントリーを確認してインシデント内容を把握してください。 * Related resource: Security Hubのセキュリティコントロールに抵触したAWSリソースのARN * Finding ID: Security Hub のFinding ID * Remediation: インシデントの解決策が記載されたAWS公式ドキュメント * 必要に応じて以下のAWS公式ドキュメントを参照してください。 * Security Hubの[コントロールに関するドキュメント](https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-controls-reference.html)を確認し、発生したインシデント内容を正確に把握してください。 * インシデント内容の把握が完了したら以下の対応をしてください。 * 該当のAWSアカウントにログイン後、Security Hubに開き、「ワークフローのステータス」を「通知済み(NOTIFIED)」に変更する * 当インシデントの「ランブック」タブを開き、「再開」ボタンをクリックして、インシデントの原因調査を進めてください。 name: Understand action: aws:pause nextStep: Investigation isEnd: false inputs: {} - description: | **インシデントの原因調査** * インシデントが発生したAWSアカウントへログインしてください。 * AWS Config を開き、左メニューから「リソース」を選択してください。 * 「リソース識別子 - オプション」に「Understand」セクションで確認した関連リソースのID(Related resource)を入力して検索し、ヒットしたリソースの詳細を開きます。 * 「リソースタイムライン」をクリックすると、リソースの変更履歴を確認することができます。 * 「CloudTrailイベント」を開くと、どのユーザーが、どのような操作をしたのかを確認することができるため、どのような経緯でインシデントが発生したのかを確認してください。 * 最後にIncident Managerの「メモ」に、インシデントが発生した経緯として以下の内容を追加してください。 * インシデントに至る操作をしたユーザー名は何か * どのリソースに対して操作が行われた * 具体的にどのような操作が行われたのか * インシデント内容の把握が完了したら以下の対応をしてください。 * 当インシデントの「ランブック」タブを開き、「再開」ボタンをクリックして、インシデントの報告を進めてください。 name: Investigation action: aws:pause nextStep: Report isEnd: false inputs: {} - description: | **インシデントの報告** * 「Investigation」で調査した内容をシステム担当者に報告してください。 * 報告後、インシデントを解決するための対策について対応策を検討/整理してください。 * 対応策は当インシデントの「関連項目」タブの「Remediation」のリンクを参考にしてください。 * インシデント内容の把握が完了したら以下の対応をしてください。 * Incident Managerの「メモ」に、決定したインシデントへの対応策を記載してください。 * 当インシデントの「ランブック」タブを開き、「再開」ボタンをクリックして、インシデントの報告を進めてください。 name: Report action: aws:pause nextStep: Recovery isEnd: false inputs: {} - description: |- **インシデントの解決** * インシデントを解決するための対策を実際に講じてください。 * 対策を実施したら以下の対応をしてください。 * Incident Managerの「メモ」に、対策を実施した結果を記載してください。 * 該当のAWSアカウントにログイン後、Security Hubに開き、「ワークフローのステータス」を「解決済み(RESOLVED)」に変更する * 対策を実施した結果をシステム担当者に報告した後、対応完了の承認が得られたら本インシデントを解決済としてください。 name: Recovery action: aws:pause isEnd: true inputs: {}
3. Incident Manager(対応プラン)の作成
Incident Manager で必要事項を入力して「対応プラン」を作成していきます。ここで先程作成したRunbookを指定します。今回は「エスカレーションプラン」や「連絡先」は作成しません。
4. Step Functions ステートマシンの作成
以下の「IncidentStateMachine」に示すJSONコードに従ってステートマシンを作成します。
IncidentStateMachine(クリックして展開)
{ "Comment": "Step Functions state machine for filtering duplicate findings and creating incidents", "StartAt": "CheckDuplicate", "States": { "CheckDuplicate": { "Type": "Task", "Resource": "arn:aws:states:::dynamodb:getItem", "Parameters": { "TableName": "[DynamoDBのテーブル名]", "Key": { "FindingId": { "S.$": "$.detail.findings[0].Id" } } }, "ResultPath": "$.dynamodb", "Next": "IsDuplicate" }, "IsDuplicate": { "Type": "Choice", "Choices": [ { "Variable": "$.dynamodb.Item", "IsPresent": true, "Next": "DuplicateFound" } ], "Default": "AddNewFinding" }, "DuplicateFound": { "Type": "Succeed", "Comment": "Duplicate finding detected. No further action taken." }, "AddNewFinding": { "Type": "Task", "Resource": "arn:aws:states:::dynamodb:putItem", "Parameters": { "TableName": "[DynamoDBのテーブル名]", "Item": { "FindingId": { "S.$": "$.detail.findings[0].Id" } } }, "ResultPath": "$.putResult", "Next": "CreateIncident" }, "CreateIncident": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:ssmincidents:startIncident", "Parameters": { "ResponsePlanArn": "[対応プランのARN]", "Impact": 2, "Title.$": "States.Format('[{}][{}]: {}', $.detail.findings[0].AwsAccountId,$.detail.findings[0].Severity.Label,$.detail.findings[0].Title)", "RelatedItems": [ { "Identifier": { "Type": "OTHER", "Value": { "Url.$": "$.detail.findings[0].Remediation.Recommendation.Url" } }, "Title": "Remediation" }, { "Identifier": { "Type": "INVOLVED_RESOURCE", "Value": { "Arn.$": "$.detail.findings[0].Resources[0].Id" } }, "Title": "Related resource" }, { "Identifier": { "Type": "OTHER", "Value": { "Arn.$": "$.detail.findings[0].Id" } }, "Title": "Finding ID" } ], "TriggerDetails": { "Source": "SecurityHub", "Timestamp.$": "$.time", "TriggerArn.$": "$.resources[0]" } }, "End": true } } }
ステートマシンの各処理内容は以下の通りです。
ステート | 処理内容 | 備考 |
---|---|---|
CheckDuplicate | DynamoDBのgetItem関数を使用して、DynamoDBテーブルからSecurity Hubが持つFinding IDをキーに指定してアイテムを取得する。実行結果は「$.dynamodb」に格納される。 | Step Functions に関連付けるIAMロールにDynamoDBテーブルのGetItem に関する操作を許可するポリシーをアタッチしておく |
IsDuplicate | 「$.dynamodb」の値をもとにFinding IDの重複チェックを行う。重複していれば「DuplicateFound」へ、そうでなければ「AddNewFinding」へ進む。 | |
DuplicateFound | 追加のアクションは実行されない。 | |
AddNewFinding | DynamoDBのputItem関数を呼び出して、DynamoDBテーブルにFinding IDを格納する。 | Step Functions に関連付けるIAMロールにDynamoDBテーブルのPutItem に関する操作を許可するポリシーをアタッチしておく |
CreateIncident | Incident ManagerのstartIncident関数を呼び出して、新規インシデントを作成する。 | Step Functions に関連付けるIAMロールにIncident Manager のStartIncident に関する操作を許可するポリシーをアタッチしておく |
5. EventBridge
Security Hub ではGuardDutyやPatch Manager等、様々なAWSサービスの統合をサポートしていますが、AWSサービスによってEventBridgeが受信するイベントの内容が異なるため、今回はSecurity Hubに関するイベントのみを受け取るようにします。
ターゲットには先程作成したStep Functionsのステートマシンを指定しておきます。
{ "source": ["aws.securityhub"], "detail-type": ["Security Hub Findings - Imported"], "detail": { "findings": { "Severity": { "Label": ["CRITICAL", "HIGH"] }, "RecordState": ["ACTIVE"], "Workflow": { "Status": ["NEW"] }, "ProductFields": { "aws/securityhub/ProductName": ["Security Hub"] } } } }
Incident Manager でインシデントを見てみる
インシデント一覧
[アカウントID][重要度]: インシデントタイトル の形式でタイトルが作成されています。これはStep Functionsの「CreateIncident」ステート内の以下の記述で実現しています。
"Title.$": "States.Format('[{}][{}]: {}', $.detail.findings[0].AwsAccountId,$.detail.findings[0].Severity.Label,$.detail.findings[0].Title)",
ランブック
任意のインシデントを開いた上で「ランブック」タブを見ると「ランブックのステップ」が表示されます。ここには「2. Runbook(SSM Automation Documents)の作成」で作成したSSM Automation Documents の内容が表示されます。
「再開」ボタンが表示されていますが、これはランブックに記載されている対応完了後にクリックすると対応ステップを次に進めることができます。
タイムライン
「タイムライン」タブを開くとインシデントに関連するアクティビティ履歴を閲覧することができます。画面右上の「追加」をクリックするとコメントを残すこともできるので、対応結果やメモを追加すると後で対応内容や調査内容をチェックすることができます。
追加したメモは右メニューで一覧として閲覧することができます
関連項目
「関連項目」タブを開くと以下4つの項目が表示されています。これにより、インシデント調査の初期動作をスピーディーに行うことができます。
- Related resource:Security Hubのセキュリティコントロールに抵触したAWSリソースのARN(リンク)
- Finding ID:検出されたSecurity Hub のFindingのARN(リンク)
- Remediation:インシデントの解決策が記載されたAWS公式ドキュメント(リンク)
- parentItem:インシデントに関するOpsItemのARN(リンク)
「parentItem」は自動生成されますが、その他の3つの項目に関してはStep Functionsの「CreateIncident」ステート内の以下の記述で実現しています。
"RelatedItems": [ { "Identifier": { "Type": "OTHER", "Value": { "Url.$": "$.detail.findings[0].Remediation.Recommendation.Url" } }, "Title": "Remediation" }, { "Identifier": { "Type": "INVOLVED_RESOURCE", "Value": { "Arn.$": "$.detail.findings[0].Resources[0].Id" } }, "Title": "Related resource" }, { "Identifier": { "Type": "OTHER", "Value": { "Arn.$": "$.detail.findings[0].Id" } }, "Title": "Finding ID" } ],
parentItem
「parentItem」のリンクをクリックすると、該当のOpsItemの詳細を見ることができます。
OpsItemの詳細画面の「概要」タブをクリックすると、「類似のOpsItem」を見ることができます。「類似のOpsItem」はすべてのOpsItemのタイトルと説明をスキャンし、類似した単語を使用しているOpsItemを列挙しています。
画面キャプチャ上ではステータスが全て「未解決」になっていますが、「解決済み」のOpsItemがあれば、過去の対応履歴を閲覧することができるためインシデント対応をよりスムーズに進めることができます。
Incident Manager でインシデントを分析してみる
分析を作成する
インシデントを解決済みにすると、「分析」を作成することができます。
「テンプレート」はカスタマイズ可能です。
Incident Manager でのインシデント後分析の実行 - Incident Manager
インシデントを分析する
概要
「インシデントの概要」「影響」を整理して、今回発生したインシデント内容を第三者が見ても分かるように整理します。
質問
次に「質問」タブでインシデント内容を細かく振り返り、恒久対策を検討します。AWSが提供しているテンプレートでは「なぜなぜ分析」が質問として掲載されています。
アクション項目
「質問」タブで振り返りおよび恒久対策を検討したら、「アクション項目」でネクストアクションを追加、管理します。
レポート作成
「分析」はPDFで印刷可能なので、インシデントレポートとして出力したPDFをそのまま提出することが可能です。
まとめ
ということで今回はIncident Manager を活用してSecurity Hubで検出したインシデントを管理する方法を検証してみました。Step Functions の実装でかなり苦戦しましたが、Incident Manager は以前から検証してみたいと思っていたので良い勉強になりました。
山﨑 翔平 (Shohei Yamasaki) 記事一覧はコチラ
2019/12〜2023/2までクラウドインテグレーション部でお客様のAWS導入支援を行っていました。現在はIE(インターナルエデュケーション)課にて採用周りのお手伝いや新卒/中途オンボーディングの業務をしています。2023 Japan AWS Top Engineers/2023 Japan AWS Ambassadors