如何搭配Cloudflare为私有S3存储桶配置预签名URL访问控制
Cloudflare + S3 仅允许预签名URL访问配置方案
整体逻辑和你之前用CloudFront的思路一致:锁死S3公网权限、边缘层拦截无合法签名的请求、回源时只透传合法签名请求,具体操作分三步:
1. 先把S3桶的公网权限彻底锁死
这步是基础,别留漏口子:
- 打开对应S3桶的权限设置,把「阻止所有公开访问」的4个选项全勾选保存,这时候直接访问S3原生域名的文件会直接返回403。
- 桶策略不要加任何公网读权限,只保留两个权限:一是你自己服务端生成预签名URL所用IAM账号的
s3:GetObject权限,二是加一条IP白名单条件,只允许Cloudflare的回源IP段访问桶的s3:GetObject动作,其他来源IP全拦,避免有人拿到S3原生域名绕开Cloudflare访问。 - 你之前用的预签名URL生成逻辑基本不用改,唯一要注意的是生成签名时填的访问endpoint要换成你后面在Cloudflare绑定的资源域名,别填S3默认的原生域名,不然签名里的host字段和实际请求host不匹配,S3会直接判定签名无效。
2. Cloudflare侧配置边缘拦截+回源规则
这部分是和CloudFront配置差异最大的地方,不用配OAI那种专用身份,用Cloudflare自带的规则就能实现:
- 先给资源访问域名做DNS解析,源站指向对应S3桶,一定要开橙云走Cloudflare代理,别开灰云直连。
- 到「转换规则-修改请求头」里加一条全路径匹配的规则,给所有回S3源的请求做两个头调整:一是清空请求自带的
Authorization头,避免和URL里的签名参数冲突;二是添加X-Amz-Content-Sha256头,值固定填e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(这是GET空请求体的固定哈希值,解决S3签名校验时的body哈希不匹配问题)。 - 到「安全-WAF-自定义规则」里加一条拦截规则,匹配条件设为:请求查询参数中不存在
X-Amz-Signature、或X-Amz-Date对应的时间加X-Amz-Expires的有效期小于当前时间、或X-Amz-Expires值超过你允许的最大有效期(比如要限制最长1小时有效就设为大于3600),匹配到的请求直接执行「阻止」动作,返回403状态码,响应内容填你要的「Access denied(访问被拒绝)」就行。 - 最后调整缓存规则:对带
X-Amz-开头查询参数的请求,缓存键必须包含所有X-Amz-前缀的查询参数,避免出现签名串校验失败、或者一个用户的有效URL被缓存后其他人无签名也能访问的问题。
3. 效果校验
配置完直接测三个场景就行:
- 直接访问不带任何参数的文件路径,比如
https://你的资源域名/demo.png,会直接返回预设的访问被拒绝提示。 - 用服务端生成的合法预签名URL访问,可以正常加载/下载文件。
- 篡改预签名URL里的
X-Amz-Signature值、或者等URL过了有效期再访问,同样返回403拒绝提示。
踩坑提示:别给S3桶开静态网站托管,开了之后S3的网页托管端点不会校验Authorization和签名参数,会直接把文件公网暴露,之前的权限配置就全失效了。
内容的提问来源于stack exchange,提问作者Red Vic
相关产品推荐
相关产品推荐

