如何隐藏由CloudFront分发的AWS S3存储桶网站公开端点?
背景
已完成操作:
- 创建启用静态网页托管的AWS S3存储桶
- 通过AWS CodePipeline与GitHub流水线将大部分文件上传至存储桶
- 权限设置:
- 仅取消最下方的公共访问勾选(允许公共访问)
- 桶策略:允许存储桶公共只读访问,以及CloudFront只读访问
- 注册并绑定域名
- 从ACM获取SSL证书,配置相关CNAME记录
- 创建CloudFront分发,源设置为S3网站端点,关联托管区域内带CNAME记录的域名/ACM证书
问题
S3存储桶网站端点仍可公开访问(且未加密)。希望仅允许注册域名(必要时可保留CloudFront URL)访问,禁止浏览器直接访问S3存储桶网站端点。
已尝试方案:
- 限制桶策略仅允许CloudFront访问
- 创建OAC(Origin Access Control)但使用S3端点时,源设置无该选项
- 重新创建分发尝试使用OAC,但无法将S3端点加入ACM证书用于路由/CNAME配置(明知可能无效仍尝试)
当前状态:
- 暂时陷入困境
解决方案
核心思路:通过桶策略+Referer校验(适配S3网站端点),或切换为S3 REST端点配合OAC(更安全)
方案一:保留S3网站端点,通过桶策略限制访问
更新桶策略,移除公共只读权限
替换现有桶策略,仅允许CloudFront访问身份,同时通过Referer校验拦截直接访问。示例策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity 你的OAI_ID" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::你的存储桶名称/*" }, { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::你的存储桶名称/*", "Condition": { "StringLike": { "aws:Referer": ["https://你的自定义域名/*", "https://你的CloudFront域名/*"] } } } ] }说明:第一条规则确保CloudFront能正常拉取资源;第二条规则仅允许来自自定义域名或CloudFront域名的请求,直接访问S3端点会因Referer不匹配被拒绝。
调整S3公共访问设置
进入存储桶「权限」-「阻止公共访问」,勾选前三项(阻止新的公共存储桶策略、阻止公共和跨账户访问存储桶策略、阻止新的公共访问控制列表),仅取消最后一项,确保访问权限完全由桶策略控制。
方案二:切换为S3 REST端点,用OAC彻底屏蔽直接访问(推荐)
S3网站端点不支持OAC,但REST端点支持,步骤如下:
- 删除现有CloudFront分发
- 创建新分发,源选择S3存储桶(而非网站端点)
此时源设置会出现OAC选项,选择「创建新的OAC」并关联当前分发。 - 更新S3桶策略,仅允许OAC访问
示例策略:{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::你的存储桶名称/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::你的AWS账户ID:distribution/你的CloudFront分发ID" } } } ] } - 配置CloudFront默认根对象
在分发设置中指定首页文件(如index.html),解决REST端点不自动索引页面的问题。 - 重新关联自定义域名与ACM证书
保持CNAME记录指向CloudFront分发域名,确保ACM证书覆盖自定义域名。 - 启用S3全部公共访问阻止
勾选所有公共访问阻止选项,此时S3桶完全拒绝直接访问,所有请求必须通过CloudFront转发。
内容的提问来源于stack exchange,提问作者iamnotarobot
相关产品推荐
相关产品推荐

