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

s3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/Region/yyyy/mm/dd

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

CloudTrail と Athena の詳細については、「Amazon Athena ユーザーガイド」の「パーティション射影を使用した Athena での AWS CloudTrail ログ用のテーブルの作成」を参照してください。

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

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

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

詳細については、AWS re:Post の「お知らせ: Amazon S3 用の AWS CloudTrail は、セキュリティ監査を強化するための新しいフィールドを追加します」を参照してください。

注記

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

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

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

例 — Signature Version 2 のイベントをすべて選択し、EventTimeS3_ActionRequest_ParametersRegionSourceIPUserAgent のみを印刷する

以下の Athena クエリで、s3_cloudtrail_events_db.cloudtrail_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_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_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_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 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://amzn-s3-demo-bucket1/AWSLogs/111122223333/';

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

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

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

SELECT useridentity.arn, Count(requestid) AS RequestCount FROM s3_cloudtrail_events_db.cloudtrail_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_table を Athena の詳細と置き換え、必要に応じてデータ範囲を変更します。

例 — PUT オブジェクトアクセス要求のあるイベントをすべて選択し、EventTimeEventSourceSourceIPUserAgentBucketNameobjectUserARN のみ印刷する
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_table WHERE eventName = 'PutObject' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'
例 — GET オブジェクトアクセス要求のあるイベントをすべて選択し、EventTimeEventSourceSourceIPUserAgentBucketNameobjectUserARN のみ印刷する
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_table WHERE eventName = 'GetObject' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'
例 — 特定の期間にバケットに対して行われた匿名のリクエスタイベントをすべて選択し、EventTimeEventNameEventSourceSourceIPUserAgentBucketNameUserARNAccountID のみ印刷する
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_table WHERE userIdentity.accountId = 'anonymous' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'
例 — 承認に ACL が必要なリクエストをすべて特定する

次の Amazon Athena のクエリの例は、承認のためにアクセスコントロールリスト (ACL) が必要な S3 バケットへのすべてのリクエストを特定する方法を示しています。リクエストに承認用の ACL が必要な場合、additionalEventDataaclRequired の値は Yes です。ACL が不要な場合は、aclRequired は存在しません。この情報を使用して、これらの ACL 権限を適切なバケットポリシーに移行できます。これらのバケットポリシーを作成したら、これらのバケットの ACL を無効にできます。ACL の無効化の詳細については、「ACL を無効にする前提条件。」を参照してください。

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

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

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