ECS容器内PHP脚本访问S3遭403,如何配置Bucket Policy?
解决ECS容器访问S3桶的403权限问题
现有S3策略的问题
你当前的Deny策略逻辑完全错误:
{ "Effect": "Deny", "Principal": "*", "Action": [ "s3:PutObject", "s3:ListBucket", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::ss-bucket-stag", "arn:aws:s3:::ss-bucket-stag/*" ], "Condition": { "StringNotLike": { "aws:PrincipalArn": "*" } } }
StringNotLike: "aws:PrincipalArn": "*" 表示只有当请求的PrincipalArn不是任何值时才执行Deny,但所有合法的AWS请求(包括ECS任务发起的)都会携带有效的aws:PrincipalArn,所以这个Condition永远不成立,导致Deny规则对所有请求生效,这就是你遇到403 Forbidden的根本原因。
正确的配置步骤
1. 修正或移除错误的Deny策略
直接删除当前的Deny策略,或者替换为符合需求的权限规则。如果你的目标是仅允许指定AWS资源(比如ECS任务)访问桶,优先通过IAM角色授权,而非Bucket Policy。
2. 给ECS任务配置IAM角色
- 创建一个IAM角色,信任关系设置为允许
ecs-tasks.amazonaws.com扮演该角色:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } - 给该角色附加权限策略,授予访问目标S3桶的权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:ListBucket", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::ss-bucket-stag", "arn:aws:s3:::ss-bucket-stag/*" ] } ] } - 在ECS任务定义中指定这个IAM角色作为任务角色(Task Role)。
3. (可选)通过Bucket Policy限制访问
如果必须用Bucket Policy来控制访问,可以添加以下Allow策略,仅允许你的ECS任务角色访问:
{ "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::你的AWS账号ID:role/你的ECS任务角色名称" }, "Action": [ "s3:PutObject", "s3:ListBucket", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::ss-bucket-stag", "arn:aws:s3:::ss-bucket-stag/*" ] }
4. 优化容器内的PHP访问方式
直接用fopen访问S3的HTTPS链接需要手动处理请求签名,容易出错。推荐使用AWS SDK for PHP,它会自动获取ECS任务角色的临时凭证,无需手动配置,示例代码:
use Aws\S3\S3Client; $s3 = new S3Client([ 'version' => 'latest', 'region' => 'us-west-2' ]); // 获取对象 $result = $s3->getObject([ 'Bucket' => 'ss-bucket-stag', 'Key' => 'test/test.csv' ]); // 读取内容 $content = $result['Body']->getContents();
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

