AWSアカウントにサインインやスイッチロールしたことを通知する仕組みを作ってみるのはどうだろう?とふと思ったので、作ってみました。 画面ポチポチではなく、AWS CloudFormationでデプロイします。
おすすめの方
- AWSにサインイン(スイッチロール含む)したとき、Slackに通知する仕組みを知りたい方
- 上記をAWS CloudFormationで作成したい方
- Amazon EventBridgeのAPI destinationsをCloudFormationで作成したい方
前提(大事なこと)
AWS CloudTrailを有効にする
サインインやスイッチロールは、AWS CloudTrailが検知します。 そのため、AWS CloudTrailを有効にしてください。
全リージョンにデプロイする
サインインが記録されるリージョンは、固定ではありません。 そのため、全リージョンにデプロイすることをおすすめします。 もしかしたら、他に良い方法があるかもしれません……。
なお、スイッチロールについては、該当のリージョンおよびバージニア北部(us-east-1)のそれぞれで記録されるようです。
AWSアクセスキーの利用は通知しない
今回の仕組みでは、AWSアクセスキーの利用は通知しません。 AWSアクセスキーの利用も通知したい場合は、下記などを参考にして、Amazon EventBridgeのルールを作成してください。
今回はAWS Chatbotを利用しない(情報が少ないため)
AWS ChatbotでもSlackに通知できますが、「情報が足りない」と思うかもしれません。
具体的には、下記の情報(Amazon EventBridgeのサンプルイベント)がありますが、AWS Chatbotを利用した場合だと知りたいことが少ないと思うかもしれません。
{
"version": "0",
"id": "6f87d04b-9f74-4f04-a780-7acf4b0a9b38",
"detail-type": "AWS Console Sign In via CloudTrail",
"source": "aws.signin",
"account": "123456789012",
"time": "2016-01-05T18:21:27Z",
"region": "us-east-1",
"resources": [],
"detail": {
"eventVersion": "1.02",
"userIdentity": {
"type": "Root",
"principalId": "123456789012",
"arn": "arn:aws:iam::123456789012:root",
"accountId": "123456789012"
},
"eventTime": "2016-01-05T18:21:27Z",
"eventSource": "signin.amazonaws.com",
"eventName": "ConsoleLogin",
"awsRegion": "us-east-1",
"sourceIPAddress": "0.0.0.0",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 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": "No"
},
"eventID": "324731c0-64b3-4421-b552-dfc3c27df4f6",
"eventType": "AwsConsoleSignIn"
}
}
そのため、本記事では、Amazon EventBridgeからSlackのIncoming WebhookにHTTPリクエストを行いました。
SlackのIncoming WebhookのURLを取得する
次のドキュメントを参考にして、Incoming WebhookのURLを取得します。
動作を確認しておきます。
curl -X POST -H "Content-type: application/json" \
-d '{"text": "Hello, world."}' \
"https://hooks.slack.com/services/aaa/bbb/ccc"
AWSアカウントへのサインインやスイッチロールを検知してSlackに通知する仕組みを作る
CloudFormationテンプレート
Amazon EventBridgeのルールを定義し、API destinationsでSlackに通知します。通知内容などは、必要に応じてカスタマイズしてください。
notify.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: Notify slack aws signin stack
Parameters:
SlackIncomingWebhookUrl:
Type: String
Resources:
SigninEventRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.signin
detail-type:
- AWS Console Sign In via CloudTrail
detail:
eventSource:
- signin.amazonaws.com
Targets:
- Id: NotifySlackSigninApiDestination
Arn: !GetAtt NotifySlackSigninApiDestination.Arn
RoleArn: !GetAtt NotifySlackSigninEventRuleRole.Arn
InputTransformer:
InputPathsMap:
account: $.account
eventTime: $.detail.eventTime
eventName: $.detail.eventName
eventID: $.detail.eventID
userIdentityType: $.detail.userIdentity.type
userIdentityArn: $.detail.userIdentity.arn
LoginTo: $.detail.additionalEventData.LoginTo
SwitchFrom: $.detail.additionalEventData.SwitchFrom
SwitchTo: $.detail.additionalEventData.SwitchTo
InputTemplate: >
{
"blocks": [
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*eventName:* <eventName>"
},
{
"type": "mrkdwn",
"text": "*eventID:* <eventID>"
},
{
"type": "mrkdwn",
"text": "*account:* <account>"
},
{
"type": "mrkdwn",
"text": "*eventTime:* <eventTime>"
},
{
"type": "mrkdwn",
"text": "*userIdentityType:* <userIdentityType>"
},
{
"type": "mrkdwn",
"text": "*userIdentityArn:* <userIdentityArn>"
},
{
"type": "mrkdwn",
"text": "*LoginTo:* <LoginTo>"
},
{
"type": "mrkdwn",
"text": "*SwitchFrom:* <SwitchFrom>"
},
{
"type": "mrkdwn",
"text": "*SwitchTo:* <SwitchTo>"
}
]
}
]
}
NotifySlackSigninEventRuleRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub notify-slack-signin-event-rule-${AWS::Region}-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: "deploy-iam-sample-deploy-policy-for-user"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: events:InvokeApiDestination
Resource: !GetAtt NotifySlackSigninApiDestination.Arn
NotifySlackSigninConnection:
Type: AWS::Events::Connection
Properties:
Name: notify-slack-signin-connection
AuthorizationType: API_KEY
AuthParameters:
ApiKeyAuthParameters:
ApiKeyName: dummy
ApiKeyValue: dummy
NotifySlackSigninApiDestination:
Type: AWS::Events::ApiDestination
Properties:
Name: notify-slack-signin-api-destination
ConnectionArn: !GetAtt NotifySlackSigninConnection.Arn
HttpMethod: POST
InvocationEndpoint: !Ref SlackIncomingWebhookUrl
デプロイ
リージョン(us-east-1)とパラメータを指定します。
SlackIncomingWebhookUrl
には、SlackのIncoming WebhookのURLを指定します。
aws cloudformation deploy \
--template-file notify.yaml \
--stack-name notify-slack-aws-signin-chatbot-stack \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1 \
--parameter-overrides \
SlackIncomingWebhookUrl="https://hooks.slack.com/services/xxx/yyy/zzz" \
--no-fail-on-empty-changeset
動作確認する
IAMユーザの動作確認は、別途、ap-southeast-2にデプロイして確認しています。
なお、Slackアプリ名が「CircleCI」になっていますが、本実験用に「既存の実験用Slackアプリ(名前:CircelCI)」を利用したためです。気にしないでくださいませ。
サインイン(IMAユーザ)
スイッチロール(IAMロール)
スイッチバック(IAMロール)
さいごに
AWSアカウントへのサインインやスイッチロールをSlackに通知する仕組みをCloudFormationで作ってみました。 具体的な運用ルールなどを設ける必要はありますが、明らかに怪しいアクセス(土日祝など)には気づけると思います。
参考
- Sending messages using Incoming Webhooks | Slack
- 【アップデート】EventBridgeのターゲットにHTTPのエンドポイントが指定可能になったので、EventBridgeから直接SlackのAPIを叩いてみた | DevelopersIO
- Integrating using the new API Destinations of Amazon EventBridge | by Samuel Vandecasteele | Medium
- EventBridge を利用して IAM User の SwitchRole 通知を行う - サーバーワークスエンジニアブログ
- リージョン別サインインイベントのログ記録
- AWS Management Console サインインイベント - AWS CloudTrail
- CloudTrailが記録するConsoleLoginイベントについて | DevelopersIO
- 特定の AWS 認証情報の使用状況を追跡する