ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【Step Functions】Security Hub CSPMの通知件名カスタマイズ・ワークフローステータスの自動変更

この記事を共有する

目次

はじめに

こんにちは。サービスGの中野です。
AWS Security Hub(CSPM)でSNS通知を設定されている方は多いと思いますが、いざ運用を始めると以下のような課題に直面するのではないでしょうか。

  • 同じ内容の通知が、とめどなく届く
  • 件名が一律(AWS Notification Message)で、何の通知か開くまで分からない
  • 本文がJSONの塊で、パッと見での解読がしんどい

本文の見づらさだけであれば、EventBridgeの「入力トランスフォーマー」で手軽に整形できますが、件名のカスタマイズは思いのほかEventBridgeではできません。
また、通知の重複を防ぐために、「ワークフローステータスが NEW のものだけを通知し、通知後にステータスをNOTIFIEDに自動更新」したいとなれば、Lambda使うしかないか、、と諦めていました。
しかし、Step Functionsを使えば、Lambdaを導入せずとも超簡単にこれらすべてを解決できることが分かったので、備忘録を兼ねて実際に実装したStep Functionsの定義を記録します。

構成図

以下が構成図です。
StepFunction構成図_中野.png

参考までに、SNSトピック、EventBridge、Step Functions、それぞれのサービスが使うIAMロールを定義したCloudFormationのテンプレートを以下に記載しておきます。(リソース名などべた書きですがご了承ください)

CloudFormationテンプレート

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  # ===========================================================================
  # Common Configuration
  # ===========================================================================
  email:
    Type: String
    Description: email address
    Default: xxx
Resources:
  # ===========================================================================
  # Create SNS Topic
  # ===========================================================================
  # SNS Topic for Security Monitoring
  SecurityMonitoringSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: sns-topic-security-alert
      DisplayName: Security Hub High Severity Alerts
      KmsMasterKeyId: alias/aws/sns
  # HTTPS Subscription for SNS Topic
  SecurityMonitoringHTTPSSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Protocol: email
      TopicArn: !Ref SecurityMonitoringSNSTopic
      Endpoint: !Ref email
  SecurityMonitoringSNSTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref SecurityMonitoringSNSTopic
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: AllowStepFunctionsPublish
            Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sns:Publish
            Resource: !Ref SecurityMonitoringSNSTopic
  # ===========================================================================
  # IAM Role for Step Functions
  # ===========================================================================
  SecurityAlertStateMachineRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: iam-role-sfn-security-alert
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                aws:SourceArn: !Sub arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:sfn-security-alert
      Policies:
        - PolicyName: iam-policy-sfn-security-alert
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource: !Ref SecurityMonitoringSNSTopic
              - Effect: Allow
                Action:
                  - securityhub:BatchUpdateFindings
                Resource: !Sub arn:aws:securityhub:${AWS::Region}:${AWS::AccountId}:hub/default
  # ===========================================================================
  # IAM Role for EventBridge
  # ===========================================================================
  EventBridgeStateMachineRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: iam-role-eb-sfn
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                aws:SourceArn: !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/eb-rule-security-alert
      Policies:
        - PolicyName: iam-policy-eb-sfn
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - states:StartExecution
                Resource: !Ref SecurityAlertStateMachine
  # ===========================================================================
  # Step Functions State Machine
  # ===========================================================================
  SecurityAlertStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      StateMachineName: sfn-security-alert
      RoleArn: !GetAtt SecurityAlertStateMachineRole.Arn
      DefinitionString: !Sub |
        {
          "Comment": "Security Hub 検出結果のSNS通知とワークフローステータスの更新(NEW⇒NOTIFIED)",
          "StartAt": "FormatAndPublishToSNS",
          "States": {
            "FormatAndPublishToSNS": {
              "Type": "Task",
              "Resource": "arn:aws:states:::sns:publish",
              "Parameters": {
                "TopicArn": "${SecurityMonitoringSNSTopic}",
                "Subject.$": "States.Format('[SecurityHub] {} アカウントで {} が検出されました({})', $.detail.findings[0].AwsAccountId, $.detail.findings[0].FindingProviderFields.Severity.Label, $.detail.findings[0].Region)",
                "Message.$": "States.Format('AWS Security Hubで以下が検出されました。\n\n・タイトル: {}\n・製品名: {}\n・検出内容: {}\n・重要度: {}\n・AWSアカウント: {}\n・リージョン: {}\n・リソース: {}\n\n・詳細は以下のURLにアクセスしてください (対象アカウントへのログインが必要です)。\nhttps://ap-northeast-1.console.aws.amazon.com/securityhub/home?region=ap-northeast-1#/findings?search=Id%3D%255Coperator%255C%253AEQUALS%255C%253A{}', $.detail.findings[0].Title, $.detail.findings[0].ProductName, $.detail.findings[0].Description, $.detail.findings[0].FindingProviderFields.Severity.Label, $.detail.findings[0].AwsAccountId, $.detail.findings[0].Region, $.detail.findings[0].Resources[0].Id, $.detail.findings[0].Id)"
              },
              "Next": "UpdateWorkflowStatus",
              "ResultPath": "$.snsResult"
            },
            "UpdateWorkflowStatus": {
              "Type": "Task",
              "Resource": "arn:aws:states:::aws-sdk:securityhub:batchUpdateFindings",
              "Parameters": {
                "FindingIdentifiers": [
                  {
                    "Id.$": "$.detail.findings[0].Id",
                    "ProductArn.$": "$.detail.findings[0].ProductArn"
                  }
                ],
                "Workflow": {
                  "Status": "NOTIFIED"
                },
                "Note": {
                  "Text": "通知済み",
                  "UpdatedBy": "Step Functions"
                }
              },
              "End": true,
              "ResultPath": "$.updateResult"
            }
          }
        }
  # ===========================================================================
  # Create EventBridge Rule
  # ===========================================================================
  SecurityHubHighSeverityRule:
    Type: AWS::Events::Rule
    Properties:
      Name: eb-rule-security-alert
      Description: Rule to detect high severity events (CRITICAL and HIGH) from Security Hub
      EventBusName: default
      State: ENABLED
      EventPattern:
        detail-type:
          - Security Hub Findings - Imported
        source:
          - aws.securityhub
        detail:
          findings:
            Compliance:
              Status:
                - anything-but: PASSED
                - exists: false
            RecordState:
              - ACTIVE
            Workflow:
              Status:
                - NEW
            Severity:
              Label:
                - CRITICAL
                - HIGH
      Targets:
        - Id: SecurityAlertStateMachine
          Arn: !Ref SecurityAlertStateMachine
          RoleArn: !GetAtt EventBridgeStateMachineRole.Arn
  # ===========================================================================
  # Outputs
  # ===========================================================================
