已为EC2实例附加S3全权限IAM角色,但EC2托管网站仍无法查看S3 Bucket图片对象(403 Forbidden)的解决咨询
碰到这种明明配置了IAM权限却还是403的情况确实闹心,我来给你梳理几个关键排查方向,应该能定位到问题:
检查S3对象的ACL权限:
有时候哪怕IAM角色权限拉满,对象本身的ACL可能没开访问权限。你可以先去S3控制台找到那张图片,查看它的ACL设置,确认是否允许Authenticated Users(EC2用IAM角色属于认证用户组)拥有读取权限,或者直接把你的IAM角色ARN添加到ACL的授权列表里。验证桶的Block Public Access配置:
如果你的网站是直接用S3对象的URL(比如https://your-bucket.s3.amazonaws.com/photo.jpg)在前端加载图片,那得检查桶的Block Public Access设置。要是里面的阻止通过任何访问控制列表(ACL)授予对存储桶和对象的公共访问选项是开启的,那即使IAM有权限,前端的公共访问请求也会被拦截。这种情况要么调整Block Public Access的设置(适合允许公开访问的场景),要么改成在EC2后端生成预签名URL给前端调用。确认EC2实例是否正确获取了IAM角色凭证:
登录到你的EC2实例,执行以下命令检查角色凭证是否正常:# 查看实例关联的IAM角色名称 curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ # 替换成上面返回的角色名,获取凭证详情 curl http://169.254.169.254/latest/meta-data/iam/security-credentials/your-role-name如果返回错误或者没有有效凭证,可能是IAM角色没正确附加到实例,或者VPC的元数据服务被禁用了,试着重新附加角色或者检查VPC配置。
排查S3 Bucket Policy的冲突:
Bucket Policy的优先级有时候会高于IAM角色权限,尤其是里面有Deny语句的话。去S3控制台查看桶的Bucket Policy,确认有没有针对GetObject动作的拒绝规则,比如是否不小心拒绝了所有用户的访问,或者限制了特定IP/条件,导致EC2的请求被拦截。确认图片的访问模式是否匹配权限:
划重点:IAM角色的权限是给EC2实例用的,不是给前端浏览器用的!如果你的网站是前端直接请求S3 URL,那这个请求是来自用户的浏览器,不会带上EC2的IAM凭证,自然会403。这种情况必须改成:要么让EC2后端读取S3图片后返回给前端,要么在后端生成预签名URL(有效期内可以访问),前端用这个预签名URL加载图片。检查VPC Endpoint的政策(如果使用):
要是你的EC2是通过VPC Endpoint访问S3,那VPC Endpoint本身也有访问政策,可能限制了对目标桶的GetObject操作。去VPC控制台找到对应的S3 Endpoint,检查它的政策是否允许你的IAM角色访问目标桶。
内容的提问来源于stack exchange,提问作者digdigdoot

