CloudFormationのStackSetを使用した、GuardDuty全リージョン有効化・SNS通知の設定方法

先日AWS GuardDutyを全リージョンで有効化して、さらにSNS通知設定を複数のアドレスに対して設定する作業を行いました。

この作業をコンソールからポチポチ進めるとかなりの時間と手間がかかってしまいます。

そこで、作業時に実際に使用した、CloudFormationのStackSetから一発で上記の設定ができる方法について、本記事ではご紹介します!

登場するサービス紹介

Amazon GuardDuty

Amazon GuardDutyは、ユーザーの動作や通信をモニタリング・分析し、脅威を識別する脅威検出サービスになります。

VPCフローログやCloudTrailのアクション記録、Route53のDNSログなどをインプットして解析を行います。

下記AWSのドキュメントでも記載されているように、GuardDutyはサポートされているすべてのリージョンで有効化することが推奨されています。

docs.aws.amazon.com

Amazon SNS

Amazon SNSとは、マネージド型のメッセージ配信サービスになります。

メッセージの発行元は、SNS トピックというアクセスポイントに対してメッセージを送ります。

トピックにメッセージが格納されると、そのトピックに登録されているサブスクリプション(メッセージを受け取りたいAWSサービスやEメールアドレスなどのエンドポイント)にメッセージが配信されるという仕組みになります。


Amazon EventBridge

Amazon EventBridgeはイベント駆動型アーキテクチャで、何らかの「イベント」が発生した際に処理を起動させるサービスになります。

Amazon EventBridge ルールを使用することで、受信したイベントの情報をターゲットに送信するという処理を行うことができます。

ルールはイベントパターンに基づいて作成することができるため、対象リソースの特定のイベントを指定して処理を発生させることが可能です。

AWS CloudFormation

AWS CloudFormationは、JSONやYAML形式で記述されたテンプレートファイルから、AWSリソースを構築するサービスです。

テンプレートを一度実行するだけでリソースの構築が行われるので、環境を繰り返し作成する必要がある場合に効果的です。

コンソール上またはAWS CLIからテンプレートを実行するというのが、基本的な使い方になります。

テンプレートから構築されたリソースの集合をStackといい、このStackの単位でAWSリソースの作成・変更・削除が行われます。また、複数のリージョンやアカウントのスタックを一度に作成・変更・削除できる機能をStackSetといいます。

今回のように複数のリージョンでの設定を一度に行いたい場合に有効な機能です。

設定内容

今回の「AWS GuardDutyの全リージョン有効化+SNS通知設定」は、上記で紹介したサービスの設定内容をCloudFormationのStackSetに流すことで一度で自動で実装することができます。

StackSetで実行するテンプレートの内容は、大きく分けて下記の3つになります。

  1. GuardDutyの有効化
  2. SNSトピックの作成
  3. SNSサブスクリプションの作成と通知先メールアドレスの登録
  4. Amazon EventBridgeルールの作成

設定手順

設定の流れとしては下記になります。

  1. CloudFormationのStackSets実行用のIAMロール作成
  2. CloudFormationで実行するテンプレートの作成
  3. CloudFormationでテンプレート実行
  4. SNSサブスクリプションの認証
CloudFormationのStackSets実行用のIAMロール作成

まずは下準備として、CloudFormationのStackSetを利用するために必要なIAMロールを作成します。

IAMロールは管理側とターゲット側とで2つのIAMロールの作成が必要です。

こちらのAWS公式サイトで提供されているテンプレートを使用します。
docs.aws.amazon.com

管理側のIAMロール名:AWSCloudFormationStackSetAdministrationRole

AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSCloudFormationStackSetAdministrationRole to enable use of AWS CloudFormation StackSets.

Resources:
  AdministrationRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetAdministrationRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: AssumeRole-AWSCloudFormationStackSetExecutionRole
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - sts:AssumeRole
                Resource:
                  - "arn:*:iam::*:role/AWSCloudFormationStackSetExecutionRole"

ターゲット側のIAMロール名:AWSCloudFormationStackSetExecutionRole

AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSCloudFormationStackSetExecutionRole to enable use of your account as a target account in AWS CloudFormation StackSets.

Parameters:
  AdministratorAccountId:
    Type: String
    Description: AWS Account Id of the administrator account (the account in which StackSets will be created).
    MaxLength: 12
    MinLength: 12

Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetExecutionRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref AdministratorAccountId
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess

それぞれのテンプレートをCloudFormationのスタックで実行します。

  • AWSCloudFormationStackSetAdministrationRole



  • AWSCloudFormationStackSetExecutionRole


ターゲット側のIAMロール作成においては、アカウントIDの入力が必須となります。

上記2つのIAMロールが作成されていることが確認できたら下準備は完了となります。

CloudFormationで実行するテンプレートの作成

CloudFormationのStackSetsを実行する際は、設定内容が記載されたテンプレート定義を使用します。
今回のテンプレートに記載するコードは下記になります。

AWSTemplateFormatVersion: 2010-09-09
Description:
  "enable guardduty of all region and set alert"
Parameters:
  MailAddress1:
    Description: Enter email address to send notification.
    Type: String
  MailAddress2:
    Description: Enter email address to send notification.
    Type: String
