Amazon S3递归复制失败:调用ListObjects时提示访问被拒绝
首先得说你踩了一个很容易忽略的小坑——你的IAM权限模拟命令用错了动作前缀!
你执行的模拟命令里写的是iam:ListBucket、iam:GetObject,但S3相关的API动作前缀是s3:,不是iam:!这些带iam:前缀的动作根本不是S3的操作,所以模拟返回的Allowed完全是无效的,根本没评估你对S3桶的真实权限。这就是为什么模拟显示允许,但实际执行aws s3 cp时还是报AccessDenied的核心原因之一。
接下来我们一步步排查可能的问题:
1. 先修正权限模拟命令
重新执行正确的模拟命令,才能得到准确的权限结果:
aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::123324234234:user/user1 --action-names s3:ListBucket s3:GetObject s3:PutObject --resource-arns arn:aws:s3:::somebucket arn:aws:s3:::somebucket/*
注意这里要同时指定桶级资源(arn:aws:s3:::somebucket)和对象级资源(arn:aws:s3:::somebucket/*):s3:ListBucket是作用于桶本身的动作,而s3:GetObject是作用于桶内对象的动作,两者需要的资源ARN不一样。
2. 检查S3桶的桶策略
即使你的IAM用户有允许的权限,如果目标S3桶的桶策略里设置了Deny语句,AWS会优先执行拒绝规则,覆盖IAM用户的允许权限。你需要登录AWS控制台,进入该S3桶的权限设置页,查看桶策略是否有针对当前用户或其所属组的拒绝规则。
3. 排查对象级权限或加密限制
- 如果桶内的对象设置了单独的ACL(访问控制列表),拒绝了当前用户的读取权限,也会导致下载失败。可以先尝试下载单个文件测试:
如果单个文件也失败,大概率是对象权限或桶策略的问题;如果单个文件能成功,再回头看递归下载的权限是否有遗漏。aws s3 cp s3://somebucket/某个存在的文件名.txt . - 另外,如果桶开启了默认服务器端加密,且你的IAM用户没有对应的KMS权限(如果用了KMS加密的话),也会出现访问被拒绝的情况。
4. 检查IAM用户的权限边界
如果这个IAM用户设置了权限边界(Permission Boundary),即使你给用户附加了允许的策略,权限边界也会限制用户实际能执行的动作。需要查看用户的权限边界是否包含所需的S3动作(s3:ListBucket、s3:GetObject等)。
最后看你的IAM策略
你的IAM策略本身是没问题的:第一个Statement给了桶的ListBucket权限,第二个Statement给了桶和桶内所有对象的s3:*权限,逻辑上已经覆盖了递归下载所需的权限。所以问题大概率出在上面提到的模拟命令错误、桶策略、权限边界或对象级权限上。
内容的提问来源于stack exchange,提问作者Suncatcher

