EventBridge, SNS, Chatbot で AWS Securtiy Hub から検出結果を Slack に飛ばす

2020年9月29日

概要

やりたいこと

Security Hub から、条件を指定して結果アラート(Findings) を Slack に飛ばしたい。

以前はメールに飛ばした。

全体構成

以下の流れ。

  • Security Hub -> EventBridge -> SNS -> Chatbot -> Slack

EventBridge と SNS は下で解説したので割愛。

Security Hub のイベントパターンは以下を参照。

今回は全リージョンの Security Hub を対象とする。

AWS Chatbot

Chatbot の利点は Slack Webhook URL を Call する Lambda を作らなくてよくなること。

利用にはワークスペース ID とチャンネル ID が必要となる。

ワークスペース ID の取得方法は後述。
チャンネル ID は Slack チャンネルを右クリックし、リンクをコピーすると以下の値が取得できる。

  • チャンネル ID : ABCD1234
https://xxxx.slack.com/archives/ABCD1234

Slack チャンネルはプライベートでもパブリックでも両方飛ばすことができるが、Direct messages には飛ばせられない。

プライベートチャンネルに飛ばしたい場合は、以下のコマンドを打つ。

/invite @aws

CloudFormation StackSets

Chatbot と Slack Workspace 連携

CloudFormation ではできないのでコンソールから操作。

Chatbot コンソールより、「新しいクライアント」を設定

Slack を選択し「設定」。

対象のワークスペースであることを確認し「Allow」。

このワークスペース ID は後で必要になるのでメモっておく。

※プライベートチャンネルに飛ばしたい場合は、チャンネル内で以下のコマンドを打っておく。

/invite @aws

EventBridge + SNS Topic

テストのため、SecurityHub の全イベントの全イベントを検知対象とする。

AWSTemplateFormatVersion: 2010-09-09
Description: EventBridge + SNS for SecurityHub to Slack

Resources:

  SecurityHubTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub securityhub-to-slack
 
  SecurityHubTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref SecurityHubTopic
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Sid: SecurityHubSNSPolicy
            Action:
              - sns:Publish
            Effect: Allow
            Resource: !Ref SecurityHubTopic
            Principal:
              Service:
                - events.amazonaws.com

  SecurityHubRule:
    Type: AWS::Events::Rule
    Properties:
      Name: SecurityHub-Finding-To-Slack
      EventPattern:
        source:
          - aws.securityhub
      Targets:
        - Arn: !Ref SecurityHubTopic
          Id: TargetSNSTopic

StackSet 作成。

aws cloudformation create-stack-set \
--stack-set-name securityhub-sns \
--template-body file://securityhub_sns.yaml \
--administration-role-arn arn:aws:iam::111122223333:role/AWSCloudFormationStackSetAdministrationRole \
--execution-role-name AWSCloudFormationStackSetExecutionRole

Instance 作成。

aws cloudformation create-stack-instances \
--stack-set-name securityhub-sns \
--accounts '["111122223333"]' \
--regions '["ap-northeast-1","ap-northeast-2", "ap-south-1", "ap-southeast-1", "ap-southeast-2", "ca-central-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-west-3", "eu-north-1", "sa-east-1", "us-east-1", "us-east-2", "us-west-1", "us-west-2"]' \
--operation-preferences FailureToleranceCount=0,MaxConcurrentCount=1

EventRule と SNS Topic が作成されていること。

SNS サブスクリプションはこの時点では作成れていない。

Chatbot

Chatbot はグローバリソースなので、EventBridge、 SNS とは CloudFromation Template を分けておく。

AWSTemplateFormatVersion: 2010-09-09
Description: Enable AWS Chatbot

Parameters:
  SlackWorkspaceId:
    Type: String
  SlackChannelId:
    Type: String

Resources:
  
  ChatbotForSecurityHub:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties: 
      ConfigurationName: chatbot-for-securityhub
      IamRoleArn: !GetAtt ChatbotIamRole.Arn
      LoggingLevel: INFO
      SlackChannelId: !Ref SlackChannelId
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SnsTopicArns: 
        - !Sub 'arn:aws:sns:ap-northeast-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:ap-northeast-2:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:ap-south-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:ap-southeast-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:ap-southeast-2:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:ca-central-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:eu-central-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:eu-west-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:eu-west-2:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:eu-west-3:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:eu-north-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:sa-east-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:us-east-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:us-east-2:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:us-west-1:${AWS::AccountId}:securityhub-to-slack'
        - !Sub 'arn:aws:sns:us-west-2:${AWS::AccountId}:securityhub-to-slack'
  
  ChatbotIamRole:
    Type: AWS::IAM::Role
    Properties: 
      RoleName: ChatbotIamRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action: "sts:AssumeRole"
            Principal:
              Service: "chatbot.amazonaws.com"
      Policies: 
        - PolicyName: AWS-Chatbot-NotificationsOnly-Policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Action:
                  - "cloudwatch:Describe*"
                  - "cloudwatch:Get*"
                  - "cloudwatch:List*"
                Effect: "Allow"
                Resource: "*"

StackSet 作成。

aws cloudformation create-stack-set \
--stack-set-name securityhub-chatbot \
--template-body file://securityhub_chatbot.yaml \
--parameters ParameterKey=SlackWorkspaceId,ParameterValue=XXXXXXX ParameterKey=SlackChannelId,ParameterValue=YYYYYYYY \
--capabilities CAPABILITY_NAMED_IAM \
--administration-role-arn arn:aws:iam::111122223333:role/AWSCloudFormationStackSetAdministrationRole \
--execution-role-name AWSCloudFormationStackSetExecutionRole

インスタンス作成。

aws cloudformation create-stack-instances \
--stack-set-name securityhub-chatbot \
--accounts '["111122223333"]' \
--regions '["ap-northeast-1"]' \
--operation-preferences FailureToleranceCount=0,MaxConcurrentCount=1

以下のように、チャネルが作成される。

SNS Topic にサブスクリプションも追加される。

Security Hub のセキュリティ基準のどれかを off/on にし、アラートを発生させたあとに Slack に通知されれば OK。

参考

Security HubのイベントをAWS ChatbotでSlackへ通知

CloudFormation で AWS Chatbot と CloudWatch Alarm を定義してSlackにアラート通知してみた

【全リージョン対応】EventBridge + SNS + Chatbotで GuardDutyの結果を Slackチャンネルに通知する