使用 CloudTrail 识别 Amazon S3 请求 - Amazon Simple Storage Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 CloudTrail 识别 Amazon S3 请求

在 Amazon S3 中,可以使用 Amazon CloudTrail 事件日志识别请求。Amazon CloudTrail 是识别 Amazon S3 请求的首选方法,但是如果您使用的是 Amazon S3 服务器访问日志,请参阅使用 Amazon S3 服务器访问日志来确定请求

识别 CloudTrail 日志中向 Amazon S3 发出的请求

在设置 CloudTrail 以将事件传输到存储桶后,您应开始看到对象进入您在 Amazon S3 控制台上的目标存储桶。其格式如下所示:

s3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/Region/yyyy/mm/dd

由 CloudTrail 记录的事件作为使用 gzipped 进行压缩的 JSON 对象存储在您的 S3 存储桶中。要高效地查找请求,您应使用 Amazon Athena 等服务来为 CloudTrail 日志建立索引并查询。

有关 CloudTrail 和 Athena 的更多信息,请参阅《Amazon Athena 用户指南》中的使用分区投影在 Athena 中创建 Amazon CloudTrail 日志表

使用 CloudTrail 识别 Amazon S3 签名版本 2 请求

您可以使用 CloudTrail 事件日志来确定已用于在 Amazon S3 中签署请求的 API 签名版本。此功能非常重要,因为对 Signature Version 2 的支持将会关闭(弃用)。之后,Amazon S3 将不再接受使用 Signature Version 2 的请求,并且所有请求必须使用 Signature Version 4 进行签署。

我们强烈建议您使用 CloudTrail 来帮助确定您的任何工作流是否正在使用 Signature Version 2 进行签署。请通过将您的库和代码升级为使用 Signature Version 4 进行纠正,以防对您的业务产生任何影响。

有关更多信息,请参阅 Amazon Web Services re:Post 中的公告:适用于 Amazon S3 的 Amazon CloudTrail 为增强安全性审计添加了新字段

注意

Amazon S3 的 CloudTrail 事件在请求详细信息中的键名称“additionalEventData”之下包含签名版本。要针对为 Amazon S3 中的对象发出的请求(如 GETPUTDELETE 请求)查找签名版本,您必须启用 CloudTrail 数据事件。(默认情况下,此特征处于关闭状态。)

Amazon CloudTrail 是确定签名版本 2 请求的首选方法。如果您使用的是 Amazon S3 服务器访问日志,请参阅使用 Amazon S3 访问日志确定签名版本 2 请求

用于识别 Amazon S3 签名版本 2 请求的 Athena 查询示例

例 — 选择所有签名版本 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://DOC-EXAMPLE-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://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/us-east-1/2019/02/19/' PARTITION (region= 'us-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/us-west-1/2019/02/19/' PARTITION (region= 'us-west-2', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/us-west-2/2019/02/19/' PARTITION (region= 'ap-southeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/ap-southeast-1/2019/02/19/' PARTITION (region= 'ap-southeast-2', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/ap-southeast-2/2019/02/19/' PARTITION (region= 'ap-northeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/ap-northeast-1/2019/02/19/' PARTITION (region= 'eu-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/eu-west-1/2019/02/19/' PARTITION (region= 'sa-east-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-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 对象的访问权限

您可以使用 Amazon CloudTrail 事件日志确定对于诸如 GetObjectDeleteObjectPutObject 等数据事件的 Amazon S3 对象访问请求,并发现有关这些请求的进一步信息。

以下示例说明如何从 Amazon 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 查询示例说明如何识别向 S3 存储桶发出的所有请求,这些请求需要访问控制列表(ACL)进行授权。如果请求需要 ACL 进行授权,则 additionalEventData 中的 aclRequired 值为 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 地址或请求者发出的 PutObjectGetObject 调用的结果,以及确定向存储桶发出的任何匿名请求。

  • 此查询仅从启用了日志记录的时间检索信息。

如果您使用的是 Amazon S3 服务器访问日志,请参阅 使用 Amazon S3 访问日志确定对象访问请求