投稿日
AWS Management Consoleのログインをメール通知する
もくじ
はじめに
こんにちは。アプリケーション開発部の谷野です。インキュベーションセンターが運営する自社サービス開発を担当しています。
そのサービスはインフラ環境をAWSで構成しており、システム運用のための仕掛けも同様にAWSで構成しています。
今回は運用業務の一環としてAWS Management Consoleのログインを記録する仕組みを構築した事例についてご紹介します。
本記事で利用している要件
- AWS環境
- AdministratorAccess権限を持つIAMユーザー
- Terraform v15.4
- 利用可能なメールアドレス
構成図
最終的な構成図は下図のようになります。
各AWSサービスの設定
Amazon CloudWatchのEvent Ruleの設定
まず、ログイン検知のきっかけとなるAmazon CloudWatchのEvent Ruleから構成しています。
このコードではAWS CloudTrailを介して AWS Console SingIn
のアクションを検知する部分を構成しています。 なお、この検知機能は2021年6月現在東京リージョンでは提供されていないため、今回は北米リージョンを指定しています。
provider "aws" {
alias = "us"
region = "us-east-1"
}
resource "aws_cloudwatch_event_rule" "console_login" {
name = "aws-console-login" //任意の名称
description = ""
event_pattern = <<PATTERN
{
"detail-type": [
"AWS Console Sign In via CloudTrail"
]
}
PATTERN
provider = aws.us
}
resource "aws_cloudwatch_event_target" "sns" {
rule = aws_cloudwatch_event_rule.console_login.name
arn = aws_sns_topic.login_alert.arn
provider = aws.us
}
AWS SNS Topicの設定
検知されたイベントをAWS Lambda Functionに伝えるためのAWS SNS Topicを構成しています。
ここでは通知されるメール本文を加工する目的でLambdaを利用しているため、加工する必要がない場合はSNSからメールを送信することも可能です。
resource "aws_sns_topic" "login_alert" {
name = "audit-alarm-to-mail-aws-console-login" //任意の名称
provider = aws.us
}
resource "aws_sns_topic_policy" "default" {
arn = aws_sns_topic.login_alert.arn
policy = data.aws_iam_policy_document.sns_topic_policy.json
provider = aws.us
}
resource "aws_sns_topic_subscription" "login_alert_mail" {
topic_arn = aws_sns_topic.login_alert.arn
protocol = "lambda"
endpoint = aws_lambda_function.login_alert_mail.arn
provider = aws.us
}
data "aws_iam_policy_document" "sns_topic_policy" {
statement {
effect = "Allow"
actions = ["sns:Publish"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
resources = [aws_sns_topic.login_alert.arn]
}
}
AWS Lambda Functionの設定
前項で記述したとおり、ここでは送信するメール本文を加工するためにLambda Functionを構成しています。 Node.jsのソースコードをsource_dir
に配置してzip化したものをアップロードするとともに必要な環境変数を引き渡します。
なお、module.iam_assumable_role_login_alert_mail
では以下の権限をLambdaに付与(assume-role)するためのポリシーを設定しています。
- SESからメールを送信する
ses:Send*
関連 - ログ出力用の
logs:CreateLog*
及びlogs:PutLogEvents
resource "aws_lambda_function" "login_alert_mail" {
function_name = "aws-console-login-alert-mail" //任意の名称
role = module.iam_assumable_role_login_alert_mail.iam_role_arn
filename = data.archive_file.this.output_path
source_code_hash = data.archive_file.this.output_base64sha256
runtime = "nodejs14.x"
handler = "index.handler"
memory_size = 128
timeout = 10
environment {
variables = {
to_address = 配信先メールアドレス
from_address = 配信元メールアドレス
}
}
}
resource "aws_lambda_permission" "login_alert_mail" {
action = "lambda:invokeFunction"
function_name = aws_lambda_function.login_alert_mail.function_name
principal = "sns.amazonaws.com"
source_arn = aws_sns_topic.login_alert.arn
}
data "archive_file" "this" {
type = "zip"
source_dir = "${path.module}/src"
output_path = "${path.module}/dest/tmp.zip"
}
Amazon SESを起動するスクリプトです。
var aws = require('aws-sdk');
var ses = new aws.SES({region: 'ap-northeast-1'});
exports.handler = (event, context) => {
const message = JSON.parse(event.Records[0].Sns.Message);
notify_login(message);
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
function notify_login(message) {
const userType = message.detail.userIdentity.type;
let loginUser;
if (userType == 'Root') {
loginUser = userType;
} else if (userType == 'IAMUser') {
let userName = message.detail.userIdentity.userName;
loginUser = `${userType}:${userName}`;
}
send_mail("AWSコンソール-ログイン通知", `
${loginUser} がログインしました。
時間 :${message.detail.eventTime}
ソースIP:${message.detail.sourceIPAddress}
`);
}
function send_mail(title, body) {
var params = {
Destination: {
ToAddresses: [process.env.to_address]
},
Message: {
Body: {
Text: { Data: body }
},
Subject: { Data: title }
},
Source: process.env.from_address
};
ses.sendEmail(params, function (err, data) {
if (err) {
console.log(err);
context.fail(err);
}
});
}
Amazon SESの設定
Amazon SESからメール通知する場合に必要な設定があります。
- 送信元メールアドレスの認証(必須)
SESからメールを送信するためにはメールアドレス又はドメインの認証が必要です。 認証されていない状態ではメール通知が利用できないので下記の手順を参考にあらかじめ設定しておくようにしましょう。
参考:Amazon SES でのドメインの検証
参考:Amazon SES での E メールアドレスの検証
- Amazon SESのサンドボックス解除(任意)
SESで送信元アドレス(ドメイン)を新たに登録すると、まずはサンドボックス環境として動作するようになります。 サンドボックス環境では送信数に制限がかかることと検証済みのメールアドレス宛にしか送信できない状態になっています。
不特定多数のメールアドレスに送信する場合はこの設定を解除する必要があります。 下記の手順を参考に必要に応じて解除しましょう。
実施結果
AWS Management Consoleにログインすると、下記のメールが飛んでくるようになります。
件名:AWSコンソールログイン通知
------------内容--------------
IAMUser:[IAMUser名] がログインしました。
時間 :2021-06-01T00:20:47Z
ソースIP:XXX.XXX.XXX.XXX
------------------------------
※ AWS、Amazon RDS CloudTrail、Amazon CloudWatch、Amazon SNS、AWS Lambda、Amazon SESは、米国および/またはその他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。
本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。