通过Referer头与CloudFront限制S3文件至指定域名失败排查
问题排查与解决方案
先解决403错误
你的S3存储桶策略里有个明显的语法错误:aws: Referer中间多了空格,应该改成aws:Referer。这个错误会导致Referer条件匹配失败,S3直接拒绝CloudFront的请求,触发403。
修复后的存储桶策略如下:
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<my-bucket>/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::<cloudfront>:distribution/<cloudfront-distribution>" }, "StringLike": { "aws:Referer": "https://my-domain.com/*" } } } ] }
除了修正策略,还要确认以下配置:
- CloudFront Origin Access Control(OAC)关联正确:确保你的CloudFront分发已经绑定了OAC(替代旧的OAI),并且OAC的权限允许访问S3存储桶。
- 转发Referer头到源:在CloudFront的行为设置中,确认已将
Referer头添加到转发给S3的头列表里,否则S3拿不到Referer值,条件匹配依然失败。 - 清除CloudFront缓存:修改策略和配置后,要手动清除CloudFront的缓存,避免旧的缓存导致请求依然失败。
提高视频下载难度的其他方案
既然你只需要增加下载门槛,不需要顶级安全,推荐以下几种低成本方案:
- HLS/DASH分片加密:将视频转成HLS或DASH格式,用AES-128加密每个分片。CloudFront可以配置密钥管理服务(KMS)或者自定义密钥,播放器需要通过合法请求获取密钥才能解密播放。普通用户下载的分片是加密的,无法直接播放。
- 禁用右键保存:在网站的视频元素上添加简单的JS代码,禁用右键菜单和视频的上下文菜单,阻止普通用户直接右键保存视频(懂技术的用户可以绕开,但能挡住大部分小白)。
- 动态生成短时效签名URL:用Lambda@Edge或者你的后端服务,给每个视频请求生成带过期时间(比如10分钟)的CloudFront签名URL。即使用户拿到URL,很快就会失效,无法长期下载或分享。
- 添加视频水印:给视频添加网站专属的水印(比如logo、网址),即使被下载传播,也能标识来源,增加非法传播的成本。
- Blob URL播放:通过前端JS发起视频请求,将返回的内容转为Blob URL,再赋值给video元素。这种方式不会直接暴露真实的CloudFront/S3 URL,普通用户很难通过浏览器开发者工具直接拿到原始地址。
内容的提问来源于stack exchange,提问作者NinjaByte
相关产品推荐
相关产品推荐

