本日も乙

ただの自己満足な備忘録。

Athena で S3 署名バージョン2の利用状況レポートを作成する

Amazon S3 の署名バージョン2(Sig V2)が6月24日以降使えなくなるとのことです。詳細についてはクラスメソッドのブログが詳しく取り上げられています。

docs.aws.amazon.com

AWS SDK や AWS CLI を定期的にバージョンアップしている人にとっては対応不要だと思いますが、大抵はバージョンが古いままになっているのではないでしょうか(私もそのうちの一人です)。
署名バージョン4(Sig V4)対応するには、AWS SDK や AWS CLI のバージョンアップやソースコードの変更をする必要がありますが、使われている箇所をすべて洗い出すだけでもかなり大変ですし、抜けがあるとも限りません。

Sig V2 の利用状況について CloudWatch Events と CloudWatch Logs Insights を使った方法についてクラスメソッドブログで記事があがっていました。

dev.classmethod.jp dev.classmethod.jp

これを利用できれば万々歳なのですが、私が携わっているシステムはそこそこ大きいので、CloudTrail のデータイベントログ量が膨大になります。CloudWatch Events だと膨大な通知量になってしまいますし、CloudWatch Logs に格納するだけでも料金が高いので、そのまま採用するのが難しいと判断しました。

そこで、もう少しコストをおさえたやり方として、S3 に保存して Athena で検索することにしました。それぞれのサービスにおける料金は以下の通りになっており(いずれも東京リージョン)、S3 + Athena だと安くおさえることができます。

  • CloudWatch Logs(保存): 0.033 USD/GB
  • CloudWatch Logs Insights: スキャンされたデータ 1 GB あたり 0.0076 USD => 1TB あたり 7.6 USD
  • S3(Standard, 従量考慮なし):0.025 USD/GB
  • Athena:スキャンされたデータ 1 TB あたり 5.00 USD

本記事では、CloudTrail のデータイベントログを Athena で検索することで、S3 の Sig V2 の利用状況を可視化できるようにする方法を紹介します。

CloudTrail

CloudTrail で S3 のデータイベントを収集する証跡情報を作成します。収集する S3 バケットは各自の状況に応じて適切に設定してください。今回はすべてのS3バケットを対象としました。

cloudtrail-s3-data-event

保存先は任意の S3 バケットにしてください。今回は s3-data-event-sample としました。

Athena

以下のようなテーブル定義にします。データ量が多い場合は以下のようにリージョンや年月を区切ると良いかと思います。

CREATE EXTERNAL TABLE IF NOT EXISTS cloudtrail_data_events_ap_northeast_1_201903 (
  Records ARRAY<
    STRUCT<
      userIdentity: STRUCT<
          type: STRING,
          arn: STRING
      >,
      eventTime: STRING,
      eventSource: STRING,
      eventName: STRING,
      awsRegion: STRING,
      sourceIpAddress: STRING,
      userAgent: STRING,
      additionalEventData: STRUCT<
        SignatureVersion: STRING
      >
    >
  >
)
ROW FORMAT SERDE
  'org.openx.data.jsonserde.JsonSerDe'
LOCATION
  's3://s3-data-event-sample/AWSLogs/<AWS アカウントID>/CloudTrail/ap-northeast-1/2019/03'
;

テーブルを作成したら以下のようなクエリを実行すると、Sig V2のみのログを抽出することができます。今回はサンプル用として LIMIT 10 をつけています。

SELECT
  record.eventTime,
  record.eventSource,
  record.eventName,
  record.awsRegion,
  record.sourceIPAddress,
  record.userIdentity.type,
  record.userIdentity.arn,
  record.additionalEventData.SignatureVersion
FROM "<データベース名>"."cloudtrail_data_events_ap_northeast_1_201903"
CROSS JOIN UNNEST(records) AS t(record)
WHERE  record.additionalEventData.SignatureVersion = 'SigV2'
LIMIT 10

s3-sigv2-athena

参考文献