62

我正在开发一个 Web 应用程序,我目前已将以下 ACL 分配给它用于访问其数据的 AWS 账户:

{
  "Statement": [
    {
      "Sid": "xxxxxxxxx", // don't know if this is supposed to be confidential
      "Action": [
        "s3:*"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::cdn.crayze.com/*"
      ]
    }
  ]
}

但是,我想让这更具限制性,这样如果我们的 AWS 凭证被泄露,攻击者就无法破坏任何数据。

从文档来看,我似乎只想允许以下操作:s3:GetObjectand s3:PutObject,但我特别希望该帐户只能创建尚不存在的对象 - 即应拒绝对现有对象的 PUT 请求。这可能吗?

4

4 回答 4

55

这在Amazon S3中是不可能的,就像您想象的那样;但是,您可以通过使用版本控制来解决这个限制,这是一种将对象的多个变体保留在同一个存储桶中的方法,并且在开发时考虑了这样的用例:

您可以启用版本控制以防止对象被错误地删除或覆盖,或者存档对象以便您可以检索它们的先前版本。

还有一些相关的常见问题解答,例如:

  • 什么是版本控制?-版本控制允许您保留、检索和恢复存储在 Amazon S3 存储桶中的每个对象的每个版本。为存储桶启用版本控制后,只要您对现有对象执行 PUT、POST、COPY 或 DELETE 操作,Amazon S3 就会保留它们。默认情况下,GET 请求将检索最近写入的版本。可以通过在请求中指定版本来检索被覆盖或删除的对象的旧版本。

  • 为什么要使用版本控制?- Amazon S3 为客户提供高度耐用的存储基础设施。版本控制通过在客户意外覆盖或删除对象时提供一种恢复方式来提供额外的保护。这使您可以轻松地从意外的用户操作和应用程序故障中恢复。您还可以使用版本控制来保留和归档数据。[强调我的]

  • 版本控制如何防止我的对象被意外删除?-当用户对对象执行 DELETE 操作时,后续的默认请求将不再检索该对象。但是,该对象的所有版本将继续保留在您的 Amazon S3 存储桶中,并且可以检索或恢复。只有 Amazon S3 存储桶的所有者可以永久删除版本。[强调我的]

如果您真的非常重视存储桶所有者的 AWS 凭证(当然,他们可能与访问用户不同),您甚至可以更进一步,请参阅如何确保最大程度地保护我的保留版本?

版本控制的 MFA 删除功能使用多重身份验证,可用于提供额外的安全层。[...] 如果您在 Amazon S3 存储桶上启用带有 MFA 删除的版本控制,则需要两种形式的身份验证才能永久删除对象的版本:您的 AWS 账户凭证和来自身份验证的有效六位数代码和序列号您实际拥有的设备。[...]

于 2012-05-15T01:04:27.390 回答
6

如果这是您试图避免的意外覆盖,并且您的业务需求允许在短时间内出现不一致,您可以在 Lambda 函数中执行回滚:

  1. 制定“没有同名新对象”的政策。大多数时候它不会发生。要执行它:
  2. 在AWS Lambda 函数中侦听 S3:PutObject 事件。
  3. 触发事件时,检查是否存在多个版本。
  4. 如果存在多个版本,请删除除最新版本之外的所有版本。
  5. 通知上传者发生了什么(让原始上传者进入对象很有用x-amz-meta-*。更多信息在这里)。
于 2016-06-30T11:56:29.337 回答
5

您现在可以使用 S3 对象锁定来锁定对象的版本。它是按桶设置的,允许您放置两种 WORM 锁中的一种。

  • “保留期” - 无法更改
  • “合法保留” - 可以由存储桶所有者随时更改

https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html

正如下面@Kijana Woodard 所提到的,这不会阻止创建新版本的对象。

于 2018-12-03T19:01:09.053 回答
1

编辑:如果您从这个问题来到这里,则适用。

对象锁仅适用于版本化存储桶。如果您不能为您的存储桶启用版本控制,但可以容忍短暂的不一致,即假定文件存在,而 DELETE 仍在进行中(S3 仅最终一致)可能导致 PUT-after-DELETE 间歇性失败,如果在紧密循环中使用,或者相反,连续的 PUT 间歇性地错误地成功,则以下解决方案可能是合适的。

给定对象路径,读取对象的 Content-Length 标头(来自元数据,HeadObject请求)。仅当请求成功时写入对象,并且在适用的情况下,如果长度大于

于 2020-09-14T17:14:30.173 回答