使用AWS SAM/CloudFormation创建公共S3存储桶遇权限问题求助
解决方案:AWS SAM配置CloudFront托管的公共S3存储桶
一、修复BucketPolicy 403错误并替换弃用的AccessControl
添加公开BucketPolicy时出现403错误,核心原因是AWS默认开启了S3块公共访问(Block Public Access),阻止创建允许公共访问的策略。以下是替换弃用配置并解决403的完整模板:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: public-bucket-for-cloudfront Parameters: BucketName: Description: S3 bucket name Type: String Default: 'my-test-public-bucket-abc123' Resources: PublicBucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName WebsiteConfiguration: IndexDocument: index.html ErrorDocument: index.html CorsConfiguration: CorsRules: - AllowedOrigins: - "*" AllowedMethods: - GET - HEAD AllowedHeaders: - "*" MaxAge: 3000 OwnershipControls: Rules: - ObjectOwnership: BucketOwnerPreferred # 关闭块公共访问限制,允许创建公开策略 PublicAccessBlockConfiguration: BlockPublicAcls: false BlockPublicPolicy: false IgnorePublicAcls: false RestrictPublicBuckets: false PublicBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref PublicBucket PolicyDocument: Version: "2012-10-17" Statement: - Sid: PublicReadGetObject Effect: Allow Principal: "*" Action: "s3:GetObject" Resource: !Sub "arn:aws:s3:::${BucketName}/*"
关键调整点:
- 移除了弃用的
AccessControl: PublicRead - 添加
PublicAccessBlockConfiguration,关闭所有阻止公共访问的选项,确保BucketPolicy能正常创建 - 精简CORS规则:静态网站通常仅需
GET/HEAD方法,移除不必要的POST/PUT/DELETE以降低安全风险
二、CloudFront托管的最佳实践(推荐)
直接公开S3桶存在安全隐患,推荐使用CloudFront Origin Access Identity(OAI),让CloudFront成为唯一能访问桶的实体,桶无需公开给所有人。这种方案既符合AWS安全规范,又能利用CloudFront的缓存、HTTPS、WAF等功能:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: cloudfront-s3-static-website Parameters: BucketName: Description: S3 bucket name Type: String Default: 'my-test-cloudfront-bucket-abc123' DomainName: Description: Optional custom domain for CloudFront Type: String Default: "" Resources: # S3存储桶(完全私有,仅允许CloudFront访问) StaticWebsiteBucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName WebsiteConfiguration: IndexDocument: index.html ErrorDocument: index.html OwnershipControls: Rules: - ObjectOwnership: BucketOwnerPreferred # 启用完整块公共访问,确保桶不被直接公开 PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true # CloudFront Origin Access Identity CloudFrontOAI: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Properties: CloudFrontOriginAccessIdentityConfig: Comment: OAI for static website bucket # 授权CloudFront OAI访问桶的策略 BucketPolicyForCloudFront: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref StaticWebsiteBucket PolicyDocument: Version: "2012-10-17" Statement: - Sid: AllowCloudFrontAccess Effect: Allow Principal: AWS: !Sub "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOAI}" Action: "s3:GetObject" Resource: !Sub "arn:aws:s3:::${BucketName}/*" # CloudFront分发配置 CloudFrontDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Enabled: true DefaultRootObject: index.html Origins: - DomainName: !GetAtt StaticWebsiteBucket.RegionalDomainName Id: S3Origin S3OriginConfig: OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CloudFrontOAI}" DefaultCacheBehavior: TargetOriginId: S3Origin ViewerProtocolPolicy: redirect-to-https AllowedMethods: - GET - HEAD - OPTIONS CachedMethods: - GET - HEAD ForwardedValues: QueryString: false Cookies: Forward: none # 若使用自定义域名,取消注释并配置ACM证书 # Aliases: # - !Ref DomainName # ViewerCertificate: # AcmCertificateArn: !Ref CloudFrontCertificate # SslSupportMethod: sni-only # MinimumProtocolVersion: TLSv1.2_2021
核心优势:
- 桶保持完全私有,避免直接公开带来的安全风险
- 强制HTTPS访问,提升网站安全性
- 利用CloudFront全球边缘节点加速内容分发
- 无需调整块公共访问设置,从根源避免403错误
常见问题说明
为什么之前添加BucketPolicy会报403?
AWS默认开启账号级别的S3块公共访问,阻止创建允许公共访问的策略。第一种方案通过显式关闭限制解决此问题,第二种方案使用OAI无需关闭限制。什么时候用第一种方案?
仅当你需要用户直接访问S3桶域名时才使用,否则优先选择CloudFront OAI方案。
内容的提问来源于stack exchange,提问作者hazmat
相关产品推荐
相关产品推荐

