我正在使用视频应用程序并将文件存储在AWS S3上,使用默认URL https://***.amazonaws.com/***
工作正常,但我决定使用CloudFront,这对内容交付更快。
使用CF,我一直在努力 403 (Forbidden)
使用此网址 https://***.cloudfront.net/***
。我错过了什么吗?
一切正常,直到我决定从CloudFront加载指向我的存储桶的内容。
有解决方案吗?
我正在使用视频应用程序并将文件存储在AWS S3上,使用默认URL https://***.amazonaws.com/***
工作正常,但我决定使用CloudFront,这对内容交付更快。
使用CF,我一直在努力 403 (Forbidden)
使用此网址 https://***.cloudfront.net/***
。我错过了什么吗?
一切正常,直到我决定从CloudFront加载指向我的存储桶的内容。
有解决方案吗?
使用检查传入的存储桶策略限制对S3内容的访问时 Referer:
标题,你需要做一些自定义配置来“智取”CloudFront。
重要的是要了解CloudFront旨在成为一个行为良好的缓存。通过“乖巧”,我的意思是CloudFront旨在永远不会返回与原始服务器返回的响应不同的响应。我相信你可以看到这是一个重要因素。
假设我在CloudFront后面有一个Web服务器(而不是S3),我的网站设计为根据检查结果返回不同的内容 Referer:
header ...或任何其他http请求标头,例如 User-Agent:
例如。根据您的浏览器,我可能会返回不同的内容。 CloudFront如何知道这一点,以避免为用户提供某个页面的错误版本?
答案是,它无法分辨 - 它无法知道这一点。因此,CloudFront的解决方案根本不是将大多数请求标头转发到我的服务器。我的Web服务器无法看到它,它无法做出反应,因此我返回的内容不会因我没有收到的标头而有所不同,这会阻止CloudFront缓存并根据这些标头返回错误的响应。 Web缓存有义务避免为给定页面返回错误的缓存内容。
“但是等等,”你反对。 “我的网站取决于某个标题的值,以确定如何回应。”是的,这很有道理......所以我们必须告诉CloudFront:
我没有根据请求的路径缓存我的页面,而是需要你转发 Referer:
要么 User-Agent:
或浏览器发送的其他几个标题之一, 并缓存响应以用于其他请求,这些请求不仅包括相同的路径,还包含您转发给我的额外标头的相同值。
但是,当源服务器是S3时,CloudFront不支持转发大多数请求标头,假设由于静态内容不太可能发生变化,这些标头只会导致它不必要地缓存多个相同的响应。
您的解决方案不是告诉CloudFront您使用S3作为原点。而是将您的发行版配置为使用“自定义”源,并为其指定要用作源服务器主机名的存储区的主机名。
然后,您可以配置CloudFront以转发 Referer:
标头到源,并且基于该标头拒绝/允许请求的S3存储桶策略将按预期工作。
好吧,几乎和预期的一样。这会稍微降低缓存命中率,因为现在缓存页面将根据路径+引用页面进行缓存。如果一个S3对象被多个站点的页面引用,CloudFront将为每个唯一请求缓存一个副本。这听起来像是一个限制,但实际上,它只是一个正确缓存行为的工件 - 无论转发到后端的几乎全部,都必须用于确定该特定响应是否可用于为将来的请求提供服务。
看到 http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesForwardHeaders 用于将CloudFront配置为将特定标头列入白名单以发送到源服务器。
重要提示:请勿转发任何不需要的标头,因为每个变体请求都会进一步降低您的命中率。特别是当使用S3作为自定义原点的后端时,请不要转发 Host:
标题,因为这可能不会达到您的预期。选择 Referer:
标题在这里,并测试。 S3应该开始看到标题并做出相应的反应。
请注意,当您删除存储桶策略以进行测试时,除非您通过发送无效请求来刷新缓存,否则CloudFront将继续提供缓存错误页面,这会导致CloudFront清除所有与您指定的路径模式匹配的缓存页面约15分钟。在试验时最简单的方法是使用新配置创建新的CloudFront分配,因为分发本身不收取任何费用。
从CloudFront查看响应标头时,请注意 X-Cache:
(命中/错过)和 Age:
(多久以前这个特定的页面被缓存)响应。这些在故障排除中也很有用。
更新: @alexjs 已经做了一个重要的观察:而不是使用桶策略并转发 Referer:
标题为S3进行分析 - 这会影响您的缓存比率,其范围随着资源在引用页面上的传播而变化 - 您可以使用新的AWS Web应用程序防火墙服务,该服务允许您对传入的请求实施过滤规则CloudFront,允许或阻止基于的请求 请求标头中的字符串匹配。
为此,您需要将分发连接到S3,如S3源(正常配置,与我提出的相反,在上面的解决方案中,使用“自定义”原点)并使用CloudFront的内置功能验证对S3的后端请求(因此如果恶意行为者直接向S3请求,则不能直接访问存储桶内容)。
看到 https://www.alexjs.eu/preventing-hotlinking-using-cloudfront-waf-and-referer-checking/ 有关此选项的更多信息。
此外,它可能是简单的事情。当您首次将文件上载到S3存储桶时,即使该存储桶中的其他文件是公共的,即使存储桶本身是公共的,它也是非公开的。
要在AWS控制台中更改此项,请选中要公开的文件夹旁边的框(刚刚上传的文件夹),然后从菜单中选择“公开”。
该文件夹(和任何子文件夹)中的文件将公开,您将能够从S3提供文件。
对于AWS CLI,在命令中添加“--acl public-read”选项,如下所示:
aws s3 cp index.html s3://your.remote.bucket --acl public-read