【问题标题】:S3: make a public folder private again?S3:再次将公用文件夹设为私有?
【发布时间】:2012-03-03 13:30:16
【问题描述】:

如何再次将 AWS S3 公用文件夹设为私有?

我正在测试一些暂存数据,因此我在存储桶中公开了整个文件夹。我想再次限制它的访问。那么如何再次将文件夹设为私有?

【问题讨论】:

  • 您可以通过管理控制台或编程 API 来执行此操作
  • 这是我的想法,但我似乎无法在控制台中找到该选项。必须使用 api 来做一些看似重要的事情,这似乎很荒谬。
  • 确实,控制台只允许您逐个文件删除授权。有关如何在 Python 中执行此操作,请参阅我的详细答案。

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


【解决方案1】:

接受的答案效果很好 - 似乎也在给定的 s3 路径上递归地设置 ACL。但是,这也可以通过名为 s3cmd 的第三方工具更轻松地完成 - 我们在我的公司大量使用它,它似乎在 AWS 社区中相当流行。

例如,假设您有这种 s3 存储桶和目录结构:s3://mybucket.com/topleveldir/scripts/bootstrap/tmp/。现在假设您已使用 Amazon S3 控制台将整个 scripts“目录”标记为公开。

现在再次以递归方式将整个scripts“目录树”(即包括子目录及其文件)设为私有:

s3cmd setacl --acl-private --recursive s3://mybucket.com/topleveldir/scripts/

如果您愿意,也可以很容易地再次递归公开scripts“目录树”:

s3cmd setacl --acl-public --recursive s3://mybucket.com/topleveldir/scripts/

您还可以选择仅在给定的 s3“目录”(即非递归)上设置权限/ACL,只需在上述命令中省略 --recursive

要使 s3cmd 正常工作,您首先必须通过 s3cmd --configure 向 s3cmd 提供您的 AWS 访问和密钥(有关详细信息,请参阅 http://s3tools.org/s3cmd)。

【讨论】:

  • 我正在使用 s3cmd 1.6.1,如果您已经在文件夹中设置了“私有”,则此建议将不起作用。在我们的例子中,我们有公共和私有,并通过 s3cmd 设置为私有,不会删除“公共”。在这里为其他用户留言。这是 --verbose 的输出 - “已经是私有的,正在跳过”
  • 使用像 s3cmd --access_key $AWS_ACCESS_KEY_ID --secret_key $AWS_SECRET_ACCESS_KEY setacl --acl-private -r s3://$S3_BUCKET_NAME/*.map 这样的正则表达式会怎样?
  • 这个工具很棒。感谢您分享您的知识
【解决方案2】:

据我了解,管理控制台中的“公开”选项会递归地为“目录”中的每个对象添加公共授权。 您可以通过右键单击一个文件来查看此内容,然后单击“属性”。然后你需要点击“权限”,应该有一行:

 Grantee:  Everyone  [x] open/download  [] view permissions   [] edit permission.

如果您在此目录中上传新文件,则该文件不会设置此公共访问权限,因此是私有的。

您需要一一删除公共读取权限,如果您只有几个密钥,则可以手动删除,也可以使用脚本删除。

我在 Python 中使用“boto”模块编写了一个小脚本,以递归地删除 S3 文件夹中所有键的“公共读取”属性:

#!/usr/bin/env python
#remove public read right for all keys within a directory

#usage: remove_public.py bucketName folderName

import sys
import boto3

BUCKET = sys.argv[1]
PATH = sys.argv[2]
s3client = boto3.client("s3")
paginator = s3client.get_paginator('list_objects_v2')
page_iterator = paginator.paginate(Bucket=BUCKET, Prefix=PATH)
for page in page_iterator:
    keys = page['Contents']
    for k in keys:
        response = s3client.put_object_acl(
                        ACL='private',
                        Bucket=BUCKET,
                        Key=k['Key']
                    )

我在一个包含(仅)2 个对象的文件夹中对其进行了测试,并且成功了。如果您有很多键,则可能需要一些时间才能完成,并且可能需要采用并行方法。

【讨论】:

  • 你已经回答了我的问题,所以我接受了你的回答。然而,这对亚马逊来说很糟糕。我们必须编写脚本才能再次将事情私有化?太可怕了。 ascobol,谢谢你的帮助
  • aws 已经提供了另一种解决方案,请查看aws.amazon.com/blogs/aws/…
【解决方案3】:

对于 AWS CLI,它相当简单。

如果对象是:s3://<bucket-name>/file.txt

对于单个对象:

aws s3api put-object-acl --acl private --bucket <bucket-name> --key file.txt

对于桶中的所有对象(bash one-liner):

aws s3 ls --recursive s3://<bucket-name> | cut -d' ' -f5- | awk '{print $NF}' | while read line; do
    echo "$line"
    aws s3api put-object-acl --acl private --bucket <bucket-name> --key "$line"
done

【讨论】:

  • 你的回答很好,但我有点错过了每个工具在脚本中的作用的解释,这样人们就不会盲目地执行它。此外,其中包含空格的文件名存在问题。我已经发布了一个带有以下更改的新答案,但所有功劳仍归您所有:)
