Amazon S3 の署名バージョン2(Sig V2)が6月24日以降使えなくなるとのことです。詳細についてはクラスメソッドのブログが詳しく取り上げられています。
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バケットを対象としました。
保存先は任意の 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