GuardDutyの検出結果通知をCloudFormationで設定してみた
GuardDutyの検出結果をEventBridgeとSNSを利用して通知することが可能ですが、手作業だと結構手順が必要なため一回で終わるようなCloudFormationテンプレートを作ってみました。
手作業の場合は以下のドキュメントを参考にすると設定できます。
作成したテンプレート
以下のリポジトリに入れてあります。
AWSTemplateFormatVersion: "2010-09-09" Description: GuardDuty Stack Parameters: # ------------------------------------------------------------# # Parameters # ------------------------------------------------------------# MailAddress: Type: String Resources: # ------------------------------------------------------------# # SNS # ------------------------------------------------------------# SnsTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref MailAddress Protocol: email TopicName: sns-guardduty SnsTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Version: '2012-10-17' Id: __default_policy_ID Statement: - Sid: __default_statement_ID Effect: Allow Principal: AWS: '*' Action: - 'SNS:GetTopicAttributes' - 'SNS:SetTopicAttributes' - 'SNS:AddPermission' - 'SNS:RemovePermission' - 'SNS:DeleteTopic' - 'SNS:Subscribe' - 'SNS:ListSubscriptionsByTopic' - 'SNS:Publish' Resource: !Ref SnsTopic Condition: StringEquals: 'AWS:SourceOwner': !Sub ${AWS::AccountId} - Sid: AWSEvents_guardduty Effect: Allow Principal: Service: events.amazonaws.com Action: 'sns:Publish' Resource: !Ref SnsTopic Topics: - !Ref SnsTopic # ------------------------------------------------------------# # GuardDuty # ------------------------------------------------------------# GuardDuty: Type: AWS::GuardDuty::Detector Properties: Enable: true # ------------------------------------------------------------# # EventBridge # ------------------------------------------------------------# EventBridge: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.guardduty detail-type: - 'GuardDuty Finding' detail: severity: - 7 - 7.0 - 7.1 - 7.2 - 7.3 - 7.4 - 7.5 - 7.6 - 7.7 - 7.8 - 7.9 - 8 - 8.0 - 8.1 - 8.2 - 8.3 - 8.4 - 8.5 - 8.6 - 8.7 - 8.8 - 8.9 Name: guardduty-event State: ENABLED Targets: - Arn: !Ref SnsTopic Id: guardduty-event InputTransformer: InputPathsMap: 'severity': '$.detail.severity' 'Account_ID': '$.detail.accountId' 'Finding_ID': '$.detail.id' 'Finding_Type': '$.detail.type' 'region': '$.region' 'time': '$.time' 'Finding_description': '$.detail.description' InputTemplate: | "AWSアカウント:<Account_ID> で重要度:<severity> のイベントが検出されました。" "検出時間:<time>" "検出タイプ:<Finding_Type>" "リージョン:<region>" "検出タイプ説明:<Finding_description>." "マネジメントコンソールから詳細をご確認ください。https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?search=id=<Finding_ID>"
テンプレート説明
上記のテンプレートで設定しているのはSNSトピックの作成、GuardDutyの有効化、EventBridgeの設定です。
それぞれ見ていきます。
SNSトピックの作成
SNSトピックのエンドポイントはパラメータでメールアドレスが入るようにしています。
EventBridgeがSNSを利用できるように「sns:Publish」権限を与えています。
この権限が無いとメールが送られてこなくなります。
# ------------------------------------------------------------# # SNS # ------------------------------------------------------------# SnsTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref MailAddress Protocol: email TopicName: sns-guardduty SnsTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Version: '2012-10-17' Id: __default_policy_ID Statement: - Sid: __default_statement_ID Effect: Allow Principal: AWS: '*' Action: - 'SNS:GetTopicAttributes' - 'SNS:SetTopicAttributes' - 'SNS:AddPermission' - 'SNS:RemovePermission' - 'SNS:DeleteTopic' - 'SNS:Subscribe' - 'SNS:ListSubscriptionsByTopic' - 'SNS:Publish' Resource: !Ref SnsTopic Condition: StringEquals: 'AWS:SourceOwner': !Sub ${AWS::AccountId} - Sid: AWSEvents_guardduty Effect: Allow Principal: Service: events.amazonaws.com Action: 'sns:Publish' Resource: !Ref SnsTopic Topics: - !Ref SnsTopic
SNSのCloudFormationドキュメント
GuardDutyの有効化
GuardDutyを有効化するだけだと数行で設定ができます。
# ------------------------------------------------------------# # GuardDuty # ------------------------------------------------------------# GuardDuty: Type: AWS::GuardDuty::Detector Properties: Enable: true
GuardDutyのCloudFormationドキュメント
EventBridgeの設定
GuardDutyの検出結果が重要度高(8.9~7.0)のものだけを通知するように設定しています。
またインプットトランスフォーマーの設定で通知する内容を編集しています。
イベントの中身は以下のドキュメントをご確認ください。
# ------------------------------------------------------------# # EventBridge # ------------------------------------------------------------# EventBridge: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.guardduty detail-type: - 'GuardDuty Finding' detail: severity: - 7 - 7.0 - 7.1 - 7.2 - 7.3 - 7.4 - 7.5 - 7.6 - 7.7 - 7.8 - 7.9 - 8 - 8.0 - 8.1 - 8.2 - 8.3 - 8.4 - 8.5 - 8.6 - 8.7 - 8.8 - 8.9 Name: guardduty-event State: ENABLED Targets: - Arn: !Ref SnsTopic Id: guardduty-event InputTransformer: InputPathsMap: 'severity': '$.detail.severity' 'Account_ID': '$.detail.accountId' 'Finding_ID': '$.detail.id' 'Finding_Type': '$.detail.type' 'region': '$.region' 'time': '$.time' 'Finding_description': '$.detail.description' InputTemplate: | "AWSアカウント:<Account_ID> で重要度:<severity> のイベントが検出されました。" "検出時間:<time>" "検出タイプ:<Finding_Type>" "リージョン:<region>" "検出タイプ説明:<Finding_description>." "マネジメントコンソールから詳細をご確認ください。https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?search=id=<Finding_ID>"
EventBridgeのCloudFormationドキュメント
デプロイ
今回はAWS CLIを使用してCloudFormationを実行します。
AWS CLIのインストールは以下のブログを参考にしてください。
AWS CLIがインストールできたら以下のコマンドを実行します。
aws cloudformation create-stack --stack-name CloudFormationスタック名 --template-body file://CloudFormationテンプレートファイル名 --parameters ParameterKey=MailAddress,ParameterValue=通知するメールアドレス
もし実行時に以下のエラーが出たらテンプレートファイルの文字コードをShift JISに変更してください
Error parsing parameter '--template-body': Unable to load paramfile (GuardDuty.yml), text contents could not be decoded. If this is a binary file, please use the fileb:// prefix instead of the file:// prefix.
CloudFormationの実行が完了するとパラメータに入力したメールアドレス宛に「AWS Notification - Subscription Confirmation」という件名でメールが届いています。
そちらのメールを開いて「Confirm subscription」をクリックするとSNSの承認が完了します。
承認完了後、マネジメントコンソール→GuardDuty→設定を開きます。
「検出結果サンプルの生成」をクリックして数分待つとメールに重要度高の検出結果サンプルが届きます。
さいごに
今回はGuardDutyの通知設定までCloudFormationで作成してみました。
内容は簡単ですがマネジメントコンソールからの設定だと面倒なこともあったので今回作成したものを今後も利用できたらと思っています。