📑

CloudTrailのイベントダウンロードをCloudshellから行いたい

2024/09/13に公開

背景

アプリケーションが稼働するアカウント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ファイルに書き込んでいく

  • 以下のスクリプトファイルを作成します。
script.sh
#!/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 パラメータによって、最大取得件数を制限し、複数回に分けて結果を取得することが必要・・・

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-pagination.html#cli-usage-pagination-maxitems

  • --max-items
    指定した数の項目のみを出力するようにできる

  • --starting-token
    出力される項目数 (--max-items) が、基盤となるAPI呼び出しによって返された項目の合計数よりも少ないNextToken場合、出力には、次のコマンドに渡して次の項目のセットを取得できる が含まれます。次の例は、前の例で返された NextToken 値を使用して、2 番目の 100 項目を取得することができる。

Discussion