Amazon S3出现拒绝访问,如何定位权限问题?

文件已经上传到Amazon S3,控制台中也能看到,访问时却返回“Access Denied”。这类问题不一定只是IAM权限不足,还可能与存储桶策略、公共访问限制、对象所有权和KMS密钥有关。

“文件明明已经上传成功,为什么打开地址还是提示拒绝访问?”

这是使用Amazon S3时比较常见的问题。

有些人遇到403错误后,会直接给IAM用户增加更多权限;还有人会关闭存储桶的公共访问限制。这样做偶尔能够让文件恢复访问,却可能在不知不觉中扩大数据暴露范围。

S3返回拒绝访问,只能说明当前请求没有通过权限检查,并不能直接说明是哪一条策略造成的。

排查时最好先确认访问者是谁、执行什么操作,再逐层检查权限。

一、先确认具体是哪一种访问失败

同样是“Access Denied”,背后的操作可能完全不同。

常见情况包括:

  • 可以看到存储桶,但无法查看文件列表。

  • 可以查看文件列表,但不能下载对象。

  • 可以下载旧文件,但不能上传新文件。

  • 控制台可以打开,通过程序访问却失败。

  • AWS账号内部可以访问,外部用户不能访问。

  • 通过S3可以访问,通过CloudFront却返回403。

这些情况对应的权限并不相同。

例如,查看存储桶中的文件列表,需要存储桶层面的权限;下载某个文件,需要对象读取权限;上传文件则需要对象写入权限。

所以,第一步不是立即修改策略,而是确认失败的具体操作。

二、确认请求使用的是哪个身份

很多S3权限问题,根源不是策略写错,而是实际发起请求的身份与预期不一致。

需要确认请求来自:

  • IAM用户

  • IAM角色

  • EC2实例角色

  • Lambda执行角色

  • 另一个AWS账号

  • CloudFront

  • 预签名链接

  • 未登录的匿名用户

例如,开发人员在控制台中拥有访问权限,但部署到EC2上的程序使用的是实例角色。如果实例角色没有S3权限,程序仍然会返回拒绝访问。

又或者,预签名链接虽然已经生成,但生成链接的身份本身没有读取对象的权限,链接同样无法正常使用。

不要只检查当前登录控制台的账号,还要确认业务程序真正使用的身份。

三、检查IAM策略和存储桶策略

S3访问权限通常会同时受到IAM策略和存储桶策略影响。

检查时重点关注三类问题:

  • 是否缺少当前操作需要的允许权限。

  • 资源范围是否写错。

  • 是否存在明确的拒绝规则。

AWS权限判断中,明确的拒绝通常会优先于允许。也就是说,即使IAM策略允许读取对象,只要存储桶策略中存在匹配当前请求的拒绝条件,访问仍然会失败。

常见的拒绝条件包括:

  • 只允许指定IP地址访问。

  • 只允许通过指定VPC端点访问。

  • 要求请求使用HTTPS。

  • 只允许指定账号或角色访问。

  • 要求对象使用指定的加密方式。

  • 限制访问时间或来源网络。

AWS官方将S3拒绝访问分为明确拒绝和隐式拒绝:前者是策略中存在匹配的拒绝规则,后者是没有任何有效规则允许当前操作。AWS S3拒绝访问排障说明

四、不要混淆存储桶权限与对象权限

S3的存储桶和对象属于不同的资源层级。

能够查看存储桶,不代表能够读取里面的文件;能够上传文件,也不一定拥有删除或修改文件权限。

比较常见的配置问题是:

  • 策略只允许列出存储桶,没有允许读取对象。

  • 策略允许读取对象,但资源范围没有包含存储桶中的文件。

  • 只授权了某个目录前缀,程序却访问了其他目录。

  • 对象名称中的大小写、空格或特殊字符不一致。

S3对象名称区分大小写。Image.jpg和image.jpg会被视为两个不同对象。

还有一种容易误判的情况:请求的文件实际上不存在,但访问者没有查看存储桶列表的权限。此时,S3可能返回403,而不是直接告诉访问者文件不存在。

因此,排查时还要确认对象路径和文件名是否真实存在。

五、检查“阻止公共访问”设置

新建S3存储桶通常默认启用“阻止公共访问”。

