背景
勤めている企業でセキュリティ対策の担当になったこともあり、去年ぐらいからセキュリティ対策を強化するべく色々と試行錯誤して来ました。AWS Cloud Trailを活用して行きたいですが、ログを全て人間が目で確認するのはあまり現実的ではないです。
何か怪しい動きがあった時に自動でSlackに通知される仕組みがあれば、日々に運用が簡単になりますね。
AWSコンソールから手作業で作成しても良かったのですが、保守性と移植性を考えるとTerraformで定義した方が良いので、 terraform apply
するだけで通知の仕組みが動くように実装しました。
機能&効果
ユーザーがコンソールにログインした時と、ログインに失敗した時に通知されます。
(赤く隠された部分はクライアントのIPアドレスです。)
ログインに成功した場合は 🟢 ログインに失敗した場合は ⚠️ という風に表示がわかれます。
ちなみに信頼できないIPアドレスからログインに成功した場合は 🔴 です。
下記のようにフィルターを定義することで、任意の操作を通知させることが可能です。
consoleLogin: (record) => {
const event = record.eventName
const name = record.userIdentity.userName
const ip = record.sourceIPAddress
const error = record.errorMessage
if (event !== 'ConsoleLogin') {
return null
} else if (error) {
return `:warning: [${name}] Console login failed from ${ip}. Error: ${error}`
} else if (config.TRUSTED_IPS.indexOf(ip) !== -1) {
return `:large_green_circle: [${name || "ROOT"}] Console login from trusted IP(${ip}) detected.`
} else {
return `:red_circle: [${name || "ROOT"}] Console login from untrusted IP(${ip}) detected.`
}
}
Cloud Trail のログが record に渡されますので、返り値が null であれば、通知はされません。文字列であれば、その内容が Slack に通知される仕組みです。
構成
Cloud Trail のログを S3 に出力して、S3 のファイルアップロードをトリガーに Lambda が動作して Slack に通知するシンプルな仕組みです。
実装
Terraformのコードは GitHub 上に保存しています。Clone してから、設定を書き換えるだけで動作します。 terraform apply
でLambdaの実装も一緒にデプロイされます。
sample.tfbackend
Terraform の state ファイルを保存するための S3 バケット
bucket = バケット名(アクセス権限のあるバケット)
key = stateファイル名(任意)
region = バケットを作成したリージョン
sample.tfvars
システムの設定ファイル
ORG_NAME = 組織名、Terraformが作成するリソースの名前のプレフィックスに使用されます。
TRUSTED_IPS = 信頼できるIPをコンマ区切りで設定します。
SLACK_WEBHOOK_URL = 通知するためのSlack Webhook URL
まとめ
EC2の終了や様々なリソースの削除など、危険な操作がたくさんありますので、時間があれば、フィルターをたくさん作って、付けたり外したりできるようにしようと考えてます。