AWS Security Hubの内容をSlackに通知する (CloudFormation利用)

通知したら終わりじゃありません。始まりです。
2022.04.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS Security Hubの内容をSlackに通知してみました。CloudFormationでデプロイします。

おすすめの方

  • AWS Security Hubを有効にしたあと、どうしたら良いのか知りたい方
    • あくまでも参考です
  • AWS Security Hubの内容をSlackに通知したい方

通知条件を決める

今回は、下記をすべて満たす条件の内容をSlackに通知します。

  • コンプライアンスのステータス: PASSED以外
  • ワークフローのステータス: NEW

このあたりは、各自で検討・調整してください。

AWS Security Hubの運用ルールを決める

AWS Security Hubを有効にしただけだと、「ワークフローのステータス:NEW」がたくさんあるため、通知もたくさん来ます。定期的に。

そのため、下記の手順で対応することにしました。

  1. AWS Security Hubを有効にする
  2. コンプライアンスのステータスが「PASSED以外」、かつ、ワークフローのステータスが「NEW」の内容をSlackに通知する
  3. 各重要度の内容がSlackに通知されたことを確認する
  4. それぞれの内容について、ワークフローのステータスを「NOTIFIED」に変更する
  5. それぞれの内容について、必要に応じて対応し、ワークフローのスタータスを「RESOLVED(解決済) or SUPPRESSED(対応不要)」のいずれかに変更する

そして、新たな通知がSlackに来たあとは、内容を確認し、必要に応じて対応し、ワークフローのスタータスを「NOTIFIED(通知済) or RESOLVED(解決済) or SUPPRESSED(対応不要)」のいずれかに変更します。

ワークフローのステータスを一括で「NOTIFIED」にする場合は、下記もご覧ください。

AWS Chatbotを準備する

AWS Chatbotにアクセスし、Slackワークスペースにアクセスできるように設定します。

AWS Chatbotの設定をする(Slack連携)

AWS Chatbotの設定をする(Slack連携)

ワークスペースIDはあとで使います。

AWS Chatbotの設定をした(Slack連携)

Slackにチャンネルを作成する

Slackにチャンネルを作成します。今回は、重要度ごとにチャンネルを作ってみました。 このあたりは、各自の運用ルールに従ってください。

Slackに通知先のチャンネルを作った

おまけとして、チャンネルのトピックに重要度の説明を設定しておきました。

Slackチャンネルの説明欄

重要度 説明
CRITICAL この問題は悪化しないようにすぐに修正する必要があります。
HIGH この問題は優先事項として対処する必要があります。
MEDIUM この問題は対処する必要がありますが、緊急ではありません。
LOW この問題は単独で対処する必要はありません。
INFORMATIONAL 問題は見つかりませんでした。

AWS Security Hubの内容をSlackに通知する仕組みを作成する

CloudFormationテンプレート

ワークスペースIDやチャンネルIDは、パラメータとしてデプロイ時に外部から設定します。 AWS SystemsManagerのパラメータストアを使ったり、必要に応じて変更してください。

通知条件のカスタマイズは、下記などを参考にしてください。

notify_security_hub_slack.yaml

AWSTemplateFormatVersion: "2010-09-09"
Description: Notify SecurityHub to Slack

Parameters:
  SlackWorkspaceId:
    Type: String

  SlackCriticalChannelId:
    Type: String

  SlackHighChannelId:
    Type: String

  SlackMediumChannelId:
    Type: String

  SlackLowChannelId:
    Type: String

