亚马逊S3文件权限,从另一个账户复制时出现访问被拒绝的情况。

19
我有一组视频文件,是从另一个AWS Bucket中的另一个帐户复制到我的帐户中的自己的存储桶。现在我遇到了一个问题,所有文件都会出现“访问被拒绝”的错误,当我试图将所有文件设置为公共访问时。
具体来说,我登录到我的AWS帐户,进入S3,通过文件夹结构定位到其中一个视频文件。
当我查看这个特定文件时,文件的权限选项卡上没有显示任何分配给任何人的权限。没有分配任何用户、组或系统权限。
在权限选项卡的底部,我看到一个小框,上面写着“错误:拒绝访问”。我不能更改文件的任何内容。我无法添加元数据。我无法向文件添加用户。我不能使文件公开。
有办法让我控制这些文件,以便我可以将它们设置为公开访问吗?有超过15,000个文件/约60GB的文件。我想避免下载和重新上传所有文件。
在这里的一些帮助和建议下,我尝试了以下操作。 我在我的存储桶中创建了一个名为“media”的新文件夹。
我尝试了这个命令:
aws s3 cp s3://mybucket/2014/09/17/thumb.jpg s3://mybucket/media --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers full=emailaddress=my_aws_account_email_address

当调用HeadObject操作时,我收到了一个致命的403错误:被禁止。


使用AWS CLI从命令行执行此操作:http://docs.aws.amazon.com/cli/latest/userguide/using-s3-commands.html - Shobhit Puri
我看到了“--grant”选项,但我不确定要使用什么命令?我不想复制、删除或同步它。我只想将权限应用于该文件。我认为同步是我想要做的,因为这听起来不像会移动文件或删除它。 - Robbiegod
@ShobhitPuri,你为什么认为OP会有从CLI执行该操作的权限?你需要使用AWS凭证配置CLI。如果你使用与登录AWS控制台相同的凭证,很可能会遇到相同的权限问题。 - Viccari
1
我注意到文件的“所有者”仍然是我从中获取这些文件的帐户。我该如何覆盖它?这可能吗? - Robbiegod
@Viccari 你是对的。我更关注于他想要更改权限的60 GB文件,但又不想重新上传。那么就有两个问题。一个是权限问题,另一个是使用CLI可以避免他手动处理所有文件。 - Shobhit Puri
7个回答

37

一个非常有趣的难题!幸运的是,有解决方法。

首先,简要回顾一下:

  • Bucket A 在 Account A 中
  • Bucket B 在 Account B 中
  • 用户在 Account A 中将对象复制到 Bucket B(已被授予相应的权限)
  • Bucket B 中的对象仍属于 Account A,不能被 Account B 访问

我设法重现了这个问题,并确认 Account B 中的用户无法访问该文件 - 甚至是 Account B 中的 root 用户也不行!

幸运的是,事情可以被修复。通过AWS 命令行界面 (CLI)中的 aws s3 cp 命令,可以在复制到相同名称的文件时更新文件的权限。但是,为了触发此操作,您还必须更新其他内容,否则会出现以下错误:

此复制请求是非法的,因为它试图在不更改对象的元数据、存储类、网站重定向位置或加密属性的情况下将对象复制到自身。

因此,使用以下命令可以更新权限:

aws s3 cp s3://my-bucket/ s3://my-bucket/ --recursive --acl bucket-owner-full-control --metadata "One=Two"
  • 必须由 Account A 用户运行,该用户具有访问对象的权限(例如最初将对象复制到 Bucket B 的用户)
  • 元数据内容不重要,但需要强制更新
  • --acl bucket-owner-full-control 将授予 Account B 权限,因此您将能够像正常使用对象一样使用它们

最终结果:一个可以使用的存储桶!


如果帐户 A 更改上传到存储桶 B 的文件的权限时出现访问被拒绝错误,那么这是帐户 A、帐户 B 还是存储桶 B 的权限错误? - Phlucious
@Phlucious 权限将在拥有资源 (在本例中是 Bucket B) 的帐户中。 以后请创建一个新的问题,而不是在评论中提出不同的问题。 - John Rotenstein
谢谢!这篇回答非常相关,因为我能够将其调整为在新的上传中授予账户B完全控制权。搜索相关信息时我找到了这里。 - Phlucious
1
我刚试了一下,发现解决方案不需要“--metadata”。 “--acl bucket-owner-full-control”就足够了。 - Imma
2
如果意图更改已存在对象的权限,则--metadata部分是必需的,否则cp命令会失败,因为没有任何东西被“更改”。如果正在复制新对象(或从不同位置复制),则不需要--metadata - John Rotenstein
显示剩余5条评论

