S3サーバーアクセスログから、アクセス失敗ログを確認する

外部のユーザーがS3に接続する時に何らかの原因でアクセスに失敗することがあります。ユーザーに詳しい状況をヒアリングできないケースで、サーバーアクセスログを解析することで原因がわかることがあります。アクセスログの有効化とAmazon Athenaでの確認方法を紹介します。
2019.08.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

S3に接続する時に何らかの原因でアクセスに失敗することがあります。詳しい状況を確認できればいいのですが、エンドユーザーがS3に接続するようなケースではヒアリングが難しいこともあります。そのような場合、サーバーアクセスログを解析し原因を確認できます。アクセスログの有効化とAmazon Athenaでの確認方法を紹介します。

S3サーバーアクセスログの有効化

S3サーバーログはS3コンソールから有効にできます。プロパティからログを出力するバケットとプレフィックスを指定します。プレフィックスを指定しないと、バケット直下にログが出ます。S3バケットごとにログ出力用のバケットを作るか、ログ用バケットにプレフィックスを作ると良いです。異なるバケットのログが同じ場所に出力されないようにしましょう。もちろん意図があって同じ場所に出力するのは問題ありません。

Athenaでのログの確認

データベースの作成

Amazon Athenaでログを確認します。Athenaコンソールでデータベースを作成します。

create database s3_access_logs_db

テーブルの作成

作成したデータベースに切り替えます。

テーブルを作成します。 s3://awsexamplebucket-logs/prefixは環境に合わせて変更します。プレフィックスがない場合は、s3://awsexamplebucket-logs/の形式で指定します。

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://awsexamplebucket-logs/prefix'

ステータスが200以外かつAWSサービスからのアクセス以外を確認する

HTTPステータスが200以外かつ、AWS ConfigやTrusted AdvisorなどAWSサービスからのリクエストを除外するクエリを実行します。

SELECT * 
FROM s3_access_logs_db.mybucket_logs
where httpstatus != '200' 
AND useragent != '"AWSConfig"' 
AND useragent NOT Like '%aws-internal%'
ORDER BY requestdatetime DESC

ログの確認

実際のログは以下のように確認できます。モザイクが多くて恐縮ですが、一列目にバケット名。2列目に時間。3列目にIPアドレス、4列目にはIAMロールやIAMユーザー名が記載されています。Bucket PokicyでIPアドレス制限を行なっている場合は、許可しているIPアドレスからの接続か確認します。また、IAMユーザーやIAMロールに該当のS3にアクセスする権限が設定されているか確認します。

オペレーションやリクエストキーも確認できます。赤枠を見ると、aa.txtをGETし、AcessDeniedになったことがわかります。

ユーザーエージェントも確認できます。特定のユーザーエージェントだけ失敗しているなど確認できるかもしれません。

さいごに

S3のサーバーアクセスログを解析することで、アクセス失敗の原因を確認する方法をご紹介しました。ログから接続元のIPアドレスやリクエスター(IAMユーザーなど)、パスや操作などを確認したら、S3バケットポリシーやIAMポリシーに問題がないか確認しましょう。具体的には、バケットポリシーで許可していないIPアドレスから接続していないかやIAMポリシーに不足があるかなど確認します。本記事がS3アクセスのトラブルシューティングの一助になれば幸いです。

参考