👮

CloudTrailのイベントを気軽にSlack通知する

2021/12/27に公開

概要

AWSセキュリティ監査を気軽に始めていくために手始めに
cloudtrail-tattletailというLambda用のアプリケーションを用いてAWS CloudTrailの特定イベントをSlack/emailに通知する。

CloudTrailはAWS上のあらゆるセキュリティ上のイベントが記録されるため、tattletailを利用して必要なイベントのみフィルターして通知してやる。

手始めに以下の2つのイベントをSlackに通知してみる。

  • CreateAccessKey
    • IAMユーザーにアクセスキーが作成されたときに通知される
  • StartSession
    • ssmを利用して、EC2への接続時に通知される

実行例

SSMでEC2にログインしたときのslack通知例
これとssm側でsession開始時に実行ログを全て保存しておくようにしておけば、誰がいつ何をしたのかはいつでもわかるようになる

overview


手順

  1. CloudTrail証跡の作成。
  2. cloudtrail-tattletailの設定を書く。
  3. cloudtrail-tattletailをAWS Lambdaにデプロイする。

CloudTrail証跡の作成

CloudTrailに証跡の作成 を実行して任意のS3 bucketにログが出力されるように設定を行う。

cloudtrail-tattletail 設定

CloudTrailのイベントログはJSONで保存され、tattletailはそのログに対してjqクエリを記述して条件を満たすと通知される仕組みになっている。
どんなイベントが発生してどんなJSONが出力されるかはCloudTrailのイベント履歴を参照しよう。

以下の設定例は、CreateAccessKey, StartSessionをSlack通知する設定例。

ruleにマッチさせる条件と宛先を記述して、destination は文字通り宛先を記述する。

tattletail.toml
# See: https://github.com/psanford/cloudtrail-tattletail#configuration-example
[[rule]]
name = "Create AccessKey"
jq_match = 'select(.eventName == "CreateAccessKey")'
description = "A new Access Key has been created"
destinations = ["Slack Audit"]

[[rule]]
name = "SSM Start Session"
jq_match = 'select(.eventName == "StartSession") | "username: \(.responseElements.sessionId) target: \(.requestParameters.target)"'
description = "SSM start session"
destinations = ["Slack Audit"]

[[destination]]
id = "Slack Audit"
type = "slack_webhook"
# 通知希望チャンネルのWEBHOOK
webhook_url = "___YOUR_SLACK_WEBHOOK___"

deploy

Create Lambda

S3 bucket triggerでLambdaを作る。対象はCloudTrailがログを出力しているs3 bucket

Lambdaで利用するIAMにS3 bucketに権限付与するのを忘れないように。s3:ListBucket,s3:GetObjectだけで動作する。

"Action": ["s3:ListBucket","s3:GetObject" ]

Build and Deploy

cloudtrail-tattletailにMakefileが用意されているので適当にbuildする。
ルールが記述されたtattletail.toml はLambdaのZIPファイルに同梱するか、S3_CONFIG_BUCKET, S3_CONFIG_PATH環境変数で指定できるので好きな方を使う。

buildしたら成果物のZIPをlambdaにアップロードすればできあがり。あとは要件に合わせて必要なCloudTrailのイベントや通知先をを追加していけばよい。


role_session_name

おまけ

SSM StartSessionの通知はassumed role していた場合に .responseElements.sessionIdの値がbotocore-session-1234... のような名前になってイマイチ使い勝手が悪い。

これをわかりやすくするためには、
~/.aws/configrole_session_nameを明示的に指定してやる。

~/.aws/config
[profile production-role]
role_session_name = sho2010
source_profile = default

こうすることによってAssumedRoleで同じRoleを共有していても、個別にセッション名を指定する事が可能となる。

セキュリティ要件としてssmでEC2に接続する人はこの設定を必須としてしまうのがいいだろう。

sts:RoleSessionNameを利用してシステム側で強制することも可能

See:

GitHubで編集を提案

Discussion