启用Block Public Access时CloudFront日志写入S3报错的解决问询
解决CloudFront写入日志到启用Block Public Access的S3桶问题
问题重现
尝试用CDK创建S3存储桶存储CloudFront日志,初始配置启用BlockPublicAccess.BLOCK_ALL时,出现错误:
Bucket cannot have public ACLs set with BlockPublicAccess enabled
注释掉该配置后仍报错;参考修改为BlockPublicAccess.BLOCK_ACLS后,又出现新错误:
Invalid request provided: The S3 bucket that you specified for CloudFront logs does not enable ACL access
错误原因
- 第一个错误:CloudFront默认会为日志对象添加公共ACL,但
BLOCK_ALL会完全阻止所有公共访问设置(包括公共ACL),两者冲突。 - 第二个错误:
BLOCK_ACLS会禁用所有ACL的生效与修改,而CloudFront日志写入默认依赖ACL授予权限,因此触发"未启用ACL访问"的报错。
正确配置方案
要在完全启用Block Public Access的前提下让CloudFront写入日志,需采用桶策略替代ACL,并启用S3的「桶所有者强制」模式(忽略ACL,权限由桶策略全权控制)。
修正后的完整代码:
const bk = new s3.Bucket(this, `cm-st-cloudfront-bk`, { bucketName: s3_name, removalPolicy: RemovalPolicy.DESTROY, autoDeleteObjects: true, blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // 保持完全阻止公共访问 encryption: s3.BucketEncryption.S3_MANAGED, versioned: true, objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_ENFORCED, // 关键:启用桶所有者强制,忽略ACL }); // 添加桶策略,授权CloudFront日志服务写入 bk.addToResourcePolicy(new iam.PolicyStatement({ actions: ['s3:PutObject'], effect: iam.Effect.ALLOW, resources: [bk.arnForObjects('cloudfront/*')], // 限定日志前缀,提升安全性 principals: [new iam.ServicePrincipal('delivery.logs.amazonaws.com')], conditions: { StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' // 确保上传对象归桶所有者所有 } } })); const oai = new cloudfront.OriginAccessIdentity(this, `my-oai`,{ comment:`Access identity for ${targetEnv}` }); const cf = new cloudfront.CloudFrontWebDistribution(this, `Website-${targetEnv}-Distribution`, { comment:`CF for resource S3 ${targetEnv}`, viewerCertificate: { aliases: [], props: { cloudFrontDefaultCertificate: true, }, }, errorConfigurations: [ { errorCode: 403, responsePagePath: "/index.html", responseCode: 200, errorCachingMinTtl: 0, }, { errorCode: 404, responsePagePath: "/index.html", responseCode: 200, errorCachingMinTtl: 0, }, ], loggingConfig: { bucket: bk, prefix: "cloudfront/", }, });
关键说明
- 桶所有者强制模式:启用后S3会忽略所有ACL,桶及对象的所有权归桶所有者,彻底避免ACL带来的权限混乱。
- Block Public Access保持BLOCK_ALL:确保桶不会被配置为公共访问,符合安全最佳实践。
- 桶策略限定范围:通过
cloudfront/*前缀限制写入范围,仅允许CloudFront日志服务写入指定路径,提升权限粒度。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

