AWS ルートユーザーが使用されたことを通知する監視設定

## 1. はじめに
* 担当サービスでは、これまで CloudWatch アラームを Slack へ飛ばすために 自作 Lambda を作成して設定していたが、最近 [AWS Chatbot](https://aws.amazon.com/jp/chatbot/) が登場したので、CloudWatch アラーム から Slack へ通知する部分を、自作 Lambda は止めて AWS Chatbot を使った監視設定へ切り替えて、監視設定をエンハンスした（AWS Chatbot はまだ現時点ではベータ版なので、少し不満な点もあるけど、これから新機能や改良されるはずなので積極的に使うようにしている・・）。

* AWS Chatbot では、CloudWatch アラームの他に、Health イベントや Budgets アラートも[サポート](https://docs.aws.amazon.com/chatbot/latest/adminguide/related-services.html)しているので、これらの通知も AWS Chatbot を使う設定にした（今後は、RDS や ElastiCache のイベントサブスクリプションもサポートされるといいな・・）。

* （AWS Chatbot のことはまた改めて書くとして・・）そんなこんなで監視設定の見直しをしていたら、AWS ルートユーザーで AWSマネジメントコンソール にサインインしたときの監視設定もこれまでのものがあまりイケてなかったので、入れ替えることにした。

* 見直しの結果、AWS ルートユーザー使用チェック監視は、[AWS 公式ブログに載っている方法](https://aws.amazon.com/jp/premiumsupport/knowledge-center/root-user-account-cloudwatch-rule/)に切り替えることにした。ただ、残念ながら、この監視は AWS Chatbot 化にはしなかった。自作 Lambda を作ればできるけど。。

## 2. AWS ルートユーザー利用の監視
* IAMドキュメント では、[AWS ルートユーザーの利用禁止](https://qiita.com/tonishy/items/9eb772b4a5a338ac6ee6#21-%E3%83%AB%E3%83%BC%E3%83%88%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%BE%E3%81%9F%E3%81%AF-root-%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88-%E3%83%AB%E3%83%BC%E3%83%88id-root-id)を推奨している。この運用ポリシーで AWS ルートユーザー が利用された場合は、ある意味緊急事態。誰が何の目的で何を行ったのかを即座に確認する必要がある。

* [これまでの監視設定](https://qiita.com/tonishy/items/bb5832c59d309fb1db4d#344-creating-cloudwatch-alarms-for-cloudtrail-events-additional-examples)
 * CloudTrail を全リージョンで有効にする。<p />ルートユーザー認証情報を使用してAWSマネジメントコンソールにサインインする<br />↓<br />そのアクティビティ情報が CloudTrail 用の CloudWatch ロググループに格納される（格納されるまで10分〜20分ほどかかる）。<p />
 * そのロググループに次のような CloudWatch ログメトリクスフィルタを設定する。<p />「ルートユーザー認証情報を使用したアクティビティ情報が保存されたら Amazon SNS へ送信する」<p />
 * Amazon SNS から Slack へ通知するための自作 Lambda を SNSのサブスクリプションに設定する。

* これまでの監視設定は、AWS ルートユーザー利用から通知まで遅くても20分ほどかかり、少しタイムラグがあった。あと、アクティビティが発生したかどうかというだけの通知のため、アクティビティの内容は通知メッセージに入っていない。<p />他の方法で監視できないかなと思い、まず、[AWS Config のマネージドルール](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/managed-rules-by-aws-config.html)に無いか探してみたけど、要望を満たすようなルールはなさそうだった。<br />で、ググっていたら、次のAWS公式ブログを見つけた。<p />[AWS ルートユーザーアカウントが使用されたことを通知する CloudWatch イベントルールを作成するにはどうすればよいですか？](https://aws.amazon.com/jp/premiumsupport/knowledge-center/root-user-account-cloudwatch-rule/)<p />（最終更新日が2019年4月19日だから、比較的新しい。ルートユーザーの利用禁止を推奨しているわりに、AWS Config にルールがなく、こんな感じでユーザに設定させるのはどうかと思うが・・）<p />この AWS公式ブログ の方法では、CloudTrail からのログインイベント通知をトリガーにして CloudWatch イベントが発動して SNS へ通知するため、ほぼリアルタイムで通知を受け取ることができる。<p />ただし、AWS Chatbot には対応してないっぽい。（試しに、サブスクリプションに AWS Chatbot を設定した SNS へ送信してみたけど、Slack へ通知が来なかった。なので、通知を Slack へ送りたい場合は、自作Lambdaを設定するか、メールからSlackへ通知するような小細工をしないといけない。）<p />テストで、メールへ通知する設定を入れてアラームを飛ばしてみたら、次のようなメールが届いた。接続元IPアドレスや、User-Agent がある。<pre>
{"version":"0","id":"20b9482a-bed9-e295-0f5f-008dcc3c0175","detail-type":"AWS Console Sign In via CloudTrail","source":"aws.signin","account":"***********","time":"2020-01-18T13:22:50Z","region":"us-east-1","resources":[],"detail":{"eventVersion":"1.05","userIdentity":{"type":"Root","principalId":"***********","arn":"arn:aws:iam::***********:root","accountId":"***********"},"eventTime":"2020-01-18T13:22:50Z","eventSource":"signin.amazonaws.com","eventName":"ConsoleLogin","awsRegion":"global","sourceIPAddress":"?.?.?.?","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36","requestParameters":null,"responseElements":{"ConsoleLogin":"Success"},"additionalEventData":{"LoginTo":"https://console.aws.amazon.com/console/home?state=hashArgs%23&isauthcode=true","MobileVersion":"No","MFAUsed":"Yes"},"eventID":"0b218cfc-b3a1-4524-8a15-ec7bedb1dacb","eventType":"AwsConsoleSignIn"}}
</pre>

## 3. AWS 公式ブログの ルートユーザー利用監視設定
[AWS ルートユーザーアカウントが使用されたことを通知する CloudWatch イベントルールを作成するにはどうすればよいですか？](https://aws.amazon.com/jp/premiumsupport/knowledge-center/root-user-account-cloudwatch-rule/)
この公式ブログの監視設定は、まず CloudTrail の設定を行ってから、CloudFormation で監視用のスタックを作成するだけ。

#### 3.1 CloudTrail設定
* サインインは us-east-1 リージョンのイベントなので、[証跡情報を全てのリージョンに適用](https://qiita.com/tonishy/items/bb5832c59d309fb1db4d#2111-creating-a-trail-for-the-first-time)する。

* AWS 公式ブログに記載がある重要事項の設定

> 重要: 開始する前に、CloudWatch イベントの CloudTrail Management 読み取り/書き込みイベントを必ず [All] または [Write-only] に設定して、ログインイベント通知をトリガーしてください。詳細については、読み取り専用/書き込み専用イベントを参照してください。
↓
[AWS マネジメントコンソール での管理イベントのログ記録](https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/logging-management-events-with-cloudtrail.html)

* 上記２つの設定を施したCloudTrailの設定確認
![20200119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/c856d219-1fa5-af49-95a2-3601c2a54989.png)

#### 3.2 公式ブログにある CloudFormation テンプレートを us-east-1 でスタック作成する
* AWSマネジメントコンソールのURLは必ず 「https://us-east-1.signin.aws.amazon.com/〜」 となる通り、サインインイベントは us-east-1 で発生する。なので、CloudWatch イベントも us-east-1 に作成する必要があるため、公式ブロブの CloudFormation テンプレートをそのまま使い、us-east-1 リージョン の CloudFormation でスタック作成する。

Root-AWS-Console-Sign-In-CloudTrail.yml

```
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

AWSTemplateFormatVersion: '2010-09-09'
Description: ROOT-AWS-Console-Sign-In-via-CloudTrail
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
    - Label:
        default: Amazon SNS parameters
      Parameters:
      - Email Address
Parameters:
  EmailAddress:
    Type: String
    AllowedPattern: "^[\\x20-\\x45]?[\\w-\\+]+(\\.[\\w]+)*@[\\w-]+(\\.[\\w]+)*(\\.[a-z]{2,})$"
    ConstraintDescription: Email address required.
    Description: Enter an email address you want to subscribe to the Amazon SNS topic
      that will send notifications if your account's AWS root user logs in.
Resources:
  RootActivitySNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: ROOT-AWS-Console-Sign-In-via-CloudTrail
      Subscription:
      - Endpoint:
          Ref: EmailAddress
        Protocol: email
      TopicName: ROOT-AWS-Console-Sign-In-via-CloudTrail
  EventsRule:
    Type: AWS::Events::Rule
    Properties:
      Description: Events rule for monitoring root AWS Console Sign In activity
      EventPattern:
        detail-type:
        - AWS Console Sign In via CloudTrail
        detail:
          userIdentity:
            type:
            - Root
      Name:
        Fn::Sub: "${AWS::StackName}-RootActivityRule"
      State: ENABLED
      Targets:
      - Arn:
          Ref: RootActivitySNSTopic
        Id: RootActivitySNSTopic
    DependsOn:
    - RootActivitySNSTopic
  RootPolicyDocument:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Id: RootPolicyDocument
        Version: '2012-10-17'
        Statement:
        - Sid: RootPolicyDocument
          Effect: Allow
          Principal:
            Service: events.amazonaws.com
          Action: sns:Publish
          Resource:
          - Ref: RootActivitySNSTopic
      Topics:
      - Ref: RootActivitySNSTopic
Outputs:
  EventsRule:
    Value:
      Ref: EventsRule
    Export:
      Name:
        Fn::Sub: "${AWS::StackName}-RootAPIMonitorEventsRule"
    Description: Event Rule ID.
```

* スタック作成前に、アラームを送信する （緊急用の）メールアドレス を入力する。

* スタック作成後に、その メールアドレスに、"AWS Notification - Subscription Confirmation" メールが届くので、メールの中の "Confirm subscription" リンクを踏む。

* 作成されるリソース
![20200119-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/ff6c456c-26df-4b4c-e9f6-0f124fee94ec.png)

* us-east-1 リージョンの CloudWatch ルールの設定はこんな感じ
![20200119-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/cbd217d4-573f-7008-3ab3-eaedf6e4772a.png)

* us-east-1 リージョンの Amazon SNS の設定はこんな感じ
（エンドポイントを追加したい場合は、「サブスクリプションの作成」で設定する感じかな）
![20200129-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/db34199f-6e69-f5c1-c9bb-f5d2c83692a4.png)

 
* 設定は以上でおわり。簡単。

#### 3.3 AWS ルートユーザーでサインインして 指定したメールアドレスに通知が来るかテスト
AWS ルートユーザーでAWSマネジメントコンソールにサインイン後、１〜２分で通知が来る。
![20200129.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/0f40ccad-9e75-181e-08ea-f7274b5e16b8.png)

ちなみに、通知はサインインのときの一回きり。
サインインを継続していても最初の一回の通知しか来ない。
リマインド通知したい場合、現時点ではSNSトピックなどではそのような機能がないため、独自でLambdaなりで実装する必要がある。