如何将AWS S3存储桶设为私有并为对象授予读取访问权限
匹配“私有存储桶+公开读静态对象”的完整配置方案
配置逻辑说明
你之前尝试开启部分公共访问阻断(BPA)开关后网站所有对象无法访问,本质是四个开关全开后,你编写的公开读策略会被S3底层的公共访问拦截模块直接阻断,根本不会进入策略权限校验流程。问题根源是BPA开关配对错误,和你编写的存储桶策略本身没有直接关系。
第一步:配对公共访问阻断开关
四个开关不要全开(全开等于堵死所有公开访问路径),按照下面的逻辑配置(存储桶级和账户级的同配置项要保持一致,避免高层级配置覆盖低层级设置):
- 开启「阻断通过新访问控制列表(ACL)授予的针对存储桶和对象的公共访问」
- 开启「阻断通过任意访问控制列表(ACL)授予的针对存储桶和对象的公共访问」
这两个开关开启后,会从底层锁死ACL的公共授权能力,你当前ACL仅保留所有者全权限的状态就不会被修改,从根源上堵死ACL带来的误公开风险。 - 关闭「阻断通过新的公共存储桶或接入点策略授予的公共访问」
- 关闭「阻断通过任意公共存储桶或接入点策略授予的针对存储桶和对象的公共及跨账户访问」
这两个开关关闭后,你自定义的、仅允许对象读的存储桶策略不会被BPA系统直接拦截,不会出现“策略写了允许、请求却被系统底层返回403”的问题。
这套开关组合下,AWS的公开访问扫描器不会将你的存储桶判定为违规公开状态——因为所有ACL层面的公开通道已经完全封死,存储桶本身仅对所有者开放管理权限,仅通过显式策略放行匿名用户的对象读取操作,控制台会将该存储桶标记为“私有”,和可列目录、可改权限的完全公开桶有本质区别。
第二步:补全现有存储桶策略
你当前编写的PublicReadGetObject策略核心逻辑完全正确,仅需要增加一条边界限制,就能彻底实现“存储桶完全私有,仅所有者可管理,所有人只读指定对象”的目标:
调整后的完整策略代码如下:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": "arn:aws:s3:::nbcbigbend/*" }, { "Sid": "BlockPublicBucketManagement", "Effect": "Deny", "Principal": "*", "Action": [ "s3:ListBucket", "s3:PutBucketPolicy", "s3:PutBucketAcl" ], "Resource": "arn:aws:s3:::nbcbigbend", "Condition": { "StringNotEquals": { "aws:PrincipalAccount": "你的AWS账户ID" } } } ] }
新增的拒绝语句会拦掉所有非账户所有者的存储桶管理操作、列目录操作,避免外部用户扫描你桶内的文件路径,这也是AWS判定存储桶“是否合规私有”的核心参考项——只要不存在匿名的管理、列目录权限,哪怕开放对象读,也不会触发过度公开的安全告警。
常见踩坑提醒
- 不要将四个BPA开关全部开启后再配置公开读策略,这种情况下S3会直接校验拒绝保存你的策略,公开读请求也会被底层拦截
- 不要通过ACL开放公共读权限,只要ACL存在公共授权条目,就算存储桶策略写得再严格,也会被扫描器判定为“完全公开的存储桶”,也就是你当前收到告警的核心原因
- 你2017、2019年创建的老桶没有默认开启BPA的保护,早年版本的S3默认ACL配置会留公开读口子,因此被扫描器标记为公开;2023年后新建的存储桶默认四个BPA开关全开启,因此和你早年创建的桶状态存在差异
内容的提问来源于stack exchange,提问作者Pamela Cook - LightBe Corp
相关产品推荐
相关产品推荐

