エンタープライズクラウド部の松田です。こんにちは。
AWS Security Hub の検出を Backlog でチケット管理する仕組みを紹介します。
はじめに
本記事では、Security Hub での検出の発生を Amazon EventBridge で検知し後続処理に繋げるという実装を紹介しております。
下記エントリとよく似た構成になりますので、よろしければご一読ください。乱暴に言えば Amazon SNS を呼び出すか、Backlog API を呼び出すかの違いです。
構成
さっそくですが構成は以下の通りです。
各要素について簡単に説明しますと、
AWS Security Hub
- 複数アカウント・複数リージョンでの利用を前提としています。
- アカウント集約・リージョン集約を ON にしており、集約アカウントの東京リージョンにすべての検出が集約されるようにしています。
Amazon EventBridge Rule
- Security Hub の検出発生イベントをトリガーに起動し、API Destination を通じて Backlog に課題を起票します。
- API Destination が認証に使用する API キーは、AWS Secrets Manager に格納しています。
- また同時に Step Functions ステートマシンも呼び出します。
AWS Step Functions
- Backlog に起票した Security Hub 検出のステータスを
NOTIFIED
に変更します。 - Security Hub のチェックは定期的に再実行されるため、これにより同じ検出が何度も Backlog に起票されてしまうのを避けています。
という感じです。
実装の詳細
ここからは実装内容を詳細に説明していきます。
Security Hub
Security Hub については、先の説明以上に特に説明することもないので割愛します。
参考までに、リージョン集約とアカウント集約に関する公式ドキュメントを掲載しておきます。
EventBridge ルール
イベントパターン
まず、Security Hub の検出発生イベントを検知するイベントパターンは以下としました。
{ "source": ["aws.securityhub"], "detail-type": ["Security Hub Findings - Imported"], "detail": { "findings": { "Compliance": { "Status": [{ "anything-but": "PASSED" }] }, "AwsAccountId": ["集約アカウントのID", "メンバーAのID", "メンバーBのID"], "Severity": { "Label": ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFORMATIONAL"] }, "Workflow": { "Status": ["NEW"] }, "RecordState": ["ACTIVE"] } } }
これにより、集約アカウントおよびメンバーアカウントAとBで検出が発生すると、EventBridge ルールが起動します。
ちなみに Severity
は CRITICAL
から INFORMATIONAL
すべてを対象としているためワイルドカード "*"
で書いても良いのですが、明示的に記述したほうが可読性が高いと感じたためこのようにしています。小さなこだわりです。
ターゲット
ルールのターゲットには EventBridge API Desinationと Step Function ステートマシンの2つを指定し、Input としてそれぞれ以下を渡しています。
Input - API Destination
※Input transformer を使用
Input path
{ "Account": "$.detail.findings[0].AwsAccountId", "Description": "$.detail.findings[0].Description", "Resource": "$.detail.findings[0].Resources[0].Id", "Summary": "$.detail.findings[0].Title", "Region": "$.detail.findings[0].Region", "Severity": "$.detail.findings[0].FindingProviderFields.Severity.Label", "ScanId": "$.detail.findings[0].Id", "Recommendation": "$.detail.findings[0].Remediation.Recommendation.Url" }
Template
{ "projectId": "BacklogのプロジェクトID", "parentIssueId": "SecurityHub用親課題のID", "priorityId": "3", "issueTypeId": "SecurityHubチケットに割り当てる分類のID", "summary": "<Summary>", "description": "AWS Security Hubで以下が検出されました。<br /><br />検出内容:<br /><Description><br /><br />重要度: <Severity><br /><br />AWSアカウント: <Account><br />リージョン: <Region><br />リソース: <Resource><br /><br />検索ID: <ScanId><br /><br />リンク:<br />[Security Hub](https://ap-northeast-1.console.aws.amazon.com/securityhub/home?region=ap-northeast-1#/findings?search=Id%3D%255Coperator%255C%253AEQUALS%255C%253A<ScanId>)<br />[Recommendation](<Recommendation>)" }
Input - Step Function ステートマシン
Matched events(イベントを無加工で Input として渡す)
EventBridge API Destination
主な設定パラメータを記載します。
この辺りは Backlog 公式の API リファレンスを見ながら設定しました。
パラメータ | 設定値 |
---|---|
エンドポイント | https://***.backlog.jp/api/v2/issues |
HTTP メソッド | POST |
接続 - 送信先タイプ | その他 |
接続 - 認証タイプ | API キー |
API キー - API キー名 | apiKey |
API キー - 値 | *********(※) |
呼び出し Http パラメータ - パラメータ | シークレットのクエリ文字列 |
呼び出し Http パラメータ - キー | apiKey |
呼び出し Http パラメータ - 値 | *********(※) |
(※):Backlog API キーの値を設定します(発行方法は以下を参照ください)。 https://support-ja.backlog.com/hc/ja/articles/360035641754-API%E3%81%AE%E8%A8%AD%E5%AE%9A
ちなみにですが、ここで設定した API キーは Secrets Manager に自動で保存されます。
また 呼び出し Http パラメータ
で API キーを設定しているため、API キー - API キー名
と API キー - 値
は設定する必要がないかもしれません(未検証。空欄にできなかったため上記の設定としています)。
更に余談ですが、Backlog も EventBridge も OAuth に対応しているようだったので、当初は API キーでなく OAuth による認証で考えていました。ですがよくよく調べてみると、それぞれサポートしている認可フローが異なっているようで、OAuth の利用は諦め API キーに切り替えました(Backlog は Authorization Code Grant を、EventBridge は Client Credentials Grant)。
Step Functions ステートマシン
ステートマシンの定義は以下の通りです。
Findings のステータスを NOTIFIED
に変えるだけです。
{ "Comment": "Security Hub finding handler", "StartAt": "Set a finding as NOTIFIED", "States": { "Set a finding as NOTIFIED": { "Type": "Task", "End": true, "Parameters": { "FindingIdentifiers": [ { "Id.$": "$.detail.findings[0].Id", "ProductArn.$": "$.detail.findings[0].ProductArn" } ], "Workflow": { "Status": "NOTIFIED" } }, "Resource": "arn:aws:states:::aws-sdk:securityhub:batchUpdateFindings" } } }
IAM ポリシー
EventBridge ルールと、Step Function ステートマシンが引き受ける IAM ロールには、それぞれ以下の IAM ポリシーをアタッチしています。
EventBridge ルール用①(API Destination 起動用)
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "events:InvokeApiDestination" ], "Resource": [ "[API Destination の ARN]" ], "Effect": "Allow" } ] }
EventBridge ルール用②(Step Function ステートマシン起動用)
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "states:StartExecution" ], "Resource": [ "[Step Function ステートマシンの ARN]" ], "Effect": "Allow" } ] }
Step Function ステートマシン用
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "securityhub:BatchUpdateFindings" ], "Resource": [ "*" ], "Effect": "Allow" }, { "Action": [ "logs:CreateLogDelivery", "logs:CreateLogStream", "logs:GetLogDelivery", "logs:UpdateLogDelivery", "logs:DeleteLogDelivery", "logs:ListLogDeliveries", "logs:PutLogEvents", "logs:PutResourcePolicy", "logs:DescribeResourcePolicies", "logs:DescribeLogGroups" ], "Resource": [ "*" ], "Effect": "Allow" } ] }
本構成の利点と課題
最後に、今回考えた構成の利点と課題点をあげておきます。
とはいえ本格運用はこれからですので、実際に回してみての感想はまた追記したいと思います。
私が思う利点は以下になります。
- チケット管理がしやすい
- 対応期日や担当者が設定できるので、上がってきた検出への対応をタスクとして管理しやすいと考えています。
- 検出結果の後追いがしやすい
- 過去の対応履歴が残り続けるので、有効活用できると考えています。
- 対応手順や注意点、対応不要とした場合はその根拠などといったナレッジが蓄積されていく点にも期待しています。
- 柔軟性が高い
- イベントパターンの設定により、Backlog に起票する検出をフィルタリングできます。
- 例えば重要度が
LOW
であれば初めから起票しない、開発環境のアカウントであれば起票しない、などとすることで、運用時のノイズを予め除去することができます。
一方で、以下のあたりは課題になりそうだと考えています。
- EventBridge のサービスクォータ
- 今回の構成では、システムごとに課題を起票する Backlog を切り替えることを想定しているため、アカウントが増えるたびに EventBridge ルールが増えていくことになります。
- 上限は300で緩和も可能ではありますが、今後の状況次第では Lambda を使うなど、別の方法への切り替えもありうると考えています。
- Security Hub と Backlog とで二重管理になる
- チケットが二重になるため、例えば Backlog ではクローズ済みのチケットが Security Hub ではオープンになっているといった状況が容易に想像できます。「Backlog を正とする」などのルールでカバーできるでしょうが、ちょっとスマートではないですね。
まとめ
Security Hub の運用を色々考えていたところ、チケットは外に持ち出したほうが何かと使いやすそうだな~と思ってこちらの構成に至りました。本格運用はこれからですが、改善点などが見つかれば適宜情報はアップデートしたいと考えています。
Backlog のところは他のチケット管理ツールにも置き換え可能ですので、同じようにSecurity Hub の運用でお困りの方がいれば、本記事が何かのヒントになれば幸いです。
松田 渓(記事一覧)
2021年10月入社。散歩が得意です。