CloudTrail を使用した Amazon S3 リクエストの識別 - Amazon Simple Storage Service

CloudTrail を使用した Amazon S3 リクエストの識別

Amazon S3 では、AWS CloudTrail イベントログを使用してリクエストを識別することができます。AWS CloudTrail は、Amazon S3 リクエストを識別する上で推奨される方法ですが、Amazon S3 サーバーアクセスログを使用している場合は、Amazon S3 アクセスログを使用したリクエストの識別 を参照してください。

CloudTrail ログで Amazon S3 に対して行われたリクエストを特定する

CloudTrail によりログ記録されたイベントは、S3 バケットにある圧縮された GZipped JSON オブジェクトに保存されます。リクエストを効率的に見つけるには、Amazon Athena などのサービスを利用して CloudTrail ログにインデックスを作成し、クエリします。CloudTrail と Athena の詳細については、Amazon Athena ユーザーガイドAWS CloudTrail ログのクエリを参照してください。

CloudTrail ログで Athena を使用する

バケットにイベントを送信するために CloudTrail をセットアップした後、Amazon S3 コンソールで送信先のバケットにオブジェクトが送信されるのを確認できるようになります。これらは次の形式になっています。

s3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/Region/yyyy/mm/dd

例 − Athena を使用して、特定のリクエストの CloudTrail イベントログをクエリする

CloudTrail イベントログを見つけます。

s3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/us-east-2/2019/04/14

CloudTrail イベントログを使用して、Athena データベースとテーブルを作成し、次のようにクエリできるようになります。

  1. https://console.aws.amazon.com/athena/ で Athena コンソールを開きます。

  2. AWS リージョンを CloudTrail 送信先 S3 バケットと同じになるように変更します。

  3. クエリウィンドウで、CloudTrail イベント用の Athena データベースを作成します。

    CREATE DATABASE s3_cloudtrail_events_db
  4. 次のクエリを使用して、バケット内のすべての CloudTrail イベントのためのテーブルを作成します。バケット名を CloudTrail_myawsexamplebucket1 から使用しているバケットの名前に変更します。バケットで使用されている AWS_account_ID CloudTrail も指定します。

    CREATE EXTERNAL TABLE s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table( eventversion STRING, useridentity STRUCT< type:STRING, principalid:STRING, arn:STRING, accountid:STRING, invokedby:STRING, accesskeyid:STRING, userName:STRING, sessioncontext:STRUCT< attributes:STRUCT< mfaauthenticated:STRING, creationdate:STRING>, sessionissuer:STRUCT< type:STRING, principalId:STRING, arn:STRING, accountId:STRING, userName:STRING> > >, eventtime STRING, eventsource STRING, eventname STRING, awsregion STRING, sourceipaddress STRING, useragent STRING, errorcode STRING, errormessage STRING, requestparameters STRING, responseelements STRING, additionaleventdata STRING, requestid STRING, eventid STRING, resources ARRAY<STRUCT< ARN:STRING, accountId:STRING, type:STRING>>, eventtype STRING, apiversion STRING, readonly STRING, recipientaccountid STRING, serviceeventdetails STRING, sharedeventid STRING, vpcendpointid STRING ) ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde' STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/';
  5. Athena をテストして、クエリが機能することを確認します。

    SELECT * FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table WHERE eventsource='s3.amazonaws.com' LIMIT 2;

CloudTrail を使用した Amazon S3 署名バージョン 2 リクエストの識別

CloudTrail イベントログを使用して、Amazon S3 でリクエストに署名するために使用された API 署名バージョンを特定できます。署名バージョン 2 のサポートがオフになる (廃止される) ため、この機能は重要です。その後、Amazon S3 は署名バージョン 2 を使用するリクエストを受け入れず、すべてのリクエストに Signature Version 4 署名を使用する必要があります。

CloudTrail を使用して、署名バージョン 2 の署名を使用しているワークフローがあるかどうかを確認することを強くお勧めします。業務に影響が出ないように、Signature Version 4 を使用してライブラリとコードをアップグレードし、修正します。

詳細については、AWS CloudTrail ディスカッションフォーラムの Announcement: AWS for Amazon S3 adds new fields for enhanced security auditing をご覧ください。

注記

Amazon S3 の CloudTrail イベントには、キー名である「additionalEventData」のリクエスト詳細に署名バージョンが含まれます。Amazon S3 にあるオブジェクトに対する GET、PUT、DELETE などのリクエストで Signature Version を見つけるには、デフォルトでオフにされている CloudTrail データイベントを有効にする必要があります。

Signature Version 2 リクエストを識別する方法として、AWS CloudTrail が推奨されます。Amazon S3 のサーバーアクセスログを使用している場合は、Amazon S3 アクセスログを使用した署名バージョン 2 リクエストの識別 を参照してください。

Amazon S3 署名バージョン 2 リクエストを識別する Athena クエリの例

例 − 署名バージョン 2 のすべてのイベントを選択し、EventTime、S3 アクション、Request_Parameters、Region、SourceIP、UserAgent のみを出力します。

以下の Athena クエリで、<s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table> を Athena の詳細と置き換え、必要に応じて上限を引き上げるか削除します。

SELECT EventTime, EventName as S3_Action, requestParameters as Request_Parameters, awsregion as AWS_Region, sourceipaddress as Source_IP, useragent as User_Agent FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table WHERE eventsource='s3.amazonaws.com' AND json_extract_scalar(additionalEventData, '$.SignatureVersion')='SigV2' LIMIT 10;

