启用 Amazon S3 服务器访问日志记录
服务器访问日志记录详细地记录对 Amazon S3 存储桶提出的各种请求。对于许多应用程序而言,服务器访问日志很有用。例如,访问日志信息可能在安全和访问权限审核方面很有用。它还可以帮助您了解您的客户群并了解您的 Amazon S3 账单。
默认情况下,Amazon S3 不会收集服务器访问日志。在您启用日志记录后,Amazon S3 会将源存储桶的访问日志传输到您选择的目标存储桶。目标存储桶必须位于与源存储桶所在的相同 Amazon Web Services 区域和 Amazon Web Services 账户中,并且不得具有原定设置的保留周期配置。
访问日志记录包含有关对存储桶做出的请求的详细信息。这些信息可能包括请求类型、请求中指定的资源以及处理请求的时间和日期。有关日志记录基本知识的更多信息,请参阅 使用服务器访问日志记录来记录请求。
-
在 Amazon S3 存储桶上启用服务器访问日志记录不收取额外费用。但是,系统提交给您的任何日志文件都会产生普通存储费用。(您可以随时删除日志文件。) 我们不会计算提交日志文件的数据传输费,但会按正常数据传输费率对访问日志文件收费。
-
您的目标存储桶不应启用服务器访问日志记录。您可以让日志传输至您拥有的且与源存储桶位于同一区域中的任何存储桶,包括源存储桶本身。但是,这将导致日志无限循环,不推荐使用。为了更方便地管理日志,我们建议您将访问日志保存在不同的存储桶中。有关更多信息,请参阅如何启用日志传送?
您可以使用 Amazon S3 控制台、Amazon S3 API、Amazon Command Line Interface (Amazon CLI) 或 Amazon 软件开发工具包启用或禁用服务器访问日志记录。
启用服务器访问日志记录之前,请考虑以下事项:
-
您可以使用存储桶策略或存储桶访问控制列表 (ACL) 来授予日志传输权限。但是,我们建议您使用存储桶策略。如果目标存储桶使用存储桶拥有者强制执行的对象所有权设置,ACL 将被禁用,并且不再影响权限。您必须使用存储桶策略向日志服务主体授予访问权限。有关更多信息,请参阅日志传输的权限。
-
向存储桶策略添加拒绝条件可能会阻止 Amazon S3 提供访问日志。
-
仅当使用 AES256 (SSE-S3) 时,您才能在目标存储桶上使用原定设置的存储桶加密。不支持带有 Amazon KMS 密钥 (SSE-KMS) 的原定设置加密。
-
您无法在目标存储桶上启用 S3 对象锁定。
日志传输的权限
Amazon S3 使用特殊的日志传输账户写入服务器访问日志。这些写入受常规的访问控制限制。我们建议您更新目标存储桶上的存储桶策略,以授予对日志记录服务主体 (logging.s3.amazonaws.com
) 的访问权限用于访问日志传送。
要使用存储桶策略对目标存储桶授予访问权限,需要更新存储桶策略以允许日志服务主体访问 s3:PutObject
。如果您使用 Amazon S3 控制台启用服务器访问日志录入,则控制台会自动更新目标存储桶上的存储桶策略,以便将这些权限授予日志录入服务主体。如果以编程方式启用服务器访问日志记录,则可以手动更新目标存储桶的存储桶策略以授予对日志记录服务主体的访问权限。
您也可以使用存储桶 ACL 授予访问日志传输的访问权限。您可以在存储桶 ACL 中添加一个授予条目,以授予对 S3 日志传输组的 WRITE
和 READ_ACP
权限。不建议使用存储桶 ACL 授予对 S3 日志传输组的访问权限。
存储桶拥有者强制设置 S3 对象所有权
如果目标存储桶使用存储桶拥有者强制执行的对象所有权设置,ACL 将被禁用,并且不再影响权限。您必须更新目标存储桶上的存储桶策略,以授予对日志服务主体的访问权。您无法更新存储桶 ACL 以授予对 S3 日志传输组的访问权限。您也不能将目标授予包含在 PutBucketLogging 配置中。有关将现有存储桶 ACL 以便将访问日志传输迁移到存储桶策略的信息,请参阅 为服务器访问日志记录授予 S3 日志交付组的访问权。有关强制实施对象所有权的更多信息,请参阅 为您的存储桶控制对象所有权和禁用 ACL。。
使用存储桶策略向日志服务主体授予权限
此示例存储桶策略向日志服务主体 (logging.s3.amazonaws.com
) 授予 s3:PutObject
权限。要使用此存储桶策略,请替换示例值。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "S3ServerAccessLogsPolicy", "Effect": "Allow", "Principal": { "Service": "logging.s3.amazonaws.com" }, "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::
DOC-EXAMPLE-BUCKET
/EXAMPLE-LOGGING-PREFIX
*", "Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:s3:::SOURCE-BUCKET-NAME
" }, "StringEquals": { "aws:SourceAccount": "SOURCE-ACCOUNT-ID
" } } } ] }
使用存储桶 ACL 向日志交付组授予权限
虽然我们不建议使用此方法,但您可以使用存储桶 ACL 向日志交付组授予权限。但是,如果目标存储桶使用存储桶拥有者强制执行的 Object Ownership 设置,则无法设置存储桶或对象 ACL。您也不能将目标授予包含在 PutBucketLogging 配置中。您必须使用存储桶策略向日志服务主体 (logging.s3.amazonaws.com
) 授予访问权限。有关更多信息,请参阅日志传输的权限。
在存储桶 ACL 中,日志交付组通过以下 URL 表示。
http://acs.amazonaws.com/groups/s3/LogDelivery
要授予 WRITE
和 READ_ACP
(ACL 读取)权限,请将以下授权添加到目标存储桶 ACL。
<Grant> <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group"> <URI>http://acs.amazonaws.com/groups/s3/LogDelivery</URI> </Grantee> <Permission>WRITE</Permission> </Grant> <Grant> <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group"> <URI>http://acs.amazonaws.com/groups/s3/LogDelivery</URI> </Grantee> <Permission>READ_ACP</Permission> </Grant>
有关以编程方式添加 ACL 授权的示例,请参阅 配置 ACL。
当您使用存储桶中的 Amazon CloudFormation 启用 Amazon S3 服务器访问录入,并使用 ACL 授予对 S3 日志传输组的访问权限时,您还必须在存储桶中的属性字段中添加 AccessControl": "LogDeliveryWrite"
。这一点非常重要,因为您只能通过为存储桶创建 ACL 授予这些权限,但无法在 CloudFormation 中为存储桶创建自定义 ACL。您只能使用标准 ACL。
要启用服务器访问日志记录
使用以下示例以通过 Amazon Web Services Management Console、Amazon CLI、REST API 和 Amazon SDK for .NET 启用服务器访问日志记录。
登录到 Amazon Web Services Management Console,然后通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/
。 -
在 Buckets (存储桶) 列表中,请选择要为其启用服务器访问日志记录的存储桶的名称。
-
选择 Properties (属性)。
-
在 Server access logging (服务器访问日志记录) 部分中,请选择 Edit (编辑)。
-
在 Server access logging (服务器访问日志记录) 下,选择 Enable (启用)。
-
对于 Target bucket (目标存储桶),请输入您想要接收日志记录对象的存储桶的名称。
目标存储桶必须位于源存储桶所在的相同区域中且不得具有默认保留周期配置。
-
选择保存更改。
当您在存储桶上启用服务器访问日志记录时,控制台会在支持在源存储桶上进行日志记录的同时更新目标存储桶的存储桶策略,以便向日志服务主体 (
logging.s3.amazonaws.com
) 授予s3:PutObject
权限。有关存储桶策略的更多信息,请参阅 使用存储桶策略向日志服务主体授予权限。您可以查看目标存储桶中的日志。启用服务器访问日志记录后,可能需要数小时,日志才会传输到目标存储桶。有关如何以及何时传送日志的更多信息,请参阅 如何传输日志?。
有关更多信息,请参阅查看 S3 存储桶的属性。
要启用日志记录,请提交 PUT Bucket 日志记录请求,以在源存储桶上添加日志记录配置。该请求指定目标存储桶,以及要用于所有日志对象键的前缀 (可选)。
以下示例将 LOGBUCKET
标识为目标存储桶,将 logs/
标识为前缀。
<BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01"> <LoggingEnabled> <TargetBucket>LOGBUCKET</TargetBucket> <TargetPrefix>logs/</TargetPrefix> </LoggingEnabled> </BucketLoggingStatus>
日志对象由 S3 日志传递账户编写并拥有,存储桶拥有者对日志对象授予完全权限。您还可以选择向其他用户授予目标权限,以便他们可以访问日志。有关更多信息,请参阅 PUT Bucket 日志记录。
如果目标存储桶使用存储桶拥有者强制执行的 Object Ownership 设置,则不能使用目标授权向其他用户授予权限。要向其他人授予权限,您可以使用更新目标存储桶上的存储桶策略。有关更多信息,请参阅日志传输的权限。
Amazon S3 还提供 GET Bucket 日志记录 API,用于检索存储桶上的日志记录配置。要删除日志记录配置,请发送 BucketLoggingStatus
为空的 PUT Bucket 日志记录请求。
<BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01"> </BucketLoggingStatus>
您可以使用 Amazon S3 API 或 Amazon 软件开发工具包包装程序库在存储桶上启用日志记录。
using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class ServerAccesLoggingTest { private const string bucketName = "*** bucket name for which to enable logging ***"; private const string targetBucketName = "*** bucket name where you want access logs stored ***"; private const string logObjectKeyPrefix = "Logs"; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 client; public static void Main() { client = new AmazonS3Client(bucketRegion); EnableLoggingAsync().Wait(); } private static async Task EnableLoggingAsync() { try { // Step 1 - Grant Log Delivery group permission to write log to the target bucket. await GrantPermissionsToWriteLogsAsync(); // Step 2 - Enable logging on the source bucket. await EnableDisableLoggingAsync(); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); } } private static async Task GrantPermissionsToWriteLogsAsync() { var bucketACL = new S3AccessControlList(); var aclResponse = client.GetACL(new GetACLRequest { BucketName = targetBucketName }); bucketACL = aclResponse.AccessControlList; bucketACL.AddGrant(new S3Grantee { URI = "http://acs.amazonaws.com/groups/s3/LogDelivery" }, S3Permission.WRITE); bucketACL.AddGrant(new S3Grantee { URI = "http://acs.amazonaws.com/groups/s3/LogDelivery" }, S3Permission.READ_ACP); var setACLRequest = new PutACLRequest { AccessControlList = bucketACL, BucketName = targetBucketName }; await client.PutACLAsync(setACLRequest); } private static async Task EnableDisableLoggingAsync() { var loggingConfig = new S3BucketLoggingConfig { TargetBucketName = targetBucketName, TargetPrefix = logObjectKeyPrefix }; // Send request. var putBucketLoggingRequest = new PutBucketLoggingRequest { BucketName = bucketName, LoggingConfig = loggingConfig }; await client.PutBucketLoggingAsync(putBucketLoggingRequest); } } }
我们建议您在其中放置 S3 存储桶的每个 Amazon Web Services 区域 中都创建一个专用日志记录存储桶。然后,将 Amazon S3 访问日志传输到该 S3 存储桶。有关更多信息和示例,请参阅 Amazon CLI 参考中的 put-bucket-logging
如果目标存储桶使用存储桶拥有者强制执行的对象所有权设置,则无法设置存储桶或对象 ACL。您也不能将目标授予包含在 PutBucketLogging 配置中。您必须使用存储桶策略向日志服务主体 (logging.s3.amazonaws.com
) 授予访问权限。有关更多信息,请参阅日志传输的权限。
例 — 为跨两个区域的五个存储桶启用访问日志
在本示例中,您有以下 5 个存储桶:
-
1-awsexamplebucket1-us-east-1
-
2-awsexamplebucket1-us-east-1
-
3-awsexamplebucket1-us-east-1
-
1-awsexamplebucket1-us-west-2
-
2-awsexamplebucket1-us-west-2
-
在以下区域中创建两个日志记录存储桶:
-
awsexamplebucket1-logs-us-east-1
-
awsexamplebucket1-logs-us-west-2
-
-
然后按如下方式启用 Amazon S3 访问日志:
-
1-awsexamplebucket1-us-east-1
记录到带有前缀awsexamplebucket1-logs-us-east-1
的 S3 存储桶1-awsexamplebucket1-us-east-1
-
2-awsexamplebucket1-us-east-1
记录到带有前缀awsexamplebucket1-logs-us-east-1
的 S3 存储桶2-awsexamplebucket1-us-east-1
-
3-awsexamplebucket1-us-east-1
记录到带有前缀awsexamplebucket1-logs-us-east-1
的 S3 存储桶3-awsexamplebucket1-us-east-1
-
1-awsexamplebucket1-us-west-2
记录到带有前缀awsexamplebucket1-logs-us-west-2
的 S3 存储桶1-awsexamplebucket1-us-west-2
-
2-awsexamplebucket1-us-west-2
记录到带有前缀awsexamplebucket1-logs-us-west-2
的 S3 存储桶2-awsexamplebucket1-us-west-2
-
-
使用存储桶 ACL 或存储桶策略授予服务器访问日志传输的权限:
-
更新存储桶策略(推荐)— 要向日志记录服务主体授予权限,请使用
put-bucket-policy
:aws s3api put-bucket-policy --bucket awsexamplebucket1-logs --policy file://policy.json
Policy.json
是当前文件夹中包含存储桶策略的 JSON 文档。要使用此存储桶策略,请替换示例值。{ "Version": "2012-10-17", "Statement": [ { "Sid": "S3ServerAccessLogsPolicy", "Effect": "Allow", "Principal": { "Service": "logging.s3.amazonaws.com" }, "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::awsexamplebucket1-logs/*", "Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:s3:::
SOURCE-BUCKET-NAME
" }, "StringEquals": { "aws:SourceAccount": "SOURCE-ACCOUNT-ID
" } } } ] } -
Update the bucket ACL(更新桶 ACL)–要授予对 S3 日志传输组的权限,请使用
put-bucket-acl
。aws s3api put-bucket-acl --bucket awsexamplebucket1-logs --grant-write URI=http://acs.amazonaws.com/groups/s3/LogDelivery --grant-read-acp URI=http://acs.amazonaws.com/groups/s3/LogDelivery
-
-
然后,应用日志记录策略。
aws s3api put-bucket-logging --bucket awsexamplebucket1 --bucket-logging-status file://logging.json
Logging.json
是当前文件夹中包含日志记录配置的 JSON 文档。如果存储桶使用 Object Ownership 的存储桶拥有者强制设置,则您的日志记录配置不能包含目标授权。有关更多信息,请参阅日志传输的权限。例 –
Logging.json
没有目标授予以下示例
Logging.json
文件不包含目标授权,可以应用于使用存储桶拥有者强制执行的 Object Ownership 设置的存储桶。{ "LoggingEnabled": { "TargetBucket": "awsexamplebucket1-logs", "TargetPrefix": "awsexamplebucket1/" } }
例 –
Logging.json
带有目标授予以下示例
Logging.json
文件包含目标授权。如果目标存储桶使用对象所有权的存储桶拥有者强制设置,则您无法在 PutBucketLogging 配置中包含目标授予。有关更多信息,请参阅日志传输的权限。
{ "LoggingEnabled": { "TargetBucket": "awsexamplebucket1-logs", "TargetPrefix": "awsexamplebucket1/", "TargetGrants": [ { "Grantee": { "Type": "AmazonCustomerByEmail", "EmailAddress": "user@example.com" }, "Permission": "FULL_CONTROL" } ] } }
-
使用 bash 脚本为您账户中的所有存储桶添加访问日志记录。
注意 此脚本仅在您的所有存储桶均位于同一区域中时有用。如果您在多个区域中有存储桶,则必须调整该脚本。
例 — 使用存储桶策略授予访问权限并为账户中的存储桶添加日志记录
loggingBucket='awsexamplebucket1-logs' region='us-west-2' # Create Logging bucket aws s3 mb s3://$loggingBucket --region $region aws s3api put-bucket-policy --bucket $loggingBucket --policy file://policy.json # List buckets in this account buckets="$(aws s3 ls | awk '{print $3}')" # Put bucket logging on each bucket for bucket in $buckets do printf '{ "LoggingEnabled": { "TargetBucket": "%s", "TargetPrefix": "%s/" } }' "$loggingBucket" "$bucket" > logging.json aws s3api put-bucket-logging --bucket $bucket --bucket-logging-status file://logging.json echo "$bucket done" done rm logging.json echo "Complete"
例 — 使用存储桶 ACL 授予访问权限并为账户中的存储桶添加日志记录
loggingBucket='awsexamplebucket1-logs' region='us-west-2' # Create Logging bucket aws s3 mb s3://$loggingBucket --region $region aws s3api put-bucket-acl --bucket $loggingBucket --grant-write URI=http://acs.amazonaws.com/groups/s3/LogDelivery --grant-read-acp URI=http://acs.amazonaws.com/groups/s3/LogDelivery # List buckets in this account buckets="$(aws s3 ls | awk '{print $3}')" # Put bucket logging on each bucket for bucket in $buckets do printf '{ "LoggingEnabled": { "TargetBucket": "%s", "TargetPrefix": "%s/" } }' "$loggingBucket" "$bucket" > logging.json aws s3api put-bucket-logging --bucket $bucket --bucket-logging-status file://logging.json echo "$bucket done" done rm logging.json echo "Complete"