AWS CloudFront 拒绝访问 S3 存储桶

Posted

技术标签:

【中文标题】AWS CloudFront 拒绝访问 S3 存储桶【英文标题】:AWS CloudFront access denied to S3 bucket 【发布时间】:2017-07-04 06:05:07 【问题描述】:

我正在尝试设置 CloudFront 以提供托管在我的 S3 存储桶中的静态文件。我有设置分发,但在尝试浏览到 S3 存储桶内的 CSS (/CSS/stlyle.css) 文件时得到AccessDenied

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>E193C9CDF4319589</RequestId>
    <HostId>
xbU85maj87/jukYihXnADjXoa4j2AMLFx7t08vtWZ9SRVmU1Ijq6ry2RDAh4G1IGPIeZG9IbFZg=
    </HostId>
</Error>

我已将 CloudFront 分配设置为我的 S3 存储桶并创建了新的 Origin Access Identity policy,它会自动添加到 S3 存储桶中:


    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        
            "Sid": "1",
            "Effect": "Allow",
            "Principal": 
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21XQ8NAGWMBQQ"
            ,
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::myhost.com.cdn/*"
        
    ]

我错过了什么吗?

我希望通过 CloudFront 提供此 S3 存储桶中的所有文件...

*** 更新 ***

这个云锋guide 说:

默认情况下,您的 Amazon S3 存储桶和其中的所有对象都是私有的——只有创建存储桶的 AWS 账户有权读取或写入其中的对象。如果您想允许任何人使用 CloudFront URL 访问您的 Amazon S3 存储桶中的对象,您必须授予对象的公共读取权限。 (这是使用 CloudFront 和 Amazon S3 时最常见的错误之一。您必须明确授予 Amazon S3 存储桶中的每个对象的权限。)

因此,基于此,我已将 S3 存储桶内的所有对象的新权限添加到 Everyone Read/Download。现在我可以访问文件了。

但是现在当我访问像 https://d3u61axijg36on.cloudfront.net/css/style.css 这样的文件时,它被重定向到 S3 URI 和 HTTP。如何禁用此功能?

【问题讨论】:

重定向可能是临时的forums.aws.amazon.com/message.jspa?messageID=677452 我自己也遇到过这个话题。还在等着看是不是这样…… 【参考方案1】:

为了帮助您解决问题,我通过以下方式重现了这种情况:

创建了一个没有存储桶策略的 Amazon S3 存储桶 已上传 public.jpg 并通过“公开”公开 已上传 private.jpg 并将其保密 创建了一个 Amazon CloudFront Web 分配源域名:从列表中选择了我的 S3 存储桶 限制存储桶访问:原始访问身份:创建新身份 授予对存储桶的读取权限:是,更新存储桶政策

我检查了存储桶,CloudFront 添加了与您类似的存储桶策略。

分发被标记为In Progress 一段时间。一旦它显示Enabled,我就通过xxx.cloudfront.net URL 访问了这些文件:

xxx.cloudfront.net/public.jpg 重定向我到 S3 URL http://bucketname.s3.amazonaws.com/public.jpg。是的,我可以看到该文件,但它不应使用重定向。 xxx.cloudfront.net/private.jpg重定向我,但后来我收到了Access Denied,因为它是 S3 中的私人文件。

然后我做了一些research 并发现这是很常见的情况。有些人通过将他们的 CloudFront 分配指向 静态托管网站 URL 来使用解决方法,但这有一个缺点,即它不适用于原始访问身份,我也怀疑它不会收到'免费 S3 流量到边缘的折扣。

所以,我等了一夜,今天早上测试了它,一切正常

底线:即使上面写着ENABLED,事情也可能需要几个小时(例如一夜之间)才能恢复正常。然后它将按文档说明工作。

【讨论】:

我也有同样的经历。感谢您与我们分享这一点。 对我来说不明显的是,云端 url 不包含存储桶名称。即 'xxxx.cloudfront.net/:path' 而不是 'xxxx.cloudfront.net/bucketname/:path' 如果我可以投票两次,我会的。这些东西花了我几个小时的时间。 @john-rotenstein 我没有听从你的回答。如果我将存储桶中的对象设为公开,我可以通过我的 CloudFront 分配 URL 访问它们。那太棒了!但我也可以通过 S3 URL 直接访问它们。我实现了一个 OAI,因此只有我的 CloudFront 分布可以读取我的对象,而其他人不能。如果我的对象是公开的,我不明白它的用途。我误解了你的回答吗?我可以提供更多信息来澄清我的问题吗? 如果您看到 cloudfront 将您重定向到 s3 资产(进入 cloudfront 域后检查您的 url),那么这(等待几个小时)很可能是解决方案。【参考方案2】:

在我的例子中,我在我的 S3 存储桶中使用了具有“路径模式”行为的多个来源以及一个来源路径:

错误设置:

CloudFront 行为: /images/* -> My-S3-origin

My-S3-起源: 来源路径:/images

S3 文件: /images/my-image.jpg

GET 请求: /images/my-image.jpg -> 403

发生的情况是整个 CloudFront GET 请求被发送到源:/image/my-image.jpg,前缀为源路径:/images,因此对 S3 的请求看起来像不存在的 /images/images/my-image.jpg

解决方案

删除原始路径。

【讨论】:

【参考方案3】:

我在 cloudFront Distribution Settings 的常规选项卡下的 Default Root Object 中添加了 index.html,它对我有用。 因为 index.html 是我项目的根文件!

【讨论】:

祝福你。我正在为此拉头发,并添加根对象来修复它! 这是检查 S3 存储桶端点是否使用 API 样式的东西。即使它说“拒绝访问”,它也不是真正的权限错误 - 这是您要求的资源在技术上不存在。 确保它是index.html 而不是/index.html 这些东西一直在建议我“放下所有这些东西去种地”。 哇,救命稻草。并确保耐心等待。事情传播或任何需要发生的事情需要大约 30 秒才能工作(这就是为什么我最初认为设置这个“可选”字段不是一个修复),但是是的,告诉它 index.html 是默认根对象为我修复了它。【参考方案4】:

源域名不要选择默认的 s3 存储桶,请输入 &lt;bucket-name&gt;.s3-website.&lt;region&gt;.amazonaws.com 作为源域名(您可以在 S3 存储桶属性下的静态网站托管属性中获取此 URL)。 p>

【讨论】:

【参考方案5】:

如果您使用的是刚刚创建的存储桶,则可能会发生这种情况。

根据这里的官方回复:AWS Forun link,您必须在创建新存储桶后等待几个小时才能让云前端分发正常工作。

解决方案是暂时从您的一个旧存储桶工作,并在几个小时后切换到新存储桶。

【讨论】:

【参考方案6】:

我也从 CloudFront 获得了 403,但我的问题有点不同,所以在这里分享它可能会帮助其他人。

确保您在存储桶策略中定义的 Origin Access Id 是正确的:


    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        
            "Sid": "1",
            "Effect": "Allow",
            "Principal": 
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity HERE_GOES_YOUR_ORIGIN_ACCESS_ID"
            ,
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::deepen-frontend-prod/*"
        
    ]

Origin Access Identity Id 大致类似于 E19F48VV5H01ZD。

您可以在https://console.aws.amazon.com/cloudfront/home#oai 上找到您所有的原始访问身份 在 Your Identities 下查找您在 CloudFront 配置中使用的那个:

【讨论】:

【参考方案7】:

将此添加到存储桶策略中

    
        "Sid": "2",
        "Effect": "Allow",
        "Principal": 
            "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ESDK2T2CSNT57"
        ,
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::Bucket name /*"
    

【讨论】:

【参考方案8】:

将 S3 存储桶中的对象设为公开读取是实现此目的的最快方法。但是,不建议这样做。而是在 s3 源策略下创建 origin_access_identity 并使用存储桶策略授予此身份对 S3 存储桶的访问权限。这样您就可以将所有对象保密。

【讨论】:

以上是关于AWS CloudFront 拒绝访问 S3 存储桶的主要内容,如果未能解决你的问题,请参考以下文章

Cloudfront 提供通过 AWS CDK Python 为 S3 存储桶来源创建的访问被拒绝响应,无需公共访问

AWS S3+Cloudfront 访问被拒绝初学者问题

AWS CloudFront 签名 URL 的访问被拒绝

带有签名 URL 的 AWS CloudFront:403 访问被拒绝

Cloudfront 访问被拒绝

Amazon Cloudfront 签名 URL 访问被拒绝问题