【解决方案4】:

在 AWS S3 存储桶列表(AWS S3 UI)中,您可以在手动任一公开一个文件后修改单个文件的权限> 通过公开整个文件夹内容(为了澄清,我指的是存储桶内的文件夹)。要将公共属性恢复为私有,请单击文件,然后转到权限并单击“每个人”标题下的径向按钮。您将获得第二个浮动窗口,您可以在其中取消选中 *read object" 属性。不要忘记保存更改。如果您尝试访问该链接,您应该会收到典型的“Access Denied”消息。我附上了两个屏幕截图. 第一个显示文件夹列表。单击文件并按照上述过程应该会显示第二个屏幕截图,其中显示了 4 个步骤。请注意,要修改多个文件,需要使用以前帖子中建议的脚本。 -Kf


【讨论】:

    【解决方案5】:

    我实际上是按照本指南使用了亚马逊的 UI http://aws.amazon.com/articles/5050/

    【讨论】:

    • 说明 @aws.amazon.com/articles/5050 似乎已经过时了......从 2011 年开始。我没有进入存储桶上“属性”的选项。 Python 脚本可能是现在唯一的方法 :(
    • 我能够以非直观的方式获得权限。我浏览到包含我关心的对象的文件夹并选中其名称旁边的复选框。这导致一个弹出框从右侧滑入。在此页面上有一个名为“权限”的部分。我注意到该名称是一个链接,当我单击它时,我进入了该对象的“权限”选项卡。
    【解决方案6】:

    虽然@Varun Chandak 的回答效果很好,但值得一提的是,由于awk 部分,该脚本仅占ls 结果的最后一部分。如果文件名中包含空格,awk 将仅获取文件名的最后一段以空格分隔,而不是整个文件名。

    示例:具有类似folder1/subfolder1/this is my file.txt 的路径的文件会产生一个名为file.txt 的条目。

    为了防止在仍然使用他的脚本时出现这种情况,您必须将 awk {print $NF} 中的 $NF 替换为一系列变量占位符,这些占位符说明“按空格分割”操作将导致的段数in. 由于文件名的名称中可能包含大量空格,因此我夸大其词,但老实说,我认为一种全新的方法可能会更好地处理这些情况。这是更新后的代码:

    #!/bin/sh
    aws s3 ls --recursive s3://my-bucket-name | awk '{print $4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25}' | while read line; do
        echo "$line"
        aws s3api put-object-acl --acl private --bucket my-bucket-name --key "$line"
    done
    

    我还应该提到,使用cut 对我没有任何结果,所以我删除了它。归功于 @Varun Chandak,因为他编写了脚本。

    【讨论】:

      【解决方案7】:

      到目前为止,根据boto docs你可以这样做

      #!/usr/bin/env python
      #remove public read right for all keys within a directory
      
      #usage: remove_public.py bucketName folderName
      
      import sys
      import boto
      
      bucketname = sys.argv[1]
      dirname = sys.argv[2]
      s3 = boto.connect_s3()
      bucket = s3.get_bucket(bucketname)
      
      keys = bucket.list(dirname)
      
      for k in keys:
          # options are 'private', 'public-read'
          # 'public-read-write', 'authenticated-read'
          k.set_acl('private') 
      

      另外,您可以考虑删除 s3 存储桶权限选项卡下的所有存储桶策略。

      【讨论】:

        【解决方案8】:

        我今天做了这个。我的情况是我有某些顶级目录,其文件需要设为私有。我确实有一些需要公开的文件夹。

        我决定像许多其他人已经展示的那样使用s3cmd。但是考虑到大量文件,我想为每个目录运行并行的s3cmd 作业。由于这需要一天左右的时间,我想在 EC2 机器上将它们作为后台进程运行。

        我使用 t2.xlarge 类型设置了一台 Ubuntu 机器。在s3cmd 在微实例上出现内存不足消息失败后,我选择了 xlarge。 xlarge 可能有点矫枉过正,但这个服务器只能运行一天。

        登录服务器后,我安装并配置了s3cmd

        sudo apt-get install python-setuptools wget https://sourceforge.net/projects/s3tools/files/s3cmd/2.0.2/s3cmd-2.0.2.tar.gz/download mv download s3cmd.tar.gz tar xvfz s3cmd.tar.gz cd s3cmd-2.0.2/ python setup.py install sudo python setup.py install cd ~ s3cmd --configure

        我最初尝试使用screen,但遇到了一些问题,主要是进程从screen -r 删除,尽管运行了正确的屏幕命令,如screen -S directory_1 -d -m s3cmd setacl --acl-private --recursive --verbose s3://my_bucket/directory_1。所以我做了一些搜索,找到了nohup 命令。这是我最终得到的结果:

        nohup s3cmd setacl --acl-private --recursive --verbose s3://my_bucket/directory_1 > directory_1.out & nohup s3cmd setacl --acl-private --recursive --verbose s3://my_bucket/directory_2 > directory_2.out & nohup s3cmd setacl --acl-private --recursive --verbose s3://my_bucket/directory_3 > directory_3.out &

        如果出现多光标错误,这变得非常容易(我使用aws s3 ls s3//my_bucket 列出目录)。

        这样做您可以根据需要logout,然后重新登录并跟踪您的任何日志。您可以跟踪多个文件,例如: tail -f directory_1.out -f directory_2.out -f directory_3.out

        所以设置s3cmd,然后使用nohup,就像我演示的那样,你就可以开始了。玩得开心!

        【讨论】:

          【解决方案9】:

          亚马逊现在似乎解决了这个问题:

          选择以下复选框使存储桶及其内容再次成为私有:

          如果存储桶有公共政策,则阻止公共和跨账户访问

          https://aws.amazon.com/blogs/aws/amazon-s3-block-public-access-another-layer-of-protection-for-your-accounts-and-buckets/

          更新:以上链接已于 2019 年 8 月更新。上图中的选项不再存在。新选项如下图所示。

          【讨论】:

          • OP 的问题是关于将单个文件夹再次设为私有,而不是整个存储桶
          【解决方案10】:

          如果您有 S3 浏览器,您可以选择将其设为公开或私有。

          【讨论】:

            【解决方案11】:

            如果您想要一个令人愉快的简单单线,您可以使用AWS Powershell Tools。 AWS Powershell 工具的参考可以是found here。我们将使用Get-S3ObjectSet-S3ACL 命令行开关。

            $TargetS3Bucket = "myPrivateBucket"
            $TargetDirectory = "accidentallyPublicDir"
            $TargetRegion = "us-west-2"
            
            Set-DefaultAWSRegion $TargetRegion
            
            Get-S3Object -BucketName $TargetS3Bucket -KeyPrefix $TargetDirectory | Set-S3ACL -CannedACLName private
            

            【讨论】:

              【解决方案12】:

              有两种方法来管理这个:

              1. 阻止所有存储桶(更简单但不适用于所有用例,例如具有静态网站和 CDN 子文件夹的 s3 存储桶)-https://aws.amazon.com/blogs/aws/amazon-s3-block-public-access-another-layer-of-protection-for-your-accounts-and-buckets/
              2. 阻止访问被授予Make Public 选项的s3 存储桶中的目录,您可以在其中执行ascobol 的脚本(我只是用boto3 重写)
              #!/usr/bin/env python
              #remove public read right for all keys within a directory
              
              #usage: remove_public.py bucketName folderName
              
              import sys
              import boto3
              
              BUCKET = sys.argv[1]
              PATH = sys.argv[2]
              s3client = boto3.client("s3")
              paginator = s3client.get_paginator('list_objects_v2')
              page_iterator = paginator.paginate(Bucket=BUCKET, Prefix=PATH)
              for page in page_iterator:
                  keys = page['Contents']
                  for k in keys:
                      response = s3client.put_object_acl(
                                      ACL='private',
                                      Bucket=BUCKET,
                                      Key=k['Key']
                                  )
              

              干杯

              【讨论】:

                猜你喜欢
                • 2018-10-26
                • 2018-12-19
                • 1970-01-01
                • 2016-11-04
                • 2018-06-07
                • 2015-06-03
                • 2017-07-27
                • 2020-06-15
                • 2022-01-13
                相关资源
                最近更新 更多