S3バケットのアクセスログ出力方法
お疲れ様です。MKです。
S3の静的ウェブサイトホスティングを使用して
Webページを公開しているけど、イマイチどの時間帯のアクセスが多いか?
また、変なアタックは受けてないか?等気になることもあるかと思います。
そんな時には、S3のアクセスログを解析することで
今後のマーケティング等に活用できるかもしれません。
アクセスログの保存設定を行うには、下記の注意点がございます。
- 「デフォルトの暗号化」が無効、もしくは有効でかつ Amazon S3 マスターキーになっている
- 「オブジェクトロック」が無効になっている
- 「アクセスコントロールリスト」で「S3 ログ配信グループ(ACL)」のアクセスを許可している
- 「バケットポリシー」でログ配信を許可している
- S3バケットの「サーバアクセスのログ記録」が有効化になっている
ただ、上記を守れば意外と簡単に設定できますので
早速、S3のアクセスログの設定方法に関してご紹介をさせていただこうと思います。
まずは、アクセスログ保存用のS3バケットを用意
まずは、アクセスログを保存するS3バケットが必要なので
「S3バケットを作成」から作成します。
※この時、下記の設定で作成を行うように注意です。
もちろん、後から編集で変更することも可能です。
- 「デフォルトの暗号化」が無効、もしくは有効でかつ Amazon S3 マスターキーに設定
- 「オブジェクトロック」を無効
現在は、静的ページ公開用のバケットとアクセスログ保存用の2つのバケットがある状態です。
S3 ログ配信グループ(ACL)を許可するポリシーの設定
次に作成したアクセスログ保存用のS3バケットに
「S3 ログ配信グループ(ACL)」を許可するポリシーの設定を行います。
Amazon S3 > バケット > アクセスログ保存用のS3バケット > アクセス許可 > バケットポリシー > 編集
上記操作で、下記のポリシーを追加してあげましょう。
これで、「S3 ログ配信グループ(ACL)」の許可設定と
「バケットポリシー」のログ配信許可設定はOKです。
※因みに、もし既存のバケットポリシーに追加する際、
“Effect”: “Deny”で拒否するポリシーのロギングサービスプリンシパルに
“Service”: “logging.s3.amazonaws.com”がある場合は、併せて削除が必要です。
S3バケットの「サーバアクセスのログ記録」を有効化
最後に静的ページ公開用のS3バケットの「サーバアクセスのログ記録」を有効化にします。
マネジメントコンソールから有効にすることも可能ですが
その場合ですと、バケットポリシーに自動的に追記されてしまうかたちになりますので
今回は、CLIから有効にしてみたいと思います。
まず、json形式にて設定ファイルを作成します。
[root@XXXX-test ~]# vi logging.json
[root@XXXX-test ~]# cat logging.json
{
"LoggingEnabled": {
"TargetBucket": "XXXX-test-s3-access-log",
"TargetPrefix": "XXXX-test/"
}
}
上記にて、作成した設定ファイルを
下記のコマンドで静的ページ公開用のS3バケットにアップロードすれば、設定は完了です。
[root@XXXX-test ~]# aws s3api put-bucket-logging --bucket XXXX-test --bucket-logging-status file://logging.json
[root@XXXX-test ~]# aws s3api get-bucket-logging --bucket XXXX-test
{
"LoggingEnabled": {
"TargetBucket": "XXXX-test-s3-access-log",
"TargetPrefix": "XXXX-test/"
}
}
これでOKです!
実際にコンソールパネルからも「サーバーアクセスのログ記録」が有効になっていることを確認できました。
ここまで設定ができれば、アクセスログ保存用のS3バケットの
オブジェクトの中に、ログファイルが出力されるようになっているはずです。
因みに中身はこんな感じです。
d3a29cf89ca831eaacf894cfbe7cef872f1910230e55cd4f8354e4545180fe11 XXXX-test [19/Feb/2023:15:17:12 +0000] XXX.XXX.XXX.XXX d3a29cf89ca831eaacf894cfbe7cef872f1910230e55cd4f8354e4545180fe11 QJM1FCACTZZND52V REST.GET.POLICY_STATUS - "GET /?policyStatus HTTP/1.1" 200 - 141 - 14 - "-" "S3Console/0.4, aws-internal/3 aws-sdk-java/1.11.1030 Linux/5.10.165-126.735.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.352-b08 java/1.8.0_352 vendor/Oracle_Corporation cfg/retry-mode/standard" - 43nkm43iSOt/1kUaHGo/6vBHGbdKWD0crmk4GTN4xz8qEt9ZFtU83WLH+U7bldr2FWbZpsrSWFA= SigV4 ECDHE-RSA-AES128-GCM-SHA256 AuthHeader XXXX-test.s3.ap-northeast-1.amazonaws.com TLSv1.2 - -
うーん。見辛いですね。。。
このままだと、ほしい情報がなかなか見つかりません。
ということで、Athena を使ってログを見やすく整形してみたいと思います。
Amazon Athena を使ってログを整形
まずは、マネジメントコンソールからAthenaを開き
「クエリエディタ」から下記のクエリを実行して、データベースの作成を行います。
create database s3_access_logs_db
クエリの実行後、画面左側のデータベースの欄にプルダウンにて
「database s3_access_logs_db」というデータベースが追加されているはずです。
次に作成した「database s3_access_logs_db」を
画面左側のデータベースの欄のプルダウンから選択して
下記のクエリを実行し、テーブルスキーマを作成します。
CREATE EXTERNAL TABLE IF NOT EXISTS s3_access_logs_db.mybucket_logs(
BucketOwner STRING,
Bucket STRING,
RequestDateTime STRING,
RemoteIP STRING,
Requester STRING,
RequestID STRING,
Operation STRING,
Key STRING,
RequestURI_operation STRING,
RequestURI_key STRING,
RequestURI_httpProtoversion STRING,
HTTPstatus STRING,
ErrorCode STRING,
BytesSent BIGINT,
ObjectSize BIGINT,
TotalTime STRING,
TurnAroundTime STRING,
Referrer STRING,
UserAgent STRING,
VersionId STRING,
HostId STRING,
SigV STRING,
CipherSuite STRING,
AuthType STRING,
EndPoint STRING,
TLSVersion STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1', 'input.regex' = '([^ ]) ([^ ]) \[(.?)\] ([^ ]) ([^ ]) ([^ ]) ([^ ]) ([^ ]) \\"([^ ]) ([^ ]) (- |[^ ])\\" (-|[0-9]) ([^ ]) ([^ ]) ([^ ]) ([^ ]) ([^ ]) ([^ ]) (\"[^\"]\") ([^ ])(?: ([^ ]) ([^ ]) ([^ ]) ([^ ]) ([^ ]) ([^ ]))?.*$' )
LOCATION 's3://XXXX-test-s3-access-log/' ←※こちらは、自分のS3アクセスログの出力先S3バケットを選択します
これで、画面左側の「テーブルとビュー」のテーブルの欄に
「mybucket_logs」という項目が追加されているはずです。
あとは、「mybucket_logs」の右側にある︙ マークを押して「テーブルをプレビュー」をクリックすると
画面真ん中下の「クエリ結果」の一覧に、S3バケットのアクセスログが見やすく整形して表示されているはずです。
「結果をダウンロード」を押すと.csv形式のファイルをダウンロードすることも可能です。
MySQLの構文を学んで、クエリを自分でアレンジして実行すれば
もっと凝った整形を行うこともできますので、よければ調べてみてください。
最後まで読んでいただき、誠にありがとうございました。
今後ともネットアシストをよろしくお願いいたします!