🐈‍⬛

AWS上の不審な操作をSlackに通知する機能をTerraformで定義する

2023/07/02に公開

背景

勤めている企業でセキュリティ対策の担当になったこともあり、去年ぐらいからセキュリティ対策を強化するべく色々と試行錯誤して来ました。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の終了や様々なリソースの削除など、危険な操作がたくさんありますので、時間があれば、フィルターをたくさん作って、付けたり外したりできるようにしようと考えてます。

Discussion