这个设置的作用,是防止存储桶策略或ACL意外把数据公开到互联网。如果业务希望通过匿名方式直接访问对象,即使已经配置了公共读取策略,阻止公共访问仍可能让请求失败。

但这里需要特别注意:

看到403错误,并不代表应该关闭阻止公共访问。

如果文件本来就只允许内部系统访问,应当继续保留该设置,通过IAM角色或受控的存储桶策略授权。

如果网站使用CloudFront分发S3文件,也不一定需要把存储桶完全公开。更稳妥的方式是让CloudFront通过受控身份访问S3。

AWS说明,S3公共访问阻止设置能够覆盖部分存储桶策略、ACL和对象权限。AWS公共访问设置说明

六、检查对象所有权

如果文件由另一个AWS账号上传,存储桶所有者不一定自动拥有该对象的完整控制权,尤其是仍在使用旧式ACL管理方式的存储桶。

这类问题通常表现为:

  • 同一个存储桶中,部分对象可以访问,部分对象返回403。

  • 存储桶管理员可以查看文件名称,但无法读取或修改某些文件。

  • 问题对象刚好由另一个账号或第三方系统上传。

AWS目前建议使用“存储桶拥有者强制”模式,由存储桶所有者统一管理对象,并通过IAM策略和存储桶策略控制权限。新建存储桶通常已默认关闭ACL,但旧存储桶仍有必要检查对象所有权设置。AWS对象所有权说明

七、使用KMS加密时还要检查密钥权限

如果对象使用AWS KMS密钥加密,仅有S3读取权限可能还不够。

访问者还需要具备相应的KMS密钥使用权限,并且密钥策略不能拒绝该身份。

常见情况是:

  • 用户可以读取未加密对象,却无法读取KMS加密对象。

  • 文件上传成功,但其他角色下载时返回拒绝访问。

  • 跨账号访问时,S3权限正确,KMS密钥策略却没有授权对方账号。

  • 使用了错误地域或已经停用的密钥。

如果只有部分加密对象出现问题,应当把检查重点放到KMS密钥策略和调用身份上。

八、跨账号访问要检查双方授权

当访问者和存储桶属于不同AWS账号时,权限检查会更复杂。

一般需要同时确认:

  • 访问方身份具备执行操作的权限。

  • 存储桶策略允许该账号或角色访问。

  • 没有组织策略限制访问。

  • VPC端点策略没有拒绝该存储桶。

  • KMS密钥策略允许跨账号使用。

  • 对象所有权符合预期。

只修改访问方的IAM策略,通常不足以完成跨账号授权。资源拥有方也需要明确允许相应访问。

九、通过CloudFront访问时单独检查

如果S3对象可以直接访问,但通过CloudFront返回403,问题可能不在普通IAM用户权限上。

此时需要检查:

  • CloudFront源站是否指向正确的存储桶。

  • 源站路径是否填写正确。

  • S3存储桶策略是否允许CloudFront访问。

  • CloudFront使用的源站访问控制是否匹配。

  • 默认首页文件是否真实存在。

  • 请求路径中的大小写是否正确。

不要因为CloudFront返回403,就直接把整个S3存储桶改成公共读取。应先确认CloudFront与S3之间的授权关系。

推荐的排查顺序

遇到S3拒绝访问,可以按照下面的顺序检查:

  1. 确认失败的是查看、下载、上传还是删除操作。

  2. 确认真正发起请求的IAM用户或角色。

  3. 检查IAM策略是否允许对应操作。

  4. 检查存储桶策略是否存在拒绝条件。

  5. 确认对象名称、路径和资源范围。

  6. 查看阻止公共访问设置。

  7. 检查对象所有权和ACL状态。

  8. 检查KMS密钥权限。

  9. 跨账号场景继续检查组织和VPC端点策略。

  10. 使用CloudFront时检查源站访问授权。

每次只修改一处配置,然后重新测试。这样才能判断是哪项设置真正影响了访问。

结语

Amazon S3的权限判断不是只看一条IAM策略,而是综合考虑身份策略、存储桶策略、公共访问设置、对象所有权、加密密钥和组织限制。

面对403错误,最有效的办法不是盲目增加权限,而是先回答两个问题:

谁在访问?他准备对哪个资源执行什么操作?

把这两个问题确认清楚,再沿着权限链逐层检查,大多数拒绝访问问题都能找到明确原因。