Resources:
  NotifySecurityHubCriticalChatbot:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: !Sub notify-security-hub-critical-chatbot
      IamRoleArn: !GetAtt NotifySecurityHubSlackChatbotIamRole.Arn
      LoggingLevel: INFO
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SlackChannelId: !Ref SlackCriticalChannelId
      SnsTopicArns:
        - !Ref NotifySecurityHubCriticalTopic

  NotifySecurityHubHighChatbot:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: !Sub notify-security-hub-high-chatbot
      IamRoleArn: !GetAtt NotifySecurityHubSlackChatbotIamRole.Arn
      LoggingLevel: INFO
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SlackChannelId: !Ref SlackHighChannelId
      SnsTopicArns:
        - !Ref NotifySecurityHubHighTopic

  NotifySecurityHubMediumChatbot:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: !Sub notify-security-hub-medium-chatbot
      IamRoleArn: !GetAtt NotifySecurityHubSlackChatbotIamRole.Arn
      LoggingLevel: INFO
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SlackChannelId: !Ref SlackMediumChannelId
      SnsTopicArns:
        - !Ref NotifySecurityHubMediumTopic

  NotifySecurityHubLowChatbot:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: !Sub notify-security-hub-low-chatbot
      IamRoleArn: !GetAtt NotifySecurityHubSlackChatbotIamRole.Arn
      LoggingLevel: INFO
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SlackChannelId: !Ref SlackLowChannelId
      SnsTopicArns:
        - !Ref NotifySecurityHubLowTopic

  NotifySecurityHubSlackChatbotIamRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub notify-slack-chatbot-role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: chatbot.amazonaws.com
            Action: sts:AssumeRole
      Policies: 
        - PolicyName: !Sub notify-slack-chatbot-policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Action:
                  - cloudwatch:Describe*
                  - cloudwatch:Get*
                  - cloudwatch:List*
                Effect: Allow
                Resource: "*"

  NotifySecurityHubCriticalEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.securityhub
        detail-type:
          - Security Hub Findings - Imported
        detail:
          findings:
            Compliance:
              Status:
                - anything-but: PASSED
            Severity:
              Label:
                - CRITICAL
            Workflow:
              Status:
                - NEW
      Targets:
        - Id: NotifySecurityHubCriticalTopic
          Arn: !Ref NotifySecurityHubCriticalTopic

  NotifySecurityHubHighEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.securityhub
        detail-type:
          - Security Hub Findings - Imported
        detail:
          findings:
            Compliance:
              Status:
                - anything-but: PASSED
            Severity:
              Label:
                - HIGH
            Workflow:
              Status:
                - NEW
      Targets:
        - Id: NotifySecurityHubHighTopic
          Arn: !Ref NotifySecurityHubHighTopic

  NotifySecurityHubMediumEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.securityhub
        detail-type:
          - Security Hub Findings - Imported
        detail:
          findings:
            Compliance:
              Status:
                - anything-but: PASSED
            Severity:
              Label:
                - MEDIUM
            Workflow:
              Status:
                - NEW
      Targets:
        - Id: NotifySecurityHubMediumTopic
          Arn: !Ref NotifySecurityHubMediumTopic

  NotifySecurityHubLowEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.securityhub
        detail-type:
          - Security Hub Findings - Imported
        detail:
          findings:
            Compliance:
              Status:
                - anything-but: PASSED
            Severity:
              Label:
                - LOW
            Workflow:
              Status:
                - NEW
      Targets:
        - Id: NotifySecurityHubLowTopic
          Arn: !Ref NotifySecurityHubLowTopic

  NotifySecurityHubCriticalTopic:
    Type: AWS::SNS::Topic

  NotifySecurityHubHighTopic:
    Type: AWS::SNS::Topic

  NotifySecurityHubMediumTopic:
    Type: AWS::SNS::Topic

  NotifySecurityHubLowTopic:
    Type: AWS::SNS::Topic

  NotifySecurityHubTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: sns:Publish
            Resource: '*'
      Topics:
        - !Ref NotifySecurityHubCriticalTopic
        - !Ref NotifySecurityHubHighTopic
        - !Ref NotifySecurityHubMediumTopic
        - !Ref NotifySecurityHubLowTopic

EventBridgeの設定をカスタマイズしたい場合は、下記の記事などを参考にしてください。WebコンソールでポチポチしたJSONをYAMLに落とし込むと楽になります。

デプロイ

parameter-overridesは、各自で設定してください。

aws cloudformation deploy \
    --template-file notify_security_hub_slack.yaml \
    --stack-name notify-security-hub-slack-stack \
    --capabilities CAPABILITY_NAMED_IAM \
    --no-fail-on-empty-changeset \
    --parameter-overrides \
        SlackWorkspaceId=aaa \
        SlackCriticalChannelId=bbb \
        SlackHighChannelId=ccc \
        SlackMediumChannelId=ddd \
        SlackLowChannelId=eee

動作確認

しばらく待つと、各チャンネルに通知が来ました。

SlackにSecurity Hubの内容が通知された

さいごに

通知設定がゴールではありません。通知されたら、しっかりと確認&対応していきたいですね。

参考