我在S3上有一个静态网站,我已将所有文件设置为公开。 此外,我有一个带有nginx的EC2实例,它充当反向代理并且可以访问静态网站,因此S3扮演原始角色。
我现在要做的是将S3上的所有文件设置为私有,以便只能通过来自nginx(EC2)的流量访问网站。
到目前为止,我已尝试过以下内容。我已经使用
创建了一个新的策略角色并将其附加到EC2实例授予权限的政策:AmazonS3ReadOnlyAccess
并重新启动了EC2实例。
然后我在S3存储桶控制台中创建了一个策略>权限>存储桶政策
{
"Version": "xxxxx",
"Id": "xxxxxxx",
"Statement": [
{
"Sid": "xxxxxxx",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXX:role/MyROLE"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::XXX-bucket/*"
}
]
}
作为校长,我设置了我为EC2实例创建角色时获得的ARN。
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXX:role/MyROLE"
},
然而,这不起作用,任何帮助都表示赞赏。
答案 0 :(得分:5)
如果带有nginx的Amazon EC2实例仅向Amazon S3发出通用Web请求,那么问题就变成了如何识别来自nginx的请求,并拒绝所有其他请求。
一种方法是使用 VPC Endpoint for S3 ,它允许从VPC直接通信到Amazon S3(而不是走出Internet网关)。
存储分区策略可以限制对存储区的访问,以便只能通过该端点访问它。
以下是来自Example Bucket Policies for VPC Endpoints for Amazon S3的广告投放管理政策:
以下是S3存储桶策略的示例,该策略仅允许从ID为
examplebucket
的VPC端点访问特定存储桶vpce-1a2b3c4d
。该策略使用aws:sourceVpce
条件密钥来限制对指定VPC端点的访问。
{
"Version": "2012-10-17",
"Id": "Policy",
"Statement": [
{
"Sid": "Access-to-specific-VPCE-only",
"Action": "s3:*",
"Effect": "Allow",
"Resource": ["arn:aws:s3:::examplebucket",
"arn:aws:s3:::examplebucket/*"],
"Condition": {
"StringEquals": {
"aws:sourceVpce": "vpce-1a2b3c4d"
}
},
"Principal": "*"
}
]
}
所以,完整的设计将是:
答案 1 :(得分:1)
Amazon S3中的权限可以通过多种方式授予:
如果上述任何一项授予访问权限,则可以公开访问该对象。
您的方案需要以下配置:
每当您拥有与用户/组/角色相关的权限时,最好在 IAM 中而不是在Bucket中分配权限。使用存储分区策略可以对所有用户进行一般访问。
关于角色的政策将是:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowBucketAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::my-bucket/*"
]
}
]
}
此政策直接应用于IAM角色,因此无需principal
字段。
请注意,此政策仅允许GetObject
- 它不允许列出存储桶,上传对象等。
您还提到"我已将所有文件设置为公开"。如果您通过使每个单独的对象公开可读来完成此操作,那么任何人仍然可以访问这些对象。有两种方法可以防止这种情况 - 从每个对象中删除权限,或创建一个带有拒绝语句的Bucket Policy来停止访问,但仍然允许Role访问。
这开始变得有点棘手且难以维护,所以我建议删除每个对象的权限。这可以通过管理控制台通过编辑每个对象的权限来完成,或者通过AWS Command-Line Interface (CLI)使用如下命令来完成:
aws s3 cp s3://my-bucket s3://my-bucket --recursive --acl private
这会就地复制文件,但会更改访问设置。
(我不能100%确定是使用--acl private
还是--acl bucket-owner-full-control
,所以请稍微玩一下。)