是否有针对仅查看/访问一个存储桶的S3策略?

146

我有一个简单的存储桶,长得像 images.mysite.com 这样,在我的S3和其他包含备份等的存储桶中。

我想允许特定用户能够访问 images.mysite.com 存储桶以上传图片。但是,我不希望他看到任何其他存储桶,甚至不知道它们的存在。

我无法创建这样的策略;每次我尝试限制某些内容,就会阻止列出任何存储桶。


我投票关闭此问题,因为它应该在Superusers上。 - Tonny Madsen
一个策略可以在这里生成:http://awspolicygen.s3.amazonaws.com/policygen.html - Suhail Gupta
2
为什么不直接共享 bucket 的 URL -- https://s3.console.aws.amazon.com/s3/buckets/my-bucket-name/。这样可以避免他们看到整个列表,并且不会改变当前策略。 - treecoder
1
@TonnyMadsen,我认为这个问题非常适合在这个论坛上讨论。 - Arefe
23个回答

120

我尝试了一段时间,最终想出了一个可行的解决方案。你必须根据你正在执行的操作使用不同的“资源”。此外,我在先前的答案中包括了一些缺失的操作(例如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 必须不同。


9
非常感谢您的回答。值得注意的是,s3:ListAllMyBuckets权限的含义是该策略的接收者可以看到你(根用户)的所有存储桶。虽然没有直接透露数据,但存储桶名称可能会涉及敏感性/混淆。可以删除这个特定的权限,系统仍然可以正常工作(尽管“s3cmd ls”等命令将不返回目标存储桶)。 - Mike Repass
124
这并不会阻止用户查看其他存储桶的名称! - metdos
2
@HendraUzia 不是这样的。移除该策略会导致控制台根本不列出任何存储桶。 - Joshua Kolden
23
为了在控制台中查看存储桶列表(以便使用控制台访问存储桶),您必须授予ListAllMyBucketsGetBucketLocation权限,涵盖所有S3存储桶(对于资源,使用"arn:aws:s3:::*"而不是"*"将起作用)。正如这篇AWS博客文章中所述:“另外需要说明的是,当前无法有选择性地过滤出某些存储桶,因此用户必须获得列出所有存储桶的权限才能访问控制台。” - jwadsack
14
这是糟糕的建议。它很危险,也正是提问者不想要的。请参考 Andreas StankewitzBFar 的回答,了解可行的解决办法。 - AndreKR
显示剩余8条评论

50

如果不授予ListAllMyBuckets权限,则无法访问S3控制台。

在我的情况下(也许对于将来的读者也是如此),可接受的替代方案是在登录后直接将用户重定向到您想让他们看到的桶。

要实现这一点,请将以下内容附加到IAM登录URL末尾:/s3/?bucket=bucket-name

完整的登录URL(替换your-aliasbucket-name):

https://your-alias.signin.aws.amazon.com/console/s3/?bucket=bucket-name

IAM策略(替换bucket-name):

{
    "Version": "2012-10-17",
    "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/


1
这个很好用。如果用户无法在存储桶视图之外浏览,那就更理想了...但我会接受它的。谢谢 @BFar。 - Jamie Popkin
这是唯一正确的答案,其他所有答案都会列出每个存储桶 - 这应该根据原始请求隐藏。 - Steve Horvath
正是我所需。谢谢。 - dzhg
此策略包含以下错误:托管策略必须具有版本字符串。有关 IAM 策略语法的更多信息,请参阅 AWS IAM 策略。 - Yevgeniy Afanasyev
版本字符串(通常添加在JSON的根级别顶部)应为"Version": "2012-10-17",。请参见https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_version.html。 - filpa

43

我们的应用场景:为云应用程序的客户提供备份空间,客户可以直接使用常见的S3工具进行访问。当然,没有任何客户应该看到其他客户的内容。

如cloudberryman所解释的,“您可以列出所有存储桶或不列出”。因此,我们必须想出一个解决方法。背景:

向用户授予ListAllMyBuckets权限是必需的,以使AWS S3控制台或S3Fox在连接时不会出现错误提示。但是,ListAllMyBuckets会列出所有存储桶,而不考虑分配的资源(实际上,只有arn:...:::*有效)。如果你问我,这是一个严重的错误。顺便说一句,拒绝对所有存储桶进行ListBucket不会防止它们被列出,因为ListBucket授予权限来列出存储桶的内容。

我考虑了三种可能的解决方法。我选择了最后一种。

(1)使用加密的存储桶名称,例如GUIDs

优点:易于设置

缺点:对于客户端来说管理困难(想象一下在成千上万个GUID中找到特定的GUID)。还显示备份服务使用的存储桶数量=使用备份服务的客户数量。

(2)使用一个存储桶和客户特定的文件夹

这是亚马逊通过其S3/IAM示例建议为某些用户或用户组提供访问权限的方法。请参见: AWS Example IAM Policies

优点:相当容易设置,符合AWS的理念

缺点:强制公开所有存储桶的存在,以便客户可以找到他们的“主目录”存储桶。AWS会计提供存储桶使用统计信息,但不提供文件夹使用统计信息,这使得按客户计算成本变得困难。

(3)不授予ListAllMyBuckets的访问权限

优点:您得到了您想要的:客户无法看到其他客户的存储桶

缺点:客户端无法查看自己的存储桶。S3Browser 提供了一个友好的“无法执行”的消息,并要求输入存储桶名称。S3Fox 在连接到根目录时会抛出错误消息,但如果已知存储桶名称,则允许直接导航到客户端的存储桶。Amazon S3 控制台根本无法工作。

希望这些内容有助于您按需处理 S3 IAM。


1
另外,对于解决方案(1),如果您想使用带有存储桶的 Web 托管,则存储桶名称必须与域名匹配。 - Andy Fusniak

22

尝试使用此策略。还要注意,没有办法让用户仅列出所选的存储桶。您只能列出所有存储桶或不列出任何存储桶。

{
    "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": {}
        }
    ]
}