例 − 署名バージョン 2 トラフィックを送信しているすべてのリクエスタを選択します。

SELECT useridentity.arn, Count(requestid) as RequestCount FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table WHERE eventsource='s3.amazonaws.com' and json_extract_scalar(additionalEventData, '$.SignatureVersion')='SigV2' Group by useridentity.arn

署名バージョン 2 データのパーティション化

クエリするデータが大量にある場合、パーティション化されたテーブルを作成することにより Athena のコストを削減しランタイムを短縮できます。

それには、次のようなパーティションがある新しいテーブルを作成します。

CREATE EXTERNAL TABLE s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table_partitioned( eventversion STRING, userIdentity STRUCT< type:STRING, principalid:STRING, arn:STRING, accountid:STRING, invokedby:STRING, accesskeyid:STRING, userName:STRING, sessioncontext:STRUCT< attributes:STRUCT< mfaauthenticated:STRING, creationdate:STRING>, sessionIssuer:STRUCT< type:STRING, principalId:STRING, arn:STRING, accountId:STRING, userName:STRING> > >, eventTime STRING, eventSource STRING, eventName STRING, awsRegion STRING, sourceIpAddress STRING, userAgent STRING, errorCode STRING, errorMessage STRING, requestParameters STRING, responseElements STRING, additionalEventData STRING, requestId STRING, eventId STRING, resources ARRAY<STRUCT<ARN:STRING,accountId: STRING,type:STRING>>, eventType STRING, apiVersion STRING, readOnly STRING, recipientAccountId STRING, serviceEventDetails STRING, sharedEventID STRING, vpcEndpointId STRING ) PARTITIONED BY (region string, year string, month string, day string) ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde' STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/';

その後で個々にパーティションを作成します。作成していない日付から結果を取得することはできません。

ALTER TABLE s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table_partitioned ADD PARTITION (region= 'us-east-1', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/us-east-1/2019/02/19/' PARTITION (region= 'us-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/us-west-1/2019/02/19/' PARTITION (region= 'us-west-2', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/us-west-2/2019/02/19/' PARTITION (region= 'ap-southeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/ap-southeast-1/2019/02/19/' PARTITION (region= 'ap-southeast-2', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/ap-southeast-2/2019/02/19/' PARTITION (region= 'ap-northeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/ap-northeast-1/2019/02/19/' PARTITION (region= 'eu-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/eu-west-1/2019/02/19/' PARTITION (region= 'sa-east-1', year= '2019', month= '02', day= '19') LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/sa-east-1/2019/02/19/';

これらのパーティションに基づいてリクエストを実行でき、バケット全体を読み込む必要はありません。

SELECT useridentity.arn, Count(requestid) AS RequestCount FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table_partitioned WHERE eventsource='s3.amazonaws.com' AND json_extract_scalar(additionalEventData, '$.SignatureVersion')='SigV2' AND region='us-east-1' AND year='2019' AND month='02' AND day='19' Group by useridentity.arn

CloudTrail を使用した S3 オブジェクトへのアクセスの識別

AWS CloudTrail イベントログを使用して、GetObjectDeleteObjectPutObject などのデータイベントに対する Amazon S3 オブジェクトアクセスリクエストを識別し、それらのリクエストに関する追加情報を確認できます。

以下の例は、AWS CloudTrail イベントログから Amazon S3 のすべての PUT オブジェクトリクエストを取得する方法を示しています。

Amazon S3 オブジェクトアクセスリクエストを識別する Athena クエリの例

以下の Athena クエリの例で、<s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table> を Athena の詳細と置き換え、必要に応じて上限を引き上げるか削除します。

例 − PUT オブジェクトアクセスリクエストを含むすべてのイベントを選択し、EventTime、EventSource、SourceIP、UserAgent、BucketName、オブジェクト、UserARN のみを出力します。

SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, json_extract_scalar(requestParameters, '$.bucketName') as bucketName, json_extract_scalar(requestParameters, '$.key') as object, userIdentity.arn as userArn FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket_table WHERE eventName = 'PutObject' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'

例 − GET オブジェクトアクセスリクエストを含むすべてのイベントを選択し、EventTime、EventSource、SourceIP、UserAgent、BucketName、オブジェクト、UserARN のみを出力します。

SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, json_extract_scalar(requestParameters, '$.bucketName') as bucketName, json_extract_scalar(requestParameters, '$.key') as object, userIdentity.arn as userArn FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket_table WHERE eventName = 'GetObject' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'

例 – バケットに対する特定の期間内のすべての匿名リクエスタイベントを選択し、EventTime、EventName、EventSource、SourceIP、UserAgent、BucketName、UserARN、および AccountID のみを出力します。

SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, json_extract_scalar(requestParameters, '$.bucketName') as bucketName, userIdentity.arn as userArn, userIdentity.accountId FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket_table WHERE userIdentity.accountId = 'anonymous' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'
注記
  • このクエリの例は、セキュリティのモニタリングにも役立つ場合があります。予期しないまたは不正な IP アドレス/リクエスタからの PutObject または GetObject コールの結果を確認し、バケットへの匿名リクエストを特定できます。

  • このクエリでは、ログ記録が有効になった時間以降の情報のみ取得されます。

Amazon S3 のサーバーアクセスログを使用している場合は、− Amazon S3 アクセスログを使用したオブジェクトアクセスリクエストの識別 を参照してください。