我有一个简单的存储桶,看起来像images.mysite.com
我的 S3 和其他包含备份等的存储桶。
我希望允许特定用户能够访问images.mysite.com
存储桶以上传图像。但是,我不希望他看到任何其他桶;甚至不存在。
我无法制定这样的政策;每次我尝试一些限制性的东西时,它最终都会阻止任何存储桶的列表。
我已经尝试了一段时间,终于想出了一个可行的解决方案。您必须根据您正在执行的操作类型使用不同的“资源”。此外,我在上一个答案中包含了一些缺失的操作(例如DeleteObject
)并限制了更多操作(例如PutBucketAcl
)。
以下 IAM 政策现在对我有用:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
],
"Resource": "arn:aws:s3:::itnighq",
"Condition": {}
},
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": "arn:aws:s3:::itnighq/*",
"Condition": {}
},
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*",
"Condition": {}
}
]
}
关于存储桶的操作和关于对象的操作必须具有不同的 arn。
我们的用例:为我们的云应用程序的客户端提供备份空间,客户端可以使用常用的 S3 工具直接访问。当然,任何客户都不应该看到其他客户拥有什么。
正如 cloudberryman 解释的那样,“您可以列出所有存储桶,也可以不列出。”所以我们必须想出一个变通办法。背景:
需要向用户授予 ListAllMyBuckets 权限,以便 AWS S3 控制台或 S3Fox 连接时不会出现错误消息。但是 ListAllMyBuckets 列出所有存储桶,无论分配的资源如何(实际上,只有 arn:...:::* 有效)。如果你问我,那是一个严重的错误。顺便提一句。拒绝所有存储桶的 ListBucket 不会阻止它们被列出,因为 ListBucket 授予列出存储桶内容的权限。
我认为有 3 种可能性可以解决。我选择了最后一个。
(1) 使用神秘的存储桶名称,例如 GUID
优点:易于设置
缺点:难以管理,尤其是对客户端而言。(想象一下在数千个其他 GUID 中找到一个特定的 GUID。)还显示了存储桶的数量 = 使用备份服务的客户端数量。
(2) 使用一个带有客户端特定文件夹的存储桶
这就是 Amazon 在其 S3/IAM 示例中建议的方式,以提供仅供特定用户或用户组访问的空间。请参阅: AWS 示例 IAM 策略
优点:相当容易设置,符合 AWS 的想法
缺点:强制公开所有存储桶的存在,因此客户端可以找到他们的“家”存储桶。AWS 会计提供存储桶使用情况的统计信息,但不提供文件夹使用情况的统计信息,这使得客户难以计算成本。
(3) 不授予 ListAllMyBuckets 的访问权限
优势:你得到你想要的:客户看不到其他客户的桶
缺点:客户看不到自己的桶。S3Browser 带有一个很好的“不能做”消息,并要求输入存储桶名称。S3Fox 在连接到根时会引发错误消息,但如果存储桶名称已知,则允许直接导航到客户端的存储桶。Amazon S3 控制台根本不起作用。
希望这有助于您根据需要处理 S3 IAM。
如果未授予权限,则无法提供对 S3 控制台的访问ListAllMyBuckets
权限。
在我的情况下(也许还有你的未来读者),一个可接受的替代方法是将登录时的用户直接重定向到你希望他们看到的存储桶。
为此,请将以下内容附加到您的 IAM 登录 url:
/s3/?bucket=bucket-name
完整登录 URL(替换your-alias和bucket-name):
https://your-alias.signin.aws.amazon.com/console/s3/?bucket=bucket-name
IAM 政策(替换bucket-name):
{
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket-name",
"arn:aws:s3:::bucket-name/*"
]
}
]
}
有关如何为用户创建存储桶特定权限的更多信息,请阅读此博客: http: //mikeferrier.com/2011/10/27/granting-access-to-a-single-s3-bucket-using-amazon-iam /
试试这个政策。还要考虑到没有办法让用户只列出选定的存储桶。您可以列出所有存储桶,也可以不列出。
{
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:GetObjectAcl",
"s3:PutObjectAcl",
"s3:ListBucket",
"s3:GetBucketAcl",
"s3:PutBucketAcl",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::your_bucket_here/*",
"Condition": {}
},
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*",
"Condition": {}
}
]
}
我将这个问题解释为:“我可以允许访问一个存储桶,而其他存储桶将无法访问并因此不可见。” 因为,显示未授予访问权限的存储桶的名称仍然等同于信息泄漏。
而正确的答案是否定的。所需的权限是 ListAllMyBuckets,这将允许用户查看所有存储桶。忽略此权限将使控制台无法使用。
有一种很好的方法可以让用户访问特定的存储桶,而无需包含其他存储桶的知识。类似于下面的组策略将只允许用户看到“存储桶 a”。唯一的问题是,如果用户连接到给定的存储桶端点,他们将只能访问存储桶。对于下面的示例,它将是 bucket-a.s3.amazonaws.com。存储桶可能还必须允许“经过身份验证的用户”才能发生这种情况。
{
"Statement": [
{
"Sid": "<EXAMPLE_SID>",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket-a"
]
},
{
"Sid": "<EXAMPLE_SID>",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket-a/*"
]
}
]
}
此方法在 Mac OS/X 上使用 Cyberduck 并使用 s3cmd 包进行了测试
./s3cmd ls s3://bucket-a --access_key=ACCESS_KEY --secret_key=SECRET_KEY --bucket-locat
ion=ap-southeast-2
对为什么没有检查答案感到困惑?
让我们从上述解决方案中分解每个政策声明:
此策略声明适用于存储桶的内容,但不适用于 buck 本身。这可能不是问题所要求的,因为您看不到桶中的内容。
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:GetObjectAcl",
"s3:PutObjectAcl",
"s3:ListBucket",
"s3:GetBucketAcl",
"s3:PutBucketAcl",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::your_bucket_here/*",
"Condition": {}
}
派生自的这两条语句策略在 ( arn:aws:s3:::your_bucket_here/
) readonly处授予对存储桶的只读访问权限,但仍允许对存储桶的内容 ( arn:aws:s3:::your_bucket_here/*
) 进行 CRUD 操作。
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
],
"Resource": "arn:aws:s3:::your_bucket_here",
"Condition": {}
},
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectAclVersion"
],
"Resource": "arn:aws:s3:::your_bucket_here/*",
"Condition": {}
}
但是,该策略包含以下语句,允许用户查看端点上的所有存储桶。这可能不是问题所要求的。
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*",
"Condition": {}
}
但是,如果您使用浏览 S3 存储的客户端,上述内容非常有用。如果您的客户端直接访问存储而不是存储桶,那么您需要访问根目录中的存储桶列表。
可能是最简单的用例:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::bucket-name"]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::bucket-name/*"]
}
]
}
我找到了这个解决方案:
AWS FLOW:
桶策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*", #Role ID
"111111111111" #AccountID
]
}
}
}
]
}
IAM 政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*", #Role ID
"AIDAEXAMPLEID", #UserID
"111111111111" #AccountID
]
}
}
}
]
}
aws iam get-user --user-name USER-NAME --profile=ExampleProfile
aws iam get-role --role-name ROLE-NAME --profile=ExampleProfile
PS注意存储桶策略,您可以在没有权限的情况下置身事外
使用 AWS Organizations 有一种简单的方法或解决方法可以做到这一点。AWS 组织允许您拥有多个用户账户。您的主账户可以有多个 AWS 账户(子),并且无论在哪个 AWS 账户中添加任何服务(s3/EC2/*),只有这些资源是可见的。
请参考https://aws.amazon.com/blogs/aws/aws-organizations-policy-based-management-for-multiple-aws-accounts/ https://aws.amazon.com/organizations/
正如上面已经充分讨论的那样,在控制台上只列出一个存储桶是不可能的。但如果 S3 存储桶的访问权限附加到 IAM,如果存储桶的 URL 可用,IAM 可以直接访问该存储桶。S3 存储桶网址将如下所示:
https://s3.console.aws.amazon.com/s3/buckets/BucketName
BucketName 是 IAM 有权访问的存储桶的名称
类似于上面其他人描述的:
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"s3:ListBucket"
],
"Resource":"arn:aws:s3:::awsexamplebucket"
},
{
"Effect":"Allow",
"Action":[
"s3:PutObject",
"s3:GetObject"
],
"Resource":"arn:aws:s3:::awsexamplebucket/*"
}
]
}
然而,这是缺失的部分。虽然无法通过 S3->Home 访问存储桶,但可以通过直接链接仅访问所需的存储桶。
https://s3.console.aws.amazon.com/s3/buckets/yourawsbucket/
您可以在以下帖子中找到更多信息:
https://aws.amazon.com/premiumsupport/knowledge-center/s3-console-access-certain-bucket/
试试这个政策。用户不能列出任何存储桶,他们必须使用直接链接到允许的存储桶。
例如:s3.console.aws.amazon.com/s3/buckets/bucketname/?region=us-east-1&tab=overview
{
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucketname"
]
},
{
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucketname*"
]
},
],
"Version": "2012-10-17"
}
我设法使以下工作。意味着列出其他存储桶收到拒绝访问消息。但是,如果我将存储桶名称设置为路径连接,仍然能够看到我想要的存储桶。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::test"
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::test"]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::test/*"]
}
]
}
我正在使用 Cyberduck 来测试这个连接。
虽然无法将s3:ListAllMyBuckets
操作限制为特定存储桶,但对于解决方法,您可以向它们发送特定存储桶的控制台 URL,例如
https://s3.console.aws.amazon.com/s3/buckets/BUCKET_NAME/
为此,您需要为给定的用户或组指定以下策略文档:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
],
"Resource": [
"arn:aws:s3:::my-bucket-1",
"arn:aws:s3:::my-bucket-2"
]
},
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": [
"arn:aws:s3:::my-bucket-1/*",
"arn:aws:s3:::my-bucket-2/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
}
]
}
您的存储桶在哪里my-bucket-1
以及在哪里my-bucket-2
提供读写访问权限。
有关的:
下面的解决方案对我有用。我想要一个策略来授予对特定存储桶my-s3-bucket上特定用户my_iam_user的访问权限。
此策略允许我的用户列出、删除、获取特定 s3 存储桶上的文件。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/my_iam_user"
},
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::my-s3-bucket"
},
{
"Sid": "AddDeleteFiles",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/my_iam_user"
},
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-s3-bucket/*"
}
]
}
不,目前无法限制用户在根目录或其他任何地方查看选择性存储桶。您现在只有这 3 个选项。
我选择让客户明确使用存储桶名称。
我使用以下内容向其他用户隐藏存储桶的内容。这不仅有助于隐藏其他存储桶(不要使用 ListAllMyBuckets),还有助于隐藏同一存储桶中的文件夹,当您创建一个存储桶但希望其中包含子文件夹为 IAM 用户/子文件夹分配适当的权限时。
以下策略适用于 IAM 组,并且所有用户都在该组中。您需要aws:userid
在存储桶中获取并创建一个具有相同名称的子文件夹。
可以使用 UserID:aws iam get-user --user-name "user_name_for_folder_access":
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bucket_name/${aws:userid}/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket_name"
]
}
]
}
我们想出的一个很好的简单解决方案是阻止用户登录到根目录。因此,他们必须使用设置为所需文件夹的远程路径登录。
{
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::folder-name*",
"Condition": {}
}
]
}
我只是添加了一个类似的需求,由此解决:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:Put*",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket-name",
"arn:aws:s3:::my-bucket-name/*"
]
}
]
}
亚马逊在http://blogs.aws.amazon.com/security/post/Tx3VRSWZ6B3SHAV/Writing-IAM-Policies-How-to-grant-access-to-an-Amazon-S3-bucket对此进行了详细说明
这对我来说很完美。用户可以上传、下载和获取文件列表,但无法查看其他存储桶中的文件。
{
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:GetObjectAcl",
"s3:PutObjectAcl",
"s3:ListBucket",
"s3:GetBucketAcl",
"s3:PutBucketAcl",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::mybucketname/*",
"Condition": {}
},
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*",
"Condition": {}
},
{
"Effect": "Deny",
"Action": [
"s3:DeleteBucket",
"s3:DeleteBucketPolicy",
"s3:DeleteBucketWebsite",
"s3:DeleteObject",
"s3:DeleteObjectVersion"
],
"Resource": "arn:aws:s3:::mybucketname/*",
"Condition": {}
}
]
}
Deny
为您不想访问的存储桶添加一个子句。请记住,它们可能仍会列出,但您将无法访问其中的内容。
{ “版本”:“2012-10-17”, “陈述”: [ { “效果”:“允许”, “行动”:“s3:*”, “资源”:“*” }, { “效果”:“拒绝”, “行动”:“s3:*”, “资源”:[ "arn:aws:s3::: 桶名", “arn:aws:s3:::桶名/*” ] } ] }