允许VPC访问时AWS S3 Bucket出现AccessDenied问题求助
让我们一步步拆解你遇到的问题,从几个关键方向入手排查:
1. 核心问题:aws:sourceVpc条件的生效前提
你桶策略里的aws:sourceVpc条件仅对通过VPC端点(Gateway或Interface Endpoint)发起的S3请求生效。如果你的EC2是通过公共互联网访问S3的公共Endpoint(比如你用的http://test.s3.us-east-1.amazonaws.com),AWS无法识别请求的源VPC,此时:
AllowByVpc策略的StringEquals: aws:sourceVpc条件不匹配,Allow权限不生效DenyByVpc策略的两个条件(NotIpAddress+StringNotEquals)都会触发:因为EC2的IP不是指定的185.24.222.124,且aws:sourceVpc字段不存在(自然不等于vpc-cf53cba8),所以Deny权限生效,导致AccessDenied。
验证方式:在EC2上执行以下命令确认EC2所属VPC:
curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/$(curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/)/vpc-id
再检查VPC是否配置了S3 Gateway Endpoint,且EC2所在子网的路由表有指向该端点的路由条目。
2. 检查IAM权限交集
AWS的权限是桶策略和IAM实体权限的交集,两者都允许才能生效。即使你的桶策略允许了VPC内的访问,如果EC2实例关联的IAM角色没有S3:PutObject(或s3:*)权限,也会被拒绝。
验证方式:
- 在EC2上安装AWS CLI后执行测试命令:
如果同样报错,检查IAM角色的权限策略是否包含允许写入该桶的语句,比如:aws s3 cp abc.jpg s3://test/abc.jpg{ "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::test/*" }
3. 简化curl命令,排除无关因素
你在curl命令中使用了--key和--cert客户端证书,但S3默认不需要客户端证书验证(除非你配置了CloudFront或第三方代理的自定义认证)。这些参数可能导致请求异常,建议先去掉测试:
curl -k -v -T abc.jpg http://test.s3.us-east-1.amazonaws.com/abc.jpg
另外,S3大部分区域默认要求HTTPS,尝试改用HTTPS端点:
curl -v -T abc.jpg https://test.s3.us-east-1.amazonaws.com/abc.jpg
4. 调整桶策略的逻辑(临时方案)
如果暂时不想配置VPC端点,可以修改Deny策略,添加Null条件排除aws:sourceVpc不存在的情况,避免公共Endpoint请求被误拒绝:
{ "Version": "2012-10-17", "Id": "NginxProxy", "Statement": [ { "Sid": "AllowByVpc", "Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::test/*", "Condition": { "StringEquals": { "aws:sourceVpc": "vpc-cf53cba8" } } }, { "Sid": "DenyByVpc", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::test/*", "Condition": { "NotIpAddress": { "aws:SourceIp": [ "185.24.222.124" ] }, "StringNotEquals": { "aws:sourceVpc": "vpc-cf53cba8" }, "Null": { "aws:sourceVpc": false } } } ] }
这样只有当aws:sourceVpc存在且不等于指定值,同时IP不匹配时才会拒绝,公共Endpoint的请求(aws:sourceVpc为Null)不会触发Deny。
5. 确认桶的区域和Endpoint匹配
确保你的S3桶确实位于us-east-1区域,否则使用test.s3.us-east-1.amazonaws.com会导致请求路由错误,间接引发AccessDenied。可以在AWS控制台查看桶的区域,或用AWS CLI执行:
aws s3api get-bucket-location --bucket test
内容的提问来源于stack exchange,提问作者Michal Sipek