Outputs:
  SNSTopicArn:
    Description: ARN of the SNS topic for security monitoring
    Value: !Ref SecurityMonitoringSNSTopic
  SNSTopicName:
    Description: Name of the SNS topic
    Value: !GetAtt SecurityMonitoringSNSTopic.TopicName
  SubscriptionArn:
    Description: ARN of the HTTPS subscription
    Value: !Ref SecurityMonitoringHTTPSSubscription
  StateMachineArn:
    Description: ARN of the Step Functions state machine
    Value: !Ref SecurityAlertStateMachine
  RuleName:
    Description: Name of the EventBridge rule
    Value: !Ref SecurityHubHighSeverityRule
  RuleArn:
    Description: ARN of the EventBridge rule
    Value: !GetAtt SecurityHubHighSeverityRule.Arn

Step Functionsの定義

以下が定義の内容です。

{
  "Comment": "Security Hub 検出結果のSNS通知とワークフローステータスの更新(NEW⇒NOTIFIED)",
  "StartAt": "FormatAndPublishToSNS",
  "States": {
    "FormatAndPublishToSNS": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "TopicArn": "arn:aws:sns:ap-northeast-1:<アカウントID>:sns-topic-security-alert",
        "Subject.$": "States.Format('[SecurityHub] {} アカウントで {} が検出されました({})', $.detail.findings[0].AwsAccountId, $.detail.findings[0].FindingProviderFields.Severity.Label, $.detail.findings[0].Region)",
        "Message.$": "States.Format('AWS Security Hubで以下が検出されました。\n\n・タイトル: {}\n・製品名: {}\n・検出内容: {}\n・重要度: {}\n・AWSアカウント: {}\n・リージョン: {}\n・リソース: {}\n\n・詳細は以下のURLにアクセスしてください (対象アカウントへのログインが必要です)。\nhttps://ap-northeast-1.console.aws.amazon.com/securityhub/home?region=ap-northeast-1#/findings?search=Id%3D%255Coperator%255C%253AEQUALS%255C%253A{}', $.detail.findings[0].Title, $.detail.findings[0].ProductName, $.detail.findings[0].Description, $.detail.findings[0].FindingProviderFields.Severity.Label, $.detail.findings[0].AwsAccountId, $.detail.findings[0].Region, $.detail.findings[0].Resources[0].Id, $.detail.findings[0].Id)"
      },
      "Next": "UpdateWorkflowStatus",
      "ResultPath": "$.snsResult"
    },
    "UpdateWorkflowStatus": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:securityhub:batchUpdateFindings",
      "Parameters": {
        "FindingIdentifiers": [
          {
            "Id.$": "$.detail.findings[0].Id",
            "ProductArn.$": "$.detail.findings[0].ProductArn"
          }
        ],
        "Workflow": {
          "Status": "NOTIFIED"
        },
        "Note": {
          "Text": "通知済み",
          "UpdatedBy": "Step Functions"
        }
      },
      "End": true,
      "ResultPath": "$.updateResult"
    }
  }
}

本ステートマシーンで実行される処理のステップ "States" は、以下の2つのみです。

stepfunction定義_中野.png

  • SNS通知用の "FormatAndPublishToSNS"
  • ワークフローステータスの変更用の "UpdateWorkflowStatus"

なお、"FormatAndPublishToSNS" 内の "Subject.$""Message.$" で States.Format を利用して通知内容を整形しており、こちらの定義をそのまま利用すると以下のような通知内容になります。

件名例:

[SecurityHub] 123456789012 アカウントで HIGH が検出されました(ap-northeast-1)

本文例:

AWS Security Hubで以下が検出されました。
・タイトル: xxx
・製品名: Security Hub (Inspector、Guardduty 等)
・検出内容: xxx
・重要度: HIGH
・AWSアカウント: 123456789012
・リージョン: ap-northeast-1
・リソース: AWS::::Account:123456789012
・詳細は以下のURLにアクセスしてください (対象アカウントへのログインが必要です)。
https://ap-northeast-1.console.aws.amazon.com/securityhub/home?region=ap-northeast-1#/xxx

おわりに

Step Functionsを使えばランタイムの管理も不要になり、とても便利だと感じました。
より複雑なロジックを入れたい場合はLambdaでの実装が必要になることも多いかと思いますが、単純な処理であればまずは一度Step Functionsでできないかを検討していきたいと思います。

この記事は私が書きました

中野 友加里

記事一覧

身体動かすの好きです。頑張って同じくらい頭も動かします。

中野 友加里

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。