AWSコンソールへのログインをGoogle Hangouts Chatで通知する
CloudWatchイベントAWS Console Sign In via CloudTrail
を使うと、AWSコンソールへのログインを検知できます。
イベントからLambdaを呼び出し、Hangouts Chatに投稿してみました。
イベントとLambdaのデプロイには、serverless frameworkを使いました。
作ったもの
IAMユーザーのログインを検知
IAMユーザーがAWSコンソールに接続すると、Hangouts Chatに通知されます。 送信元IPアドレスやログインの成功有無、User Agentなどを確認できます。
ログイン成功
IAMユーザーでログインすると、以下の通知が行われます。
ログインに成功するとConsoleLogin:Success
にります。
IPアドレス、ユーザーエージェント、IAMユーザー名などを確認できます。
ログイン失敗
ログインに失敗すると、ConsoleLogin:Failure
になります。
IAMロールでのログインを検知
IAMロールでのログインも通知されます。
Jumpアカウントに戻る操作(下図)を行うと、eventName:ExitRole
が通知されます。
事前準備
Serverless Frameworkをインストールしておきます。
$ node -v v12.2.0 $ serverless -v 1.42.2 $
AWS LambdaからGoogle Hangouts Chatに投稿してみたを参考に、Chatルームを作成し、WebHook URLを発行します。 WebHook URLにリクエストを送り、チャットに通知します。
プラグインによるパッケージ管理
LambdaはPython3.7で実行しました。 Lambda関数でrequestsパッケージを呼び出します。 パッケージ管理にserverless-python-requirementsプラグインを利用します。 serverlessのブログを参考にしました。
プラグインとrequestモジュールをインストールします。
npm install --save serverless-python-requirements pip install request pip freeze
pip freezeの結果から、requestsについてrequirements.txtに記載します。 私の環境ではrequirements.txtは以下のようになりました。
requests==2.21.0
プラグインの実行にはDockerが必要です。 Dockerデーモンを起動しておきます。
serverless frameworkの作成
providedテンプレートの作成
以下のコマンドを実行すると、serverless.yml、handler.pyのテンプレートが作成されます。
serverless create -t aws-python3 -n lambda-awslogin2hangoutschat
ファイルの記載
3つのファイルを作成します。
- serverless.yml(serverless frameworkの設定ファイル)
- handler.py(Lambda関数)
- consolelogin.json(テスト用のCloudWatchイベントファイル)
serverless.yml
Serverless Frameworkの設定ファイルです。 Lambda関数の設定や、CloudWatch Eventsなどを記述します。 environmentにはLambda関数で利用する環境変数を指定します。HANGOUT_WEBHOOK_URLにWeb HookのURLを記入します。 plugins以下は前述のプラグインの利用に必要です。
service: lambda-awslogin2hangoutschat provider: name: aws runtime: python3.7 # you can overwrite defaults here stage: prod region: ap-northeast-1 # you can add packaging information here package: exclude: - consolelogin.json functions: main: handler: handler.main events: - cloudwatchEvent: event: detail-type: - "AWS Console Sign In via CloudTrail" # Define function environment variables here environment: HANGOUT_WEBHOOK_URL: 'Hangout-URL' # Add python package(https://github.com/UnitedIncome/serverless-python-requirements) plugins: - serverless-python-requirements custom: pythonRequirements: dockerizePip: true
handler.py
Lambda関数ファイルです。
CloudWatchイベントの内容をevent変数で受け取ります。
body変数にイベントの内容eventevent['version']
、event['detail']['account']
などを追加します。
最後にWebHookにPOSTして終了です。
# -*- coding: utf-8 -*- from json import dumps, loads import requests import os def main(event, context): URL = os.environ['HANGOUT_WEBHOOK_URL'] ## event(version) body = "version:" + str(event['version']) + '\n' ## event(other) messages_keys = ["account","time","region","detail-type","eventTime","eventSource","eventName","awsRegion","requestParameters","sourceIPAddress","userAgent"] for key in messages_keys: if 'detail' in event: if key in event['detail']: body += key + ":" + str(event['detail'][key]) + '\n' ## event-detail-responseElements messages_response_keys = ["ConsoleLogin"] for key in messages_response_keys: if 'detail' in event: if 'responseElements' in event['detail']: if key in event['detail']['responseElements']: body += key + ":" + str(event['detail']['responseElements'][key]) + '\n' ## event-detail-userIdentity messages_userIdentity_keys = ["type","principalId","arn","accountId"] for key in messages_userIdentity_keys: if 'detail' in event: if 'userIdentity' in event['detail']: if key in event['detail']['userIdentity']: body += key + ":" + str(event['detail']['userIdentity'][key]) + '\n' ## event-detail-additionalEventData messages_additionalEventData_keys = ["LoginTo","MobileVersion","MFAUsed"] for key in messages_userIdentity_keys: if 'detail' in event: if 'additionalEventData' in event['detail']: if key in event['detail']['additionalEventData']: body += key + ":" + str(event['detail']['additionalEventData'][key]) + '\n' bot_message = { 'text' : body} message_headers = { 'Content-Type': 'application/json; charset=UTF-8'} ## POST response = requests.post( URL, headers=message_headers, data=dumps(bot_message), ) return loads(response.text)
consolelogin.json
CloudWatchイベントのルールの作成からAWS コンソールのサインインを選択すると、サンプルイベントを表示できます。 jsonが表示されるので、コピーアンドペーストします。
デプロイ
デプロイコマンドを実行します。
$ sls deploy
サンプルイベントを使って、テストします。 チャットに通知されれば成功です。
$ sls invoke -f main -p consolelogin.json
全リージョンへのデプロイ
東京リージョン以外にもデプロイします。 EC2のようなリージョンをサポートするコンソールにログインした場合、そのリージョンでCloudWathイベントが発生します。S3のようなグローバルサービスにログインした場合は、バージニア北部でイベントが発生します。全てのリージョンにCloudWatchイベントとLambdaを設定します。
sls deploy --region us-east-2 sls deploy --region us-east-1 sls deploy --region us-west-1 sls deploy --region us-west-2 sls deploy --region ap-east-1 sls deploy --region ap-south-1 sls deploy --region ap-northeast-3 sls deploy --region ap-northeast-2 sls deploy --region ap-southeast-1 sls deploy --region ap-southeast-2 sls deploy --region ca-central-1 sls deploy --region cn-north-1 sls deploy --region cn-northwest-1 sls deploy --region eu-central-1 sls deploy --region eu-west-1 sls deploy --region eu-west-2 sls deploy --region eu-west-3 sls deploy --region eu-north-1 sls deploy --region sa-east-1
まとめ
CloudWatchイベントAWS Console Sign In via CloudTrail
を使うと、AWSコンソールへのログインを検知できます。
イベントからLambdaを呼び出し、Hangouts Chatに投稿してみました。
Serverless Frameworkを使うことで、CloudWatchイベントの作成やPythonのパッケージ管理を簡単にできました。