マルチアカウント環境でセキュリティサービスの検出結果を全てSecurity Hubに集約して通知してみた

組織内のセキュリティアラートはSecurity Hubに集約して管理すると通知設定も楽ですよ。
2022.05.10

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

以下のブログを読んだとき、「Security Hubに集約できるサービスなら全部マルチアカウントでもまとめられるのでは?」と閃いたので試してみました。

構成

構成としてはこんな感じです。Organizations統合でSecurity Hubを利用していて、リージョン集約を設定すれば自然とこの形になります。

この構成であれば、Security Hub管理アカウントの集約リージョンに検知したいEventBridgeのルールをサービス(プロダクト)ごと作成するだけで組織内全ての検出結果を通知する環境が作れます。

Security Hubの検出結果リージョン集約

前提ですが、先日アップデートがあったSecurity Hubで集約リージョンを指定すると、他リージョンのSecurity Hubからの検出結果を集約できるようになりました。

Security Hubには元々セキュリティサービスが数多く統合されているため、各リージョンごとにはセキュリティサービスの検知結果を集約できていたのですが、通知は各リージョンごとに実装する必要がありました。

これがアップデートにより1つのリージョンに集約できるため、管理がとっても楽になったというのがSecurity Hubのリージョン集約です。

参考:【アップデート】AWS Security Hub が検出結果のリージョン集約に対応しました | DevelopersIO

Security HubのOrganizations統合と組み合わせる

次にSecurity HubのOrganizations統合をリージョン集約と合わせて利用していきます。

参考: [アップデート]Security Hubが AWS Organizations と統合!組織内セキュリティチェック環境を簡単にセットアップ/管理できるようになりました | DevelopersIO

Organizations統合ではSecurity Hubの管理アカウント(ここではAudit Account)からメンバーアカウントを管理でき、管理アカウント上のリージョンごとにメンバーアカウントの検出結果を集約できる機能を持っています。(下の図では赤線で示されている部分です。)

この機能によってメンバーアカウントの検出結果は最終的に全て管理アカウント上の各リージョン上に一度集約されます。

それに先ほど紹介した検出結果リージョン集約を組み合わせることで、管理アカウント上にある集約リージョンへ全ての検出結果を集約できます。

通知の設定をしたい場合は、集約リージョンのSecurity Hubから通知したいサービスのイベントを取得するEventBridgeのルールを作成すれば良いのでとてもシンプルに考えることができそうです。

やってみる

実際に通知されるのか試してみます。今回はメンバーアカウントのGuardDutyとSecurity Hubの集約リージョン外の検出結果を、管理アカウント上の集約リージョンで設定したEventBridgeのルールから通知してみます。

  • 集約リージョン:東京リージョン
  • 集約外リージョン:バージニア北部

前提

以下の機能を利用している前提で進めるため、実装部分は省きます。各ブログをご参照ください。

EventBridgeのルール作成

Security Hubのイベントを取得するため、管理アカウントの集約リージョンに以下のリソースを作成します。

  • EventBridgeルール
  • SNSトピック

作成するEventBridgeルールのパターンは以下の2つです。

Security Hub用

{
  "detail-type": ["Security Hub Findings - Imported"],
  "source": ["aws.securityhub"],
  "detail": {
    "findings": {
      "ProductName": ["Security Hub"],
      "Severity": {
        "Label": ["LOW", "MEDIUM", "HIGH", "CRITICAL", "INFORMATIONAL"]
      }
    }
  }
}

GuardDuty用

{
  "detail-type": ["Security Hub Findings - Imported"],
  "source": ["aws.securityhub"],
  "detail": {
    "findings": {
      "ProductName": ["GuardDuty"],
      "Severity": {
        "Label": ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
      }
    }
  }
}

GuardDutyの検出結果を検知するEventBridgeルールですが、取得元はaws.securityhubであることに注意しましょう。

EventBridgeのルールとSNSトピックはCloudFormationテンプレートで作成したので、参考程度にお使い下さい。

AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  Prefix:
    Type: String
    Default: test
  GuardDutySeverities:
    Type: CommaDelimitedList
    Default: "LOW,MEDIUM,HIGH,CRITICAL"
  SecurityHubSeverities:
    Type: CommaDelimitedList
    Default: "LOW,MEDIUM,HIGH,CRITICAL,INFORMATIONAL"

