我的总体目标: 我尝试了几个方面并阅读了相关的AWS文档,但我无法确定如何编写S3存储桶策略以仅允许访问特定的IAM角色和Cloudfront Origin Access Identity(OAI),并拒绝其他所有人。
到目前为止我尝试过的事情: 1.我找到了这个博客,其中展示了如何限制对特定IAM角色的s3存储桶访问:https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/ 2.基于上面的博客,我写了以下的桶策略。此策略仅允许MY_IAM_ROLE允许对名为“myBucket”的存储桶执行所有操作:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"MY_IAM_ROLE_USER_ID:*"
]
}
}
}
]
}
我的问题: 如何在一个政策声明中合并(1)aws:IAM角色/用户的用户ID和(2)OAI ID?
答案 0 :(得分:1)
总而言之,您需要一个限制访问S3存储桶和内容的存储桶策略,但允许访问您希望指定的Cloudfront Origin Access Identity以及您的IAM角色。我有几种方法可以做到这一点,一个使用NotPrincipal元素,另一个使用Principal元素。这取决于有多少人使用您的IAM角色,或者您是否计划扩展对角色的访问权限。您可以通过使用NotPrincipal元素和显式拒绝在存储桶策略中指定权限来阻止Amazon Identify和Access Management(IAM)实体访问您的Amazon S3存储桶。但是,NotPrincipal不支持通配符。
在此策略示例中,您必须列出每个用户的角色会话名称以及将承担角色的每个实例ID:
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:sts::444455556666:assumed-role/cross-account-read-only-role/cross-account-audit-app",
"arn:aws:sts::444455556666:assumed-role/cross-account-read-only-role/instanceID",
"arn:aws:iam::444455556666:role/cross-account-read-only-role",
"arn:aws:iam::444455556666:root"
]
}
要涵盖所有这些用户和实例,您需要在语句中使用通配符来表示假定的角色:
"arn:aws:sts::444455556666:assumed-role/cross-account-read-only-role/*"
但是,NotPrincipal元素不支持通配符。如果您只使用角色或一个实例,这将起作用,但在扩展时,您需要添加ARN为用户/实例承担角色。
在此示例中,使用NotPrincipal
作为每个语句块中的目标实体,而不是"Principal": "*"
,其中包括每个允许块的条件。在"aws:userid": ["ROLE-ID:*"]
中使用通配符来包括调用进程传递的所有名称(例如应用程序,服务或实例ID),以便在进行调用以获取临时凭证时使用。 有关详细信息,请参阅所有请求中可用的信息。包含root帐户以防止锁定:
"Condition": {
"StringLike": {
"aws:userid": [
"AROAID2GEXAMPLEROLEID:*",
"444455556666"
]
}
}
Deny块中的StringNotLike:
"Condition": {
"StringNotLike": {
"aws:userid": [
"AROAID2GEXAMPLEROLEID:*",
"444455556666"
]
}
}
以下是完整的政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::myExampleBucket",
"Condition": {
"StringLike": {
"aws:userid": [
"AROAID2GEXAMPLEROLEID:*",
"444455556666"
]
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::myExampleBucket/*",
"Condition": {
"StringLike": {
"aws:userid": [
"AROAID2GEXAMPLEROLEID:*",
"444455556666"
]
}
}
},
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::myExampleBucket/*",
"arn:aws:s3:::myExampleBucket"
],
"Condition": {
"StringNotLike": {
"aws:userid": [
"AROAID2GEXAMPLEROLEID:*",
"444455556666"
]
}
}
}
]
}
注意:
- 请确保使用您自己的角色ID和存储桶名称替换示例名称。
- 在上面的示例中,我使用的是IAM实体的唯一ID。 http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids
获取有关IAM角色的信息 以下get-role命令获取有关名为Test-Role:
的角色的信息aws iam get-role --role-name Test-Role
输出:
{
"Role": {
"AssumeRolePolicyDocument": "<URL-encoded-JSON>",
"RoleId": "AIDIODR4TAW7CSEXAMPLE",
"CreateDate": "2013-04-18T05:01:58Z",
"RoleName": "Test-Role",
"Path": "/",
"Arn": "arn:aws:iam::123456789012:role/Test-Role"
}
}
重要提示
基本上,当您使用 CloundFront API 创建 Origin Access Identity 时,您将获得UserID和S3规范ID,您必须记下它以使用此功能在条件字符串中。如果您目前没有CloudFront的Origin Access Identity的ID,请创建一个新ID,您可以按照建议保存ID元素和S3 Canonical ID。
答案 1 :(得分:1)
我遇到了同样的问题,我只需要限制对Cloudbuck(OAI),MediaConvert(Role)和某些用户(IAM)的访问。
NotPrincipal
指令适用于Cloudfront和单个用户,但是正如@MuhammadHannad所说,问题在于,对于一个角色,您必须列出与之关联的每个会话名称,并且无法通过将通配符与字符串,因为该元素不支持。
使用"Condition": {"StringNotLike": {"aws:userid" [...]}}
也不起作用,因为正如您在评论中所说,Cloudfront Origin Access Identity没有相应的aws:userid
。
我想我终于找到了解决方案,我们可以使用StringNotLike
而不是使用"Condition": {"ArnNotLike": {"aws:PrincipalArn": [...]}}
,它的行为显然与NotPrincipal
相同,但是可以使用通配符在资源名称中。
{
"Sid": "1",
"Effect": "Deny",
"Principal": "*",
"Condition": {
"ArnNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::111122223333:user/S3-USER",
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity AAAABBBBCCCC1",
"arn:aws:iam::111122223333:role/MediaConvertRole",
"arn:aws:sts::111122223333:assumed-role/MediaConvertRole/*",
"arn:aws:iam::111122223333:root"
]
}
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
]
}
答案 2 :(得分:0)
这似乎有点远,但找到Origin Access Identity的ID(不是规范用户ID ...找到以E
开头并且大约12个字符的ID )并将其添加到政策中:
"StringNotLike": {
"aws:userId": [
"MY_IAM_ROLE_USER_ID:*",
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXEXAMPLEXX"
]
}
请注意单词&#34; CloudFront Origin Access Identity&#34;包括空格,是这个引用字符串的一部分。完全按照所示插入,仅更改12个字符ID。
可能阻止此策略拒绝访问OAI。 如果有办法将OAI的用户包含在条件键中,这似乎是唯一可行的解决方案。
另外,您需要第二个策略声明,即允许对OAI进行必要访问的正常声明。
答案 3 :(得分:0)
我的老答案会支持某些人,但可能不是你的。所以,我正在发布另一个答案,它将更准确地满足您的需求。以下角色策略将允许访问IAM角色和OAI,并将拒绝其他所有人:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXXXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*"
},
{
"Sid": "2",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXXXX",
"arn:aws:iam::AWS-account-ID:role/role-name"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*"
}
]
}
答案 4 :(得分:0)
您的问题可以通过将Principal: "*"
语句中的Deny
替换为引用CloudFront OAI的相应NotPrincipal
,并为CloudFront OAI添加适当的Allow
语句来解决:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"NotPrincipal": {
"CanonicalUser": "..."
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::myBucket",
"arn:aws:s3:::myBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"MY_IAM_ROLE_USER_ID:*"
]
}
}
},
{
"Effect": "Allow",
"Principal": {
"CanonicalUser": "..."
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::myBucket/*"
}
]
}
这样,您的IAM角色会被Deny
条件排除在aws:userId
条件之外,而您的CloudFront OAI会被NotPrincipal
条件排除在外。所有其他主体仍将被拒绝访问,CloudFront OAI将仅具有您在存储桶策略中直接授予它的权限。
回想起来似乎很简单,这个解决方案肯定不是很明显,这个答案应归功于AWS Support,他最近为我回答了同样的问题。