【问题标题】:How can I enable an ec2 instance to have private access to an S3 bucket?如何让 ec2 实例拥有对 S3 存储桶的私有访问权限?
【发布时间】:2020-04-14 04:49:07
【问题描述】:

首先我知道这些问题:

但解决方案对我不起作用。

我创建了一个角色“sample_role”,将AmazonS3FullAccess-policy 附加到它,并将该角色分配给了ec2-instance。

我的bucket-policy如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::My-Account-ID:role/sample_role"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::my_bucket/*"
        }
    ]
}

在我的 ec2 实例上,从命令行 (aws s3 ls) 和 python 脚本列出我的存储桶都可以正常工作。 但是当我尝试上传文件 test.txt 到我的存储桶时,我得到了AccessDenied

import boto3

s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
bucket = s3_resource.Bucket('my_bucket')

with open('test.txt', "rb") as f:
    s3_client.upload_fileobj(f, bucket.name, 'text.txt')

错误信息:

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

当我尝试列出存储桶中的对象时也会发生同样的情况。命令行aws s3api list-objects --my_bucket或python脚本:

import boto3

s3_resource = boto3.resource('s3')
bucket = s3_resource.Bucket('my_bucket')

for my_bucket_object in bucket.objects.all():
    print(my_bucket_object)

错误信息:

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied

当我在我的存储桶设置中关闭“阻止所有公共访问”并在我的访问控制列表中启用公共访问时,它显然有效。但我需要限制对指定角色的访问。

我错过了什么? 感谢您的帮助!

【问题讨论】:

  • s3:ListBucket 是存储桶级别的操作。它需要arn:aws:s3:::my_bucket 的资源(而不是与对象有关的arn:aws:s3:::my_bucket/*)。
  • 谢谢。所以我将my_bucket/* 添加到我的资源中,例如:"Resource": [ "arn:aws:s3:::my_bucket", "arn:aws:s3:::my_bucket/*" ],但列出对象仍然失败。这也不能解释为什么上传失败,对吧?
  • 退后一步,您想通过 S3 存储桶上的策略来实现什么目标?如果您授予 IAM 角色访问存储桶的权限,那么您也不需要在 S3 存储桶策略中允许它(通常您没有存储桶策略)。您是否尝试将对该存储桶的访问限制为特定 IAM 角色?
  • 是的,我想将存储桶的访问权限限制为在我的存储桶策略中指定的 IAM 角色,例如 "Principal": { "AWS": "arn:aws:iam::My-Account-ID:role/sample_role" }
  • aws.amazon.com/blogs/security/…有一篇关于这个话题的文章

标签: amazon-web-services amazon-s3 amazon-ec2


【解决方案1】:

看来您的要求是:

  • 您有一个 Amazon S3 存储桶 (my_bucket)
  • 您有一个附加了 IAM 角色的 Amazon EC2 实例
  • 您希望允许在该 EC2 实例上运行的应用程序访问 my_bucket
  • 您不希望存储桶可公开访问

我还将假设您不会尝试拒绝其他用户访问存储桶,如果他们已经被授予访问权限。您只是想Allow 访问 EC2 实例,而不需要 Deny 访问可能也有访问权限的其他用户/角色。

您可以通过向附加到 EC2 实例的 IAM 角色添加策略来执行此操作:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my_bucket",
                "arn:aws:s3:::my_bucket/*"
            ]
        }
    ]
}

这会将所有 Amazon S3 权限授予my_bucket 的 IAM 角色。请注意,有些命令需要对存储桶本身的权限,而其他命令需要对存储桶的内容 (/*) 的权限。

我还要提一下授予s3:* 可能过于慷慨,因为它会允许在实例上运行的应用程序删除内容,甚至删除存储桶,这可能不是您希望授予的。如果可能,将操作限制在必要的范围内。

【讨论】:

  • 这给了我Has prohibited field Principal。但是在存储桶策略中 Principal 似乎是允许的。
  • 糟糕!删除了角色(在 IAM 用户/角色策略中不需要)。
【解决方案2】:

当我在我的存储桶设置中关闭“阻止所有公共访问”并在我的访问控制列表中启用公共访问时,它显然有效。

从这句话中删除“启用公共访问”,这将是您的解决方案:-)

“阻止所有公共访问”会阻止所有公共访问,并且与您使用的存储桶策略无关。因此,取消选中此选项,您的存储桶策略将按您的计划开始工作。

【讨论】:

    【解决方案3】:

    所以我发现了问题。 我的 ec2 实例的凭据配置为使用未分配角色的开发用户帐户的访问密钥。

    我通过运行aws sts get-caller-identity 发现它返回了实际使用的身份(例如 IAM 角色)。

    所以看起来分配的角色可以被用户身份覆盖,这是有道理的。 为了解决这个问题,我简单地通过删除配置文件~/.aws/credentials来取消配置。之后身份更改为分配的角色。

    【讨论】:

      猜你喜欢
      • 2016-09-05
      • 2022-01-17
      • 1970-01-01
      • 2019-09-29
      • 2020-10-15
      • 2016-01-22
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多