导读:本期聚焦于过客创作的《如何配置S3桶策略只允许CloudFront访问?AWS CloudFront资源策略详解》,敬请观看详情。S3桶直接暴露公网常常带来数据泄露风险,如何让静态资源只能通过CloudFront分发访问,而拒绝所有其他来源的请求?本文围绕AWS CloudFront的资源策略与S3桶策略配合展开,详细讲解Origin Access Control(OAC)的创建流程、桶策略JSON的编写要点、以及如何利用aws:SourceArn条件精确限制访问来源。内容涵盖常见配置错误排查、SignatureV4签名要求、terraform自动化配置示例,以及在迁移旧版OAI到新版OAC时的注意事项,帮助你搭建安全合规的CDN回源架构。

AWS CloudFront与S3的组合是最经典的静态网站与资源分发方案,但很多人在配置时习惯直接把S3桶设为公开可读,这等于绕过了CloudFront的所有防护能力。正确做法是借助Origin Access Control(OAC)配合S3桶策略,让S3桶彻底关闭公开访问,只接受来自指定CloudFront分配的请求。本文将完整讲解这套机制的原理与落地配置。

如何配置S3桶策略只允许CloudFront访问?AWS CloudFront资源策略详解

一、为什么要用OAC而不是让S3公开

先看问题的本质。当S3桶开放公开读取时,任何人拿到桶的URL就能直接访问对象,CloudFront的缓存优化、地域限制、签名URL、WAF防护统统形同虚设。更危险的是,攻击者可以绕过CDN直连S3源站,消耗源站流量,甚至配合对象列举权限摸清桶内全部文件结构。

OAC(Origin Access Control)是AWS官方推荐的回源鉴权机制,它取代了旧的OAI(Origin Access Identity)。原理是CloudFront在回源时使用一种特殊的服务主体身份访问S3,S3桶策略通过aws:SourceArn条件判断请求是否来自指定的CloudFront分配。这个条件是精确到分配ID级别的,即使别人知道你的桶名,也无法用自己的CloudFront分配来冒充回源。

相比旧版OAI,OAC有几个明显优势:支持S3所有区块加密配置(包括SSE-KMS)、支持动态请求(PUT、POST等,可用于S3 Transfer Acceleration场景)、并且配置后无需修改S3对象的ACL。唯一的限制是OAC要求CloudFront必须使用签名版本SigV4(Signed URL和Signed Cookies场景同样适用),这在配置_distribution时需要注意。

二、控制台配置OAC与桶策略

配置流程分为三步:创建OAC、绑定到CloudFront分配、更新S3桶策略。在CloudFront控制台进入Settings中的Origins页面,选中你的S3源站,点击Edit,将Origin access切换为Origin access control settings,再创建一个新的OAC。关键选项有两个:Origin type选择S3,Sign requests保持Yes(默认就是签名回源)。名字可以随意取,例如my-s3-oac

保存后AWS会自动生成一段桶策略示例,可以直接复制去S3桶的Permissions页面粘贴。这段策略的核心结构如下:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontOACRead",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-example-bucket/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/E1234ABCD5678"
        }
      }
    }
  ]
}

这里有几个字段必须理解到位。Principal写的是cloudfront.amazonaws.com服务主体,而不是某个IAM用户或角色,这是服务级鉴权的写法。Condition里的AWS:SourceArn是整个策略的安全核心,它把授权范围锁死到你的那个具体分配,注意这里的资源名是AWS:SourceArn,在老版本控制台生成的示例中写作aws:SourceArn,两者都有效,AWS策略JSON的条件键大小写不敏感,但建议统一用大写风格保持一致。桶策略只授予s3:GetObject,不做写入和列举授权,符合最小权限原则。

另外别忘了在S3桶的Block Public Access设置中保持全部启用(BlockPublicAcls、IgnorePublicAcls、BlockPublicPolicy、RestrictPublicBuckets四项全开),并确认没有任何Bucket Policy语句允许公开访问。配置完成后,通过S3的直连URL访问应该返回403,而通过CloudFront域名访问则正常返回内容,可以用curl快速验证。

三、用Terraform自动化完整配置

生产环境中手动点控制台不可维护,下面给出一段可直接使用的Terraform配置,涵盖OAC、分发和桶策略三个资源。假设S3桶已通过aws_s3_bucket资源创建:

resource "aws_cloudfront_origin_access_control" "oac" {
  name                              = "my-s3-oac"
  description                       = "OAC for static site bucket"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

resource "aws_cloudfront_distribution" "cdn" {
  origin {
    domain_name              = aws_s3_bucket.site.bucket_regional_domain_name
    origin_id               = "s3-site-origin"
    origin_access_control_id = aws_cloudfront_origin_access_control.oac.id
  }

  enabled         = true
  comment         = "static site cdn"
  default_root_object = "index.html"

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "s3-site-origin"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false
      cookies { forward = "none" }
    }
  }

  restrictions {
    geo_restriction { restriction_type = "none" }
  }

  viewer_certificate { cloudfront_default_certificate = true }
}

resource "aws_s3_bucket_policy" "site" {
  bucket = aws_s3_bucket.site.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "AllowCloudFrontOACRead"
      Effect    = "Allow"
      Principal = { Service = "cloudfront.amazonaws.com" }
      Action    = "s3:GetObject"
      Resource  = "${aws_s3_bucket.site.arn}/*"
      Condition = {
        StringEquals = {
          "AWS:SourceArn" = aws_cloudfront_distribution.cdn.arn
        }
      }
    }]
  })
}

注意Terraform中存在一个经典鸡生蛋问题:桶策略引用分发ARN,而分发又引用桶作为源。上面的写法之所以能工作,是因为aws_s3_bucket_policyaws_cloudfront_distribution之后创建,Terraform会自动推导依赖顺序,无需显式depends_on。但如果你的桶策略还要引用别的高依赖资源,建议显式声明依赖避免循环。

还有一个容易踩的坑:源站地址必须使用bucket_regional_domain_name而不是桶名本身。CloudFront在启用OAC后不能选REST endpoint的遗留模式,同时注意别把这个桶同时配置成网站托管endpoint(形如bucket.s3-website-us-east-1.amazonaws.com),网站endpoint不支持OAC签名鉴权,会导致回源全部403。

四、从OAI迁移到OAC的注意事项

如果你的架构还在用旧版OAI,迁移时要按顺序操作:先在CloudFront创建OAC,然后把源站的Origin access从OAI切换到OAC,等待分发部署完成,最后再更新桶策略并移除旧的OAI授权语句。顺序不能乱,先删桶策略里的OAI授权会导致服务中断。

迁移后建议做一轮回归验证,重点检查三点:一是KMS加密的桶是否在OAC中正确处理(需要在KMS密钥策略中额外授权cloudfront服务主体使用密钥);二是是否有Lambda@Edge或CloudFront Functions在回源路径上改写了URI导致404;三是SigV4签名要求是否影响了你的自定义源配置。验证通过后再清理OAI资源,完成整个切换。

总结一下,S3桶策略限制仅CloudFront访问的核心就三件事:桶彻底关闭公开访问、OAC开启签名回源、桶策略用AWS:SourceArn精确锁定分配。把这套配置固化到Terraform中,既能保证安全基线,又便于后续多环境复制。

AWS CloudFrontS3桶策略Origin Access Control修改时间:2026-09-05 20:38:51

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260905/51130.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。