CloudTrailのイベントダウンロードをCloudshellから行いたい
背景
アプリケーションが稼働するアカウントAと監査データ収集用アカウントBがある。
構築期間中は、アカウントAからアカウントBへの監査データ収集はオンになってしないが、データとしては必要になる。
CloudTrailに記録されているデータの大部分は東京リージョンであるが、サインイン時に飛ばされてたまに別のリージョンに行ってしまうこともある。つまり、有効にしている全リージョンのイベントデータをダウンロードすることが必要になりました!
いろいろ試行錯誤してみたので、記録としてまとめてみました。
【番外編】方法その0
コンソール画面から「イベントをダウンロード」からダウンロードをする
いきなり番外編か!!と突っ込まれそうですが、コンソール画面からダウンロードするのが最も直感的で良いと思います。ただ、これだといちいちリージョンを変更する手間があります。
ちなみに、人間が読みやすいのは圧倒的CSVです。
方法その1
CloudshellからS3ダウンロードを行う
※この方法は事前にCloudTrailの証跡の作成をされていることが前提です。
証跡保存先のバケットを指定してまるごとダウンロードしてしまおうという方法です。
- 証跡ログの場所がリンクになっているのでクリックしてS3バケットに飛びます
飛ぶとフォルダ階層になっています。
-
「cloudtrail/AWSLogs/」フォルダまでクリックし、「<アカウントID>/」フォルダが表示されるまで階層を下ります。
-
左側のチェックボックスにチェックを入れ、「S3 URIをコピー」をクリックします。
- 以下のコマンドの<S3 URI>の部分を先ほどコピーしたものと置き換えます。
aws s3 cp <S3 URI> . --recursive
※あとで使います
-
Cloudshellを開きます。
-
一時的なフォルダを作成しその中で実行するようにしたいのでcloudtrail-dlフォルダを作っておきます。
mkdir cloudtrail-dl
cd cloudtrail-dl
pwd
- 以下コマンドを実行しダウンロードが終了するまで待ちます。
aws s3 cp <S3 URI> . --recursive
- ローカルPCにダウンロードするために、一度フォルダの中身をZIPに固めます
zip -r cloudtrail-dl.zip *
- 右上の「アクション」>「ファイルのダウンロード」を選択し、個別のファイルパスに「~/cloudtrail-dl/cloudtrail-dl.zip」を入力します。
- 最後にダウンロード完了したので、「cloudtrail-dl」フォルダごと削除します。
cd ~
rm -rf cloudtrail-dl
ls
方法その2
CloudShellでCloudTrailのlookup-eventコマンドを使ってcsvファイルに書き込んでいく
- 以下のスクリプトファイルを作成します。
#!/bin/bash
# 処理するリージョンのリストを作成
regions=$(aws ec2 describe-regions --query "Regions[*].RegionName" --output text)
# 各リージョンでループ (配列として処理)
for region in $regions; do
# 初回実行、イベントを取得しリージョンごとのファイルに書き込み
aws cloudtrail lookup-events --region $region --max-items 2000 --output table > "${region}-events.csv"
# NextTokenを取得
NextToken=$(aws cloudtrail lookup-events --region $region --max-items 1 --output json | jq -r '.NextToken // empty')
# ループ回数を初期化
count=0
# NextTokenがある限りループ
while [ -n "$NextToken" ]; do
# 次のページのイベントを取得してリージョンごとのファイルに追記
aws cloudtrail lookup-events --region $region --max-items 2000 --output table --starting-token $NextToken >> "${region}-events.csv"
# 新しいNextTokenを取得
NextToken=$(aws cloudtrail lookup-events --region $region --max-items 1 --starting-token $NextToken --output json | jq -r '.NextToken // empty')
# ループ回数をインクリメント
count=$((count + 1))
echo "リージョン: $region - ループ回数: $count"
done
echo "$region のイベント収集が完了しました。"
done
echo "Complete"
- Cloudshellにてscript.shを実行します。
sh script.sh
-
「Complete」が表示されたら完了となります。
-
あとは、方法1と同様に事後処理をすすめます。
-
ローカルPCにダウンロードするために、一度フォルダの中身をZIPに固めます
zip -r cloudtrail-dl.zip *
- 右上の「アクション」>「ファイルのダウンロード」を選択し、個別のファイルパスに「~/cloudtrail-dl/cloudtrail-dl.zip」を入力します。
- 最後にダウンロード完了したので、「cloudtrail-dl」フォルダごと削除します。
cd ~
rm -rf cloudtrail-dl
ls
- 展開して確認してみると、こんな感じで保存されます。見やすい!
余談:lookup-eventを使った方法で少し苦労した
試しにlookup-eventで出力確認しようと思ったが、出来なかった・・・
失敗コマンド
aws cloudtrail lookup-events --region ap-northeast-1 --output json
エラー内容:
An error occurred (ThrottlingException) when calling the LookupEvents operation (reached max retries: 2): Rate exceeded
CloudTrail における LookupEvents API は一秒間に 2 回のリクエストが可能な API のため、多くの結果を取得する際に lookup-events コマンドを実行すると、繰り返し LookupEvents API が実行され、情報を取得いたします。
その際、一秒間に 2 回を超えることによってスロットリングのエラーが発生しているらしい。
ではどうしたらよいのか?
一度に取得する件数を少なくする以外に回避策はない!
AWS CLI コマンドのオプションとして --max-items および --starting-token パラメータによって、最大取得件数を制限し、複数回に分けて結果を取得することが必要・・・
-
--max-items
指定した数の項目のみを出力するようにできる -
--starting-token
出力される項目数 (--max-items) が、基盤となるAPI呼び出しによって返された項目の合計数よりも少ないNextToken場合、出力には、次のコマンドに渡して次の項目のセットを取得できる が含まれます。次の例は、前の例で返された NextToken 値を使用して、2 番目の 100 項目を取得することができる。
Discussion