ちょっと話題の記事

EC2インスタンスを消したのは誰?AWS CloudTrailを使って犯人を捜せ!

2015.05.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

複数人で使っているAWSアカウントでいつの間にか自分で作成したEC2インスタンスが削除されていました。どのユーザが削除したか調査する必要があります。AWSにはManagement ConsoleやAWS CLI、AWS SDKからAPIを実行した場合に操作履歴を残すことができるCloudTrailという機能があります。これを使ってEC2インスタンスを削除したユーザを調査してみたいと思います。CloudTrailで残した履歴はManagement Consoleから見ることができますが以下のような制約があります。

  • 7日間しか見れない。
  • リクエスト元IPアドレスなどJSONファイルには含まれているが表示されない項目がある。
  • 複数フィルタをかけられない。
  • あいまいな条件で検索できない。
  • すべてのリージョンをまとめて参照できない。
  • 日付の降順以外でソートできない。

Management Consoleで操作履歴を確認したところ7日以内にインスタンスを削除した人はいませんでした。S3にもログが保存されていますが複数に分かれたJSON形式のファイルなので確認するのは厳しそうです。ログ解析のツールやサービスと連携することもできますが構築する時間や費用がかかります。今回はS3に残しているログを確認したいだけなのでS3にアップロードされたJSON形式のファイルをTSVにしてExcelで確認してみたいと思います。

CloudTrailが有効でない場合

CloudTrailはデフォルトの設定ではオフになっており、リージョンごとに設定する必要があります。一括で有効にする場合は以下のRubyスクリプトを実行するといいでしょう。CloudTrailがオフの場合は調査することができないので今回はCloudTrailが有効にしていた前提で話を進めます。

新規アカウントでもこれ一発!CloudTrailを全リージョンで有効化するスクリプトを書いた

TSV変換スクリプトを実装する

MacとWindowsでS3にあるJSON形式のログをダウンロードしてTSV形式に変換するスクリプトを実装してみます。S3上のファイルをローカルにコピーして解凍した後にJSONをパースして連結しているだけの簡単なものです。

Macの場合

シェルスクリプトを実装します。まずは必要なライブラリをインストールします。S3からファイルをダウンロードするためにAWS CLIをインストールして下さい。MacでAWS CLIをインストールしたり初期設定する方法は以下の記事をご覧ください。今回は使ったバージョンは1.7.26になります。

【初心者向け】MacユーザがAWS CLIを最速で試す方法

次にS3にアップロードされたJSONを解析するjqというライブラリを以下のコマンドでインストールします。jqのバージョンは1.4で試しました。

brew install jq


準備ができたので以下のファイルを作業フォルダに置いて下さい。

cloudtrail2tsv.sh

#!/bin/sh
S3_PATH=s3://[バケット名]/AWSLogs/[アカウントID]/CloudTrail/
OUT_FILE=out.tsv
WORK_DIR=~/work/

cd ${WORK_DIR}
aws s3 sync ${S3_PATH} log

echo eventTime	awsRegion	eventSource	eventName	userName	sourceIPAddress	userAgent	requestParameters > ${OUT_FILE}
find ./log -name "*.json.gz" | xargs gunzip -c | jq ".Records[]" | \
jq -r '"\(.eventTime)	\(.awsRegion)	\(.eventSource)	\(.eventName)	\(.userIdentity.userName)	\(.sourceIPAddress)	\(.userAgent)	\(.requestParameters)"' >> ${OUT_FILE}

出来たら実行してみましょう。作業フォルダにlogフォルダとout.tsvというファイルが生成されたら成功です。

cd ~/work
chmod +x cloudtrail2tsv.sh
./cloudtrail2tsv.sh

Windowsの場合

バッチファイルを実装します。Macの場合と同様にまずは必要なライブラリをインストールします。S3からファイルをダウンロードするためにAWS SDKのインストーラを以下からダウンロードしてインストールして下さい。今回使ったバージョンは1.7.26になります。

AWS コマンドラインインターフェイス

インストール後、以下のaws configureコマンドでAPIキーなどの設定を行ってください。

c:\tmp>aws configure
AWS Access Key ID [****************]:
AWS Secret Access Key [************]:
Default region name [ap-northeast-1]:
Default output format [None]:


次にjqをダウンロードします。ダウンロードしたファイルを解凍して作業フォルダにおいて下さい。Mac版やLinux版と違いシングルクォーテーション使うとエラーになったので、ダブルクォーテーションをエスケープしています。今回使ったバージョンは1.4になります。
Download jq

Windowsにはgzファイルを解凍するコマンドがないので以下からダウンロードします。
The gzip home page

準備ができたので以下のファイルを作業フォルダに置いて下さい。

cloudtrail2tsv.bat

@echo off
set S3_PATH=s3://[バケット名]/AWSLogs/[アカウントID]/CloudTrail/
set OUT_FILE=out.tsv
set WORK_DIR=C:\work/

cd %WORK_DIR%
aws s3 sync %S3_PATH% log

echo eventTime	awsRegion	eventSource	eventName	userName	sourceIPAddress	userAgent	requestParameters > %OUT_FILE%
for /f "usebackq tokens=*" %%i in (`dir *.json.gz /b /s`) do ^
gzip -dc %%i | jq ".Records[]" | jq -r "\"\(.eventTime)	\(.awsRegion)	\(.eventSource)	\(.eventName)	\(.userIdentity.userName)	\(.sourceIPAddress)	\(.userAgent)	\(.requestParameters)\"" >> %OUT_FILE%

作業用フォルダは以下のような構成になります。もちろんパスを通してれば同じフォルダに入れる必要はないです。

cloudtrail-sample-4

出来たら実行してみましょう。作業フォルダにlogフォルダとout.tsvというファイルが生成されたら成功です。私はほとんどバッチファイルを書いたことがないので書き方などおかしいところがあるかもしれませんがとりあえず動くので許してください。

cd c:\work
cloudtrail2tsv.bat

操作履歴を調査する

TSVファイルにすることができたので実際に調査してみます。各項目の説明は以下になります。

項目名 説明
eventTime イベントが発生した日時(UTC)。
awsRegion イベントが発生したリージョン。東京リージョンの場合はap-northeast-1。
eventSource イベントが発生したサービス。EC2の場合であれば、ec2.amazonaws.com になります。
eventName イベント名。参照系の多くのイベント名はDescribe、Get、Listなどで始まるので必要なければフィルタリングしましょう。
userName アカウント名。
sourceIPAddress リクエスト元IPアドレス。
userAgent ブラウザの情報や携帯端末の機種情報。
requestParameters 送信されたリクエストパラメータ。ここはイベントによって項目が異なるのでJSON形式のままにしています。

EC2インスタンスを誰がTerminateしたのか?

それでは実際にExcelで開いて調査してみましょう。画像では見やすいように線を入れたりヘッダーの背景色を変えて見ています。まずは表にフィルターを設定してからeventNameをTerminateで検索するとTerminateInstancesというイベント名が表示されますのでこちらを選択します。

cloudtrail-sample-2

次にrequestParameters列を見てみるとTerminateしたインスタンスのIDが表示されています。削除されたインスタンスIDが確認できたらそのレコードのuserNameに表示されている人が犯人になります。簡単に見つけることができましたね。

cloudtrail-sample-3

おまけ

CloudWatch Logsに関して

CloudWatch Logsを使えば表示はJSON形式になりますが7日よりも以前のCloudTrailのログをWeb上で確認することができます。またログを見るだけでなく特定の条件のイベントが発生したらメールを送信する機能があり便利そうです。興味のある方は以下の記事をご覧ください。

CloudTrailとCloudWatch Logsの連携によるログのアラーム設定
AWS管理コンソールの不正ログインをCloudTrail と CloudWatch Logsで検知する

まとめ

CloudTrailを使って履歴から調査してみました。デフォルトでオンにしてもいいんじゃないかと思うほど重要な機能だと思います。料金はCloudTrail自体は無料でS3に出力したログに対して課金されます。ほっとくとどんどん増えていくのでS3のLifeCycle機能を使ってローテーションさせたり、Amazon Glacierに移動させたりするといいでしょう。

Amazon S3でオブジェクトの有効期限を設定できるようになりました
Amazon S3のGlacierアーカイブ機能を活用する