Resources:
# EventBridge Rule
  GuardDutyEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${Prefix}-guardduty-finding-rule"
      EventPattern:
        "source": ["aws.securityhub"]
        "detail-type": ["Security Hub Findings - Imported"]
        "detail":
          "findings":
            "ProductName": ["GuardDuty"]
            "Severity":
              "Label": !Ref GuardDutySeverities
      Targets:
        - Arn: !Ref SnsTopic
          Id: sns-topic

  SecurityHubEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${Prefix}-securityhub-finding-rule"
      EventPattern:
        "source": ["aws.securityhub"]
        "detail-type": ["Security Hub Findings - Imported"]
        "detail":
          "findings":
            "ProductName": ["Security Hub"]
            "Severity":
              "Label": !Ref SecurityHubSeverities
      Targets:
        - Arn: !Ref SnsTopic
          Id: sns-topic

  # SNS Topic
  SnsTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub "${Prefix}-security-alert-topic"

  # SNS Topic Policy
  EventTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "events.amazonaws.com"
            Action: "sns:Publish"
            Resource: "*"
      Topics:x
        - !Ref SnsTopic

通知設定

次に通知設定を行います。先ほど作成したSNSトピックにChatbotをサブスクライブさせて通知設定を行いました。ここで設定するのはメールでも構いません。

これでSecurity Hub管理アカウント上の集約リージョンに、通知する仕組みが導入できました。

Security Hubの検出結果

それでは早速メンバーアカウント上で検出されたSecurity Hubの結果を通知させてみます。今回はバージニア北部でAWS 基礎セキュリティのベストプラクティス v1.0.0を有効化して通知させてみました。

リージョンは検出したバージニア北部、アカウントIDは塗りつぶしていますがちゃんと通知元のメンバーアカウントのIDで通知されました。

GuardDutyの検出結果

GuardDutyも同じように検出結果を通知させてみます。メンバーアカウントのバージニア北部でサンプルイベントを発行してみると、以下のような通知が確認できました。(サンプルイベントは大量に送られてくるので注意)

こちらも検出元のリージョンとメンバーアカウントのアカウントIDで通知されていますね。

というわけで、想像より簡単にマルチアカウントの通知環境を作ることができました。

考慮点

試している中で、運用では考慮しておいた方がいいかも?と思ったことがいくつかあったので書いておきます。

通知先でどのサービスの検出結果なのか分かりやすくしておく

今回の実装ではSecurity Hubに集約した検出結果を通知しているため、GuardDutyの検出結果のタイトルもSecurity Hub Findingsと表記されていることに注意してください。(GuarDutyに限らず他のサービスを統合して通知した場合も同様です。)

例えば通知するサービスごとにSlackチャンネルを分ける、通知を整形してどのサービスの検出結果なのかをタイトルに入れるなど、見分けがつくようにしておきましょう。

メンバーアカウントのユーザーへの通知をどこに実装するか

今回はマルチアカウントの管理者用にAuditアカウントへ集約して通知を実装しましたが、通知先としてはメンバーアカウントを管理しているユーザーを含めることが望ましいです。

管理アカウント側に実装するのか、メンバーアカウント上に実装するのかは考慮の余地があるかと思いますので、運用を考えながら選択しましょう。Auditアカウントから通知先を分けたい場合のアーキテクチャは以下が参考になります。

メンバーアカウントごとに実装する場合は、冒頭でも紹介した以下の記事のようにSecurity Hubの集約リージョンにEventBridgeルールを作成する形がシンプルです。

どの重要度で通知するか

今回Auditアカウントの実装は全ての検出結果を通知するようにしていますが、運用する際はどの重要度で通知するのかを検討する必要があります。通知が多すぎて見なくなってしまった…なんてことにならないようフィルタリングをうまく活用してください。

検出結果はリージョン集約とOrganizations統合で重複しない

これは考慮点というより認識しておけばいい情報なのですが、メンバーアカウント上で検出された結果に対し管理アカウントの集約リージョンで通知設定を行った場合は1つのみ通知されます。

試す前はリージョン集約とOrganizations統合の機能でどちらにも同じ検出結果が共有されるので、重複して通知されないのか気になっていましたがSecurity Hub側でうまく重複削除してくれるようです。

終わりに

Security Hubの集約機能を使ってマルチアカウント環境の検出結果を通知してみました。通知周りを各リージョン、各サービスごとに用意するとリソース数も多くなり管理が大変です。ぜひSecurity Hubに集約してシンプルな構成で通知を実装してみてください。

参考