amazon-web-services - 使用 S3 和 CloudFront 防止图像盗链
问题描述
我有一个包含许多页面的网站,其中每个页面都有许多图像(数十个甚至数百个)。
我试图避免图像盗链,但不会过多增加 AWS 成本。
到目前为止,我找到了 3 个选项:
选项 1:使用 WAF 来防止盗链,通过创建基于 referer 标头的阻止规则。
这个解决方案的问题是,如果你在每个页面上加载了很多图片,成本会增加太多,因为除了支付 S3 和 CloudFront 之外,你还需要为每个图片请求支付 WAF(想象一下如果你有 100 张图片例如,在每一页上)。
选项 2:将 CloudFront 配置为触发 Lambda@Edge 查看器请求触发器,该触发器将检查进入前门的每个请求,并根据引用标头阻止请求。
https://stackoverflow.com/a/46044606/2444386
这类似于上面的选项。问题是您为每个请求添加了开销,即使图像已经在 CloudFront 缓存中。Lambda@Edge 将始终被调用,并且如果您网站的每个页面上有很多图像,也会增加太多的成本。
选项 3:配置 S3 存储桶策略以阻止基于 referer 标头的请求,并在 CloudFront 将 referer 标头列入白名单。
到目前为止,在我看来,这似乎是成本效益最高的选项,因为如果图像已经在 CloudFront 缓存中,您就没有任何开销,而且成本也是最便宜的,因为您不需要支付 WAF 或Lambda@Edge。
问题是缓存命中率会小得多,因为 CloudFront 不会从缓存中提供响应,除非传入请求的 Referer 标头与已缓存请求中的标头完全匹配。
我尝试使用“原始”请求标头来避免此问题,但似乎浏览器不会为图像 GET 请求发送此标头。
有更好的选择吗?
解决方案
我最终使用了选项 3(S3 存储桶策略)并另外使用了CloudFlare的免费计划。CloudFlare 即使在免费计划中也有“刮盾”中的“热链接保护”。
防止盗链的 S3 存储桶策略:
{
"Version": "2012-10-17",
"Id": "http referer policy",
"Statement": [
{
"Sid": "Allow access only from my website",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::resources.mywebsite.com/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://dev.mywebsite.com:8080/*",
"https://staging.mywebsite.com/*",
"https://www.mywebsite.com/*"
]
}
}
}
]
}
在 CloudFront 中,我将 Referer 标头列入白名单:
在 CloudFlare 中,您可以在“Scrape Shield”菜单中启用“Hotlink Protection”选项:
推荐阅读
- google-cloud-storage - 压缩/压缩谷歌云存储上的多个文件,无需下载
- amazon-web-services - 如何在同一子网范围内的 ec2 实例中分配/生成新的 IP 地址?
- jersey-2.0 - jersey 客户端失败,ClientResponse 状态为 400
- sublimetext3 - Sublime Text 3 中的新建筑系统
- javascript - 如果 html 数据为空,我想隐藏 div,如果不是,我想显示。HTML JavaScript
- php - Laravel 属性 [title] 在 Eloquent 构建器实例上不存在
- node.js - 如何在快速路线中显示而不是下载 pdf 文件
- salesforce - 使用 Salesforce Community 中的超链接公式在同一窗口中打开外部 URL
- javascript - 部分看起来比预期的要小
- ansible - Ansible 的集成级别:角色和剧本之间