2
它很好用!我必须将操作更改为s3:*才能让它对我起作用。我还有"Resource": ["arn:aws:s3:::your_bucket_here", "arn:aws:s3:::your_bucket_here/*"],但这可能不是必需的。 - Michael Yagudaev
3
s3:* 授予了执行任何操作的权限,包括删除存储桶。您确定要这样做吗? - Dave Gregory

13
我理解这个问题的意思是:“我能否允许访问一个存储桶,而其他存储桶将无法访问且不可见。”因为显示未授权访问的存储桶名称仍然等同于信息泄露。
正确的答案是不行。所需的权限是ListAllMyBuckets,它将允许用户查看所有存储桶。省略此权限将使控制台无法使用。

7

有一种很好的方法可以让用户访问特定的存储桶,而不会泄露其他存储桶的信息。像下面这样的组策略将只允许用户查看“bucket 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

1
我仍然可以看到所有存储桶的列表。不起作用 :( - Rishikesh Chandra

5

对于为什么没有选中答案感到困惑?

让我们逐一分解上述解决方案中的每个策略声明:

此策略声明来自适用于存储桶的内容,但不适用于存储桶本身。这可能不是问题所询问的,因为您无法看到存储桶中的内容。

{
"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/)的只读访问权限,同时还允许在存储桶的内容(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存储的客户端,则上述非常有用。如果您的客户端访问存储而不是直接访问存储桶,则需要访问根目录下的存储桶列表。

3

可能是最简单的用例:

{
  "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/*"]
    }
  ]
}

1
AWS 响应:此策略包含以下错误:策略必须包含有效的版本字符串。 - MaximeBernard
没错 - 我纠正了我的回答 -><br/>这里只有两个可能的值:<br/>2012-10-172008-10-17。<br/>更多参考资料可以在这里找到:<br/>http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Version - jjanczyszyn
对于(包括列表)的含义,有没有关于如何列出用户被允许获取的存储桶的任何想法?到目前为止(根据所有其他答案),似乎AWS不允许这样做。 - MaximeBernard

3
我发现了如下解决方案:
AWS FLOW:
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
          ]
        }
      }
    }
  ]
}

使用示例: 查询IAM用户信息

aws iam get-user --user-name USER-NAME --profile=ExampleProfile

使用示例: 查询IAM角色信息

aws iam get-role --role-name ROLE-NAME --profile=ExampleProfile

来源: https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/

P.S. 注意 S3 存储桶权限控制,未经授权可能无法访问。


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接