AWS ルートユーザーでのサインインをAWS Chatbotを使ってSlackに通知してみた

2024.01.19

私のプライベートで使用しているAWSアカウントのルートユーザーではパスワードの複雑化やMFA設定を行ってはいるのですが、モニタリングなどはやっていなかったなということでやってみました。
AWS アカウントのルートユーザーのベストプラクティス

やること

簡易的な構成図を作成しました。
  

ユーザーがサインインを行うと「ConsoleLogin」イベントをus-east-1リージョンのAWS CloudTrailに記録します。
そのイベントをAmazon EventBridgeで取得してAWS ChatbotからSlackに通知される流れになります。
AWS Management Console サインインイベント

大まかな作業の流れとしては以下となります。

  1. AWS ChatBotとSlackの連携
  2. Amazon EventBridgeとAmazon SNS、AWS Chatbotの連携
  3. 動作確認

1. AWS ChatbotとSlackの連携

Slackのワークスペースと通知先のチャンネルは作成済みのところから開始します。
操作はブラウザ版のSlackから行っています。

マネジメントコンソールからAWS Chatbotのダッシュボードを開いて右上にある「チャットクライアント」でSlackを選択して「クライアントを設定」をクリックします。

クリックすると画面が遷移するので「許可する」をクリックします。

2. Amazon EventBridgeとAmazon SNS、AWS Chatbotの連携

Amazon EventBridgeなどの設定はCloudFormationを使用して作成します。
また、リソースはus-east-1リージョンで作成を行います。
作成したCloudFormationテンプレートは以下になります。

AWSTemplateFormatVersion: '2010-09-09'
Description: ConsoleLogin

Parameters:
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------# 
  WorkspaceId:
    Type: String

  ChannelId:
    Type: String

Resources:
# ------------------------------------------------------------#
# IAM
# ------------------------------------------------------------# 
  ChatbotIamRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: Chatbot-role
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: chatbot.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/ReadOnlyAccess

# ------------------------------------------------------------#
# SNS
# ------------------------------------------------------------# 
  SNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: chatbot-topic

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

# ------------------------------------------------------------#
# Chatbot
# ------------------------------------------------------------# 
  ChatbotConfiguration:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: ConsoleLogin
      IamRoleArn: !GetAtt ChatbotIamRole.Arn
      SlackWorkspaceId: !Ref WorkspaceId
      SlackChannelId: !Ref ChannelId
      SnsTopicArns:
        - !Ref SNSTopic

# ------------------------------------------------------------#
# EventBridge
# ------------------------------------------------------------# 
  EventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        detail-type:
          - "AWS Console Sign In via CloudTrail"
        detail:
          userIdentity: 
            type:
              - "Root"
      Targets:
        - Arn: !Ref SNSTopic
          Id: SNSTopic

上記のCloudFormationテンプレートをデプロイするとSNSトピック、SlackとAWS Chatbotの紐づけ、EventBridgeルールの作成を行います。
EventBridgeルールではルートユーザーでのサインインが発生したときに通知したいので以下のイベントパターンとなっています。

{
  "detail-type": ["AWS Console Sign In via CloudTrail"],
  "detail": {
    "userIdentity": {
      "type": ["Root"]
    }
  }
}

ルートユーザーのサインインイベントの例は以下のドキュメントに記載されています。
root ユーザーのイベントレコードの例

ワークスペースIDはAWS Chatbotの画面から確認ができます。

SlackのチャンネルIDは以下のように確認できます。

デプロイは以下のコマンドを実行します。

aws cloudformation create-stack --stack-name CloudFormationスタック名 --template-body file://CloudFormationテンプレートファイル名 --capabilities CAPABILITY_NAMED_IAM --parameters ParameterKey=WorkspaceId,ParameterValue=ワークスペースID ParameterKey=ChannelId,ParameterValue=チャンネルID

デプロイが完了したらSlackチャンネルに「@aws」を招待してください。
  

3. 動作確認

ルートユーザーとしてサインインするには以下のドキュメントの手順で行います。
AWS Management Console にルートユーザーとしてサインインします。

以下の画面で「ルートユーザー」を選択してメールアドレスを入力後「次へ」をクリックします。

画面が遷移したら「パスワード」を入力して「サインイン」をクリックします。

MFAが設定されている場合は以下の画面でコードを入力して「送信」をクリックします。

ルートユーザーとしてサインイン後、しばらくすると以下のようにSlackのチャンネルに通知が送信されてきます。

さいごに

作業自体は簡単なので自分のAWSアカウントを守るためにも設定しておくのがよいと思います。