3
aws s3 cp s3://account1/ s3://accountb/ --recursive --acl bucket-owner-full-control 

2
为了正确设置新添加文件的适当权限,请添加此存储桶策略:
[...]
{
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::123456789012::user/their-user"
    },
    "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl"
    ],
    "Resource": "arn:aws:s3:::my-bucket/*"
}

在代码中为新创建的文件设置ACL。Python示例:
import boto3

client = boto3.client('s3')
local_file_path = '/home/me/data.csv'
bucket_name = 'my-bucket'
bucket_file_path = 'exports/data.csv'
client.upload_file(
    local_file_path,
    bucket_name, 
    bucket_file_path, 
    ExtraArgs={'ACL':'bucket-owner-full-control'}
)

来源:https://medium.com/artificial-industry/how-to-download-files-that-others-put-in-your-aws-s3-bucket-2269e20ed041(免责声明:本文为我撰写)

1
通过添加 --acl bucket-owner-full-control,它可以正常工作。

你能提供更多的细节吗?你把那放在哪里了? - Robbiegod
请将其放在您的aws s3 <参数>之后,然后使用上述内容。 - Barath Ravichander

1

如果有人想使用Hadoop/Spark作业而不是AWS CLI来执行相同的操作,请注意以下步骤。

  • 步骤1:授予帐户A中的用户适当的权限,以将对象复制到Bucket B中。(如上所述)
  • 步骤2:使用Hadoop Configuration设置fs.s3a.acl.default配置选项。可以在conf文件中或程序中设置:

    Conf文件:

    <property> <name>fs.s3a.acl.default</name> <description>为新创建和复制的对象设置预定义ACL。值可以是Private、PublicRead、PublicReadWrite、AuthenticatedRead、LogDeliveryWrite、BucketOwnerRead或BucketOwnerFullControl。</description> <value>$chooseOneFromDescription</value> </property>

    编程方式:

    spark.sparkContext.hadoopConfiguration.set("fs.s3a.acl.default", "BucketOwnerFullControl")


0

很抱歉,您无法按照您的意愿转移所有权。以下是您所做的事情:

旧账户将对象复制到新账户。

正确的做法(假设您想在新账户上拥有所有权)应该是:

新账户从旧账户复制对象。

看到这个微小但重要的区别了吗?S3文档解释得比较清楚。

我认为您可以通过在同一个存储桶中复制所有文件,然后删除旧文件来避免下载整个文件的需要。确保在复制后可以更改权限。这样可以节省一些费用,因为您不必支付下载所有数据的数据传输费用。


是的,我明白了。谢谢你。我无法获得其他账户存储桶的“bucket”访问权限,所以我们不得不尝试这种方式。我会尝试你建议的方法。 - Robbiegod
我尝试使用Cloudberry下载图像,但是它也无法工作。我收到了403错误,即访问被拒绝。我在CLI中尝试了cp命令,但是我仍然遇到了403错误。现在不确定我的选择是什么。 :( - Robbiegod
我认为您应该能够在AWS控制台上复制/粘贴您的文件。如果您无法从该存储桶下载文件,则看起来您甚至没有GetObject权限,只有ListBucket权限。这实际上是有道理的,因为GetObject是对象权限,而ListBucket是存储桶权限,并且您拥有存储桶,但不拥有文件。如果您可以确认这一点,您将需要请求其他AWS帐户的所有者重新复制它或授予您访问权限。 - Viccari

0

boto3中的“copy_object”解决方案:

为目标存储桶所有者提供授权控制

client.copy_object(CopySource=copy_source, Bucket=target_bucket, Key=key, GrantFullControl='id=<bucket owner Canonical ID>')
  • 获取控制台
  • 选择存储桶,权限选项卡,“访问控制列表”选项卡

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