【CloudFormation】一撃でInspectorのメール通知を実現させてみる

2021.11.12

こんにちは、森田です。
この記事では、Inspectorの評価結果が"High"または"Medium"となった場合にのみ、メール通知が行われるようにCloudFormationで構築します。

構成

今回作成する構成は以下のようになります。
Inspectorの検出結果をSecurity Hubに統合、Security HubのEventとしてSNSのパブリッシュを行い、対象のメールアドレスに通知を行います。

前提

Inspectorの検出結果をSecurity Hubに統合させておく必要があります。まだの方は、Security Hubの統合より結果を受け入れるを有効にしてください。

やってみる

以下が今回作成したCloudFormationのテンプレートになります。
ポイントとしては、メールの内容が見やすいように入力トランスフォーマーで、JSONの加工を行なっております。

inspectornotify.yml

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  Email:
    Type: String
    Description: "Email destination address"
    AllowedPattern: "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"
    MinLength: 5

Resources:
  InspectorNotifyEvent:
    Type: AWS::Events::Rule
    Properties: 
      EventPattern: 
        {
          "source": [
            "aws.securityhub"
          ],
          "detail-type": [
            "Security Hub Findings - Imported"
          ],
          "detail": {
            "findings": {
              "ProductArn": [ !Sub "arn:aws:securityhub:${AWS::Region}::product/aws/inspector"],
              "Severity": {
                "Label": [
                  "HIGH",
                  "MEDIUM"
                ]
              },
              "Workflow": {
                "Status": [
                  "NEW"
                ]
              }
            }
          }
        }
      Targets: 
        - Arn: !Ref SnsTopic
          Id: LogGroup
          InputTransformer:
            InputPathsMap:
              "DATE" : "$.detail.findings[0].UpdatedAt"
              "Description" : "$.detail.findings[0].Description"
              "ID" : "$.detail.findings[0].Id"
              "LEVEL" : "$.detail.findings[0].Severity.Label"
            InputTemplate: |
                "LEVEL : <LEVEL>" 
                "ID : <ID>"
                "Description : <Description>" 
                "DATE : <DATE>" 

  SnsTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: notify-mail
      Subscription:
        - Endpoint: !Ref Email
          Protocol: email

  SnsTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: events.amazonaws.com
          Action: sns:Publish
          Resource: !Ref SnsTopic
    
      Topics:
        - !Ref SnsTopic

Outputs:
  EventBridgeARN: 
    Value: !GetAtt InspectorNotifyEvent.Arn
  SnsTopicARN:
    Value: !Ref SnsTopic

スタックの作成

送信先メールアドレスがパラメータとして求められますので、入力します。

スタックの作成に成功すると作成したリソースのARNが出力に表示されます。

メールの確認

先ほど入力したメールアドレスに確認のメールが届きますので、リンクを開き承諾します。

実際に通知させてみる

CloudFormationでリソースの作成はできましたが、本当に通知されるかがわかりません。
そこで、Inspectorで"middle"を検出させるようにEC2のSecurity Groupで使用しないPort(2049)を開けてみます。

Inspectorで全EC2を対象として、Network Reachabilityの評価を実行します。

すると、"Medium"が検出され、正しく動作していれば、下記のようにメール通知がきます。

まとめ

当初、EventBridge→SNSでは、生のJSONしか渡せないと思っており、メール内容加工のため、SNS→Lambda→SNSの構成を考えておりました。
メール内容加工だけのために、Lambdaとか面倒だなぁと思ってたところ、以下の記事を教えてもらい、入力トランスフォーマーの存在を知りました。(便利!)

参考にした記事