0

假设我正在构建一个 Dropbox 克隆:Filebox。我使用 S3 存储所有用户的文件,并且使用 Cloudfront 作为我的 CDN。

因此,我有一个受限制的 S3 存储桶 ( files.filebox.com),其存储桶策略s3:GetObject允许我通过 Cloudfront 创建的源访问身份。这会强制所有“文件”请求通过 Cloudfront,并禁止任何人通过 S3 URL 访问文件。


files.filebox.com 的存储桶策略

{
    "Version": "2008-10-17",
    "Id": "AllowCloudfrontGet",
    "Statement": [
        {
            "Sid": "AllowCloudFrontGet",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::files.filebox.com/*"
        }
    ]
}


意外的行为

假设,为简单起见,我将所有文件都存储为public-read.

所以这个 URL 应该可以工作:
https://files.filebox.com/<userID>/some-file.txt

但这应该导致 403: https://s3.amazonaws.com/files.filebox.com/<userID>/some-file.txt

但我看到了相反的结果。S3 URL 工作正常,但files.filebox.com通过 Cloudfront 的 URL 引发MissingKey错误。

files.filebox.comURL确实有效,但前提是我签署了该 URL,即使对于具有 ACL 的对象也是如此public-read


问题

鉴于存储桶策略仅允许s3:GetObjectCF OAI,即使对象具有public-readACL,S3 URL 是否不应该失败并显示 403?
除了模糊的语言之外,我在文档中找不到任何关于此的信息,这似乎表明对于未通过 Cloudfront进行的任何请求,受限存储桶应为 403。

当我将对象的 ACL 设置public-read为时,即使在受限制的存储桶上,是否也不需要签署 Cloudfront URL?

我是否需要在Statement我的存储桶策略中添加另一个允许未签名 URL 访问public-read对象的策略?
我尝试了这个,但没有奏效。我Statement什至不知道如何写这样的......

如何真正拒绝通过 S3 URL 发出的任何请求?
我想为通过 S3 URL 的任何请求抛出 403,即使是 ACL 为public-read.

4

1 回答 1

2

鉴于存储桶策略仅允许 s3:GetObject 用于 CF OAI,即使对象具有公共读取 ACL,S3 URL 是否不应该失败并显示 403?

No. public-read表示允许直接从 S3 进行公共(未经身份验证)读取。由于存储桶拥有者允许使用public-readACL 上传对象,因此对象在存储桶拥有者的默示同意下是公开的,即使根本没有存储桶策略。

对象 ACL 和存储桶策略Allow选项是相加的。如果您不希望通过 S3 端点访问该对象,请不要将其公开。

当我将对象的 ACL 设置为公共读取时,即使在受限制的存储桶上,是否也不需要签署 Cloudfront URL?

不,它没有。CloudFront 不评估对象 ACL。它根据缓存行为设置决定是否需要身份验证。如果配置为要求对给定路径模式进行身份验证,则无论 CloudFront 背后的实体是 S3 还是其他实体,都需要身份验证。如果 CloudFront 拒绝访问,则甚至不会向 S3 发送任何请求。

我是否需要在我的存储桶策略中添加另一个允许未签名 URL 访问公共读取对象的语句?

不会。存储桶策略中的任何内容都不会修改 CloudFront 前端身份验证的行为。

典型的方法是将某些前缀指定为公共前缀,而将其他前缀指定为非公共前缀,并使用适当的匹配路径模式配置 CloudFront 缓存行为,因此例如/public/*可能配置为不需要签名 URL,但/private/*可能需要它们。

此设置称为Restrict Viewer Access,并设置在缓存行为级别(因此在路径模式级别)。

我想为通过 S3 URL 的任何请求抛出 403,即使对于具有公共读取 ACL 的对象也是如此。

根据定义,将对象 ACL 设置为public-read意味着该对象应该可以直接从 S3 存储桶端点访问而无需凭据。不多也不少。

从这个角度来看,你所说的类似于说“我想防止有人偷我的车,即使我打算把钥匙留在点火装置中。” 它可以完成,但它解决了错误的问题......它很快变得复杂,因为你必须诉诸诸如条件之类的策略DenyNotPrincipal不仅包括 CloudFront 的例外,而且还包括你自己在控制台中的例外以及您访问存储桶的应用程序、角色等。

源访问身份的意义在于,CloudFront 拥有一组可在向存储桶发送请求时使用的凭据,无论 CloudFront 是否要求用户提供身份验证凭据。有了 OAI,就没有理由public-read在对象 ACL 上使用。

于 2017-10-25T02:34:56.970 回答