Resources:
##GuardDutyの有効化
  GuardDutyDetector:
    Type: "AWS::GuardDuty::Detector"
    Properties:
      Enable: true
##SNSトピックの作成
  SNSTopic:
    Type: "AWS::SNS::Topic"
    Properties:
      TopicName: GuardDutyTopic
##SNSサブスクリプションの作成
  SNSSub1:
    Type: "AWS::SNS::Subscription"
    Properties:
      Endpoint: !Ref MailAddress1
      Protocol: email
      TopicArn: !Ref SNSTopic
  SNSSub2:
    Type: "AWS::SNS::Subscription"
    Properties:
      Endpoint: !Ref MailAddress2
      Protocol: email
      TopicArn: !Ref SNSTopic
##SNSトピックのアクセスポリシー作成
  SNSTopicPolicy:
    Type: "AWS::SNS::TopicPolicy"
    Properties:
      PolicyDocument:
        Id: default_policy_ID
        Version: "2012-10-17"
        Statement:
        - Sid: default_statement_ID
          Effect: Allow
          Principal:
            AWS: "*"
          Action:
            - "SNS:Publish"
            - "SNS:RemovePermission"
            - "SNS:SetTopicAttributes"
            - "SNS:DeleteTopic"
            - "SNS:ListSubscriptionsByTopic"
            - "SNS:GetTopicAttributes"
            - "SNS:AddPermission"
            - "SNS:Subscribe"
            - "SNS:Receive"
          Resource: !Ref SNSTopic
          Condition:
            StringEquals:
              "AWS:SourceOwner": !Ref "AWS::AccountId"
        - Sid: AWSEvents_AlertGuardDutyFindings_Id123
          Effect: Allow
          Principal:
            Service:
            - "events.amazonaws.com"
          Action: "sns:Publish"
          Resource: !Ref SNSTopic
      Topics:
      - !Ref SNSTopic
##EventBridgeルールの作成
  ER:
    Type: "AWS::Events::Rule"
    Properties:
      Name: AlertGuardDutyFindings
      Description: "Alert to SNS topic when find threats by GuardDuty"
      EventPattern: {
                      "source": [
                        "aws.guardduty"
                      ],
                      "detail-type": [
                        "GuardDuty Finding"
                      ]
                    }
      Targets:
        - Arn: !Ref SNSTopic
          Id: Id123

GuardDutyを有効化するリージョンの指定についてはテンプレートに記載せず、StackSetの設定の際に行います。

今回はSNSのサブスクリプションに2つのEメールアドレスを登録します。
そのためParametersにはMailaddress1とMailaddress2と定義されていますが、Eメールアドレスをこのコードの中に記載するのではなく、CloudFormationのスタック実行時に指定する形となります。

Amazon EventBridgeのルールでは、イベントの発生リソースをGuardDutyとし、脅威が検出された際にターゲットとして設定するAmazon SNSトピックのサブスクリプションに対して通知させるよう設定します。

CloudFormationでテンプレート実行

上記のテンプレートをCloudFormationのStackSetで実行していきます。

CloudFormationのコンソール画面から[StackSetの作成]をクリックする

先ほど作成したIAMロールを管理ロールと実行ロールにそれぞれ指定する

作成したテンプレートをアップロードする

StackSet名を任意で設定する
また、SNS通知先として登録したいEメールアドレスを「パラメータ」のMailaddress1,2にそれぞれ入力する

スタックのデプロイ先にアカウントを選択し、実行するアカウントIDを入力する

「リージョンの指定」項目にてGuardDutyを有効化するリージョンを指定する
今回は全リージョン有効化のため、[すべてのリージョンを追加]をクリックする

他はデフォルトで設定し、[送信]をクリックしてStackSetを実行する

StackSetの詳細からオペレーションを確認することができます。

また、今回はSNSの通知先Eメールアドレスを登録しているため、「AWS Notification - Subscription Confirmation」のメールが全リージョン分届きます。(今回の設定では17通届きます。)
メール本文にある[Confirm subscription]をクリックして、登録を完成させます。

===================================
以上で設定は完了になります!

コンソール上から、全てのリージョンでGuardDutyが有効になっていること、SNSのトピックとサブスクリプションが作成されていること、EventBridgeのルールが作成されていることが確認できます!
■GuardDuty(東京)

■SNS(バージニア北部)

■EventBridge ルール(オレゴン)

要件もよりますが、GuardDutyの全リージョン有効化は推奨設定となっているにもかかわらず、一発で全リージョン有効化できる方法は今のところないので、設定の際はぜひ参考にしてみて下さい!

まとめ

本記事ではCloudFormation のStackSetを使用して、全リージョンのGuardDutyを一斉に有効化+SNS通知を設定する方法について記載しました。

StackSetを使うとリージョンをまたいだ設定や、さらにはアカウントをまたいだ設定も可能になります!
構築などのぽちぽち作業が一気に楽になるので、ぜひいろんな場面で活用してみてください!

執筆担当者プロフィール
徐 一静

徐 一静(日本ビジネスシステムズ株式会社)

クラウドソリューション本部所属。主にAWSに関連する設計、構築を担当しています。Azureでも設計/構築経験ありです。 趣味はお笑いライブに行くことです。

担当記事一覧