Amazon S3 文件权限,从另一个帐户复制时拒绝访问

Amazon S3 File Permissions, Access Denied when copied from another account

我有一组视频文件是从另一个账户的一个 AWS 存储桶复制到我自己的存储桶中的账户。

我 运行 现在遇到了所有文件的问题,当我尝试制作所有文件 public.

时收到拒绝访问错误

具体来说,我登录到我的 AWS 帐户,进入 S3,深入了解文件夹结构以找到其中一个视频文件。

当我查看这个特定文件时,文件上的权限选项卡没有显示分配给任何人的任何权限。没有分配用户、组或系统权限。

在“权限”选项卡的底部,我看到一个小方框,上面写着 "Error: Access Denied"。我无法更改文件的任何内容。我无法添加元数据。我无法将用户添加到文件中。我无法制作文件 Public.

有什么方法可以让我获得对这些文件的控制权,以便我可以制作它们 public?有超过 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:禁止访问。

恐怕您无法如愿转让所有权。这是你所做的:

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

"right" 的实现方式(假设您想获得新帐户的所有权)是:

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

看出细微但重要的区别了吗? S3 docs 解释一下。

我认为您只需复制同一个存储桶中的所有文件,然后删除旧文件,就可以不用下载整个文件就可以摆脱它。确保您可以在复制后更改权限。这也应该为您节省一些钱,因为您不必支付下载所有内容的数据传输费用。

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

首先,回顾一下:

  • 账户 A 中的桶 A
  • 账户 B 中的存储桶 B
  • 帐户 A 中的用户将对象复制到存储桶 B(已被授予这样做的适当权限)
  • Bucket B 中的对象仍然属于账户 A,不能被账户 B 访问

我成功地重现了这个并且可以确认帐户 B 中的用户无法访问该文件——即使是帐户 B 中的根用户也不能!

幸运的是,事情是可以解决的。 AWS Command-Line Interface (CLI) 中的 aws s3 cp 命令可以在复制到同名文件时更新文件的权限。但是,要触发此操作,您还必须更新其他内容,否则会出现此错误:

This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.

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

aws s3 cp s3://my-bucket/ s3://my-bucket/ --recursive --acl bucket-owner-full-control --metadata "One=Two"
  • 必须由对对象具有访问权限的帐户 A 用户(例如,最初将对象复制到存储桶 B 的用户)运行
  • 元数据内容不重要,但需要强制更新
  • --acl bucket-owner-full-control 将向帐户 B 授予权限,这样您就可以正常使用这些对象

最终结果:一个你可以用的桶!

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

以防有人尝试做同样的事情但使用 Hadoop/Spark 作业而不是 AWS CLI。

  • 第 1 步:授予帐户 A 中的用户适当的复制权限 Bucket B 的对象。(在上面的回答中提到)
  • 第 2 步:使用 Hadoop 配置设置 fs.s3a.acl.default 配置选项。这可以在 conf 文件或程序中设置:

    配置文件:

    <property> <name>fs.s3a.acl.default</name> <description>Set a canned ACL for newly created and copied objects. Value may be Private, PublicRead, PublicReadWrite, AuthenticatedRead, LogDeliveryWrite, BucketOwnerRead, or BucketOwnerFullControl.</description> <value>$chooseOneFromDescription</value> </property>

    以编程方式:

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

要为新添加的文件正确设置适当的权限,请添加此存储桶策略:

[...]
{
    "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(免责声明:由我撰写)

通过输入

--acl bucket-owner-full-control made it to work.

boto3“copy_object”解决方案:

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

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