在 Web 开发中,保护静态资源(如图片、文件等)不被滥用是一个常见需求,通过防盗链机制可以实现
- 成本控制:防止第三方站点盗用资源消耗带宽
- 安全防护:限制资源访问来源防止恶意爬取
- 数据准确 - 确保统计分析的访问来源可信度
本文将以图片资源为示例,介绍如何使用 Caddy 服务器实现灵活的防盗链机制
完整配置示例
oss.example.com {
@deny_no_referer {
header !Referer
header Accept image/*
}
@deny_not_in_whitelist {
header Referer *
not header_regexp Referer ^https?://([^\s/:]+\.)*(example\.com|trusted\.site)(:\d+)?(/|$)
}
handle {
respond @deny_no_referer "Access denied" 403
respond @deny_not_in_whitelist "Access denied" 403
}
reverse_proxy 127.0.0.1:8080
}
配置解析与工作原理
Caddy 配置字段解析
Named matchers 命名匹配器
@name {
...
}
命名匹配器,可以定义一个命名以及一些指令,在需要这些指令的时候直接使用命名匹配器
Request Matchers 请求匹配器
header <field> [<value> ...]
header
- 通过请求头字段 field ,以值 value 进行匹配field
- 请求头字段,例如 Referervalue
- 匹配的值
header_regexp [<name>] <field> <regexp>
header_regexp
- 通过请求头字段 field ,以正则的值 regexp 进行匹配regexp
- 正则表达式
not header <field> [<value> ...]
not
- 取反匹配器的结果
核心匹配规则
基础防护层 - 阻断无 Referer 请求
@no_referer {
header !Referer # 缺失来源标识
header Accept image/* # 请求图片类资源
}
部分浏览器能支持在 web 加载图片资源时,不携带 Referer。如在 HTML 的
标签中增加如下代码<meta name="referrer" content="no-referrer">
或者针对特定资源使用 referrerpolicy 属性
<!-- 图片不发送 Referer -->
<img src="image.jpg" referrerpolicy="no-referrer">
<!-- 链接不发送 Referer -->
<a href="https://example.com" referrerpolicy="no-referrer">Link</a>
<!-- 脚本加载不发送 Referer -->
<script src="script.js" referrerpolicy="no-referrer"></script>
白名单控制 - 只允许特定域名的引用
@deny_not_in_whitelist {
header Referer *
not header_regexp Referer ^https?://([^\s/:]+\.)*(example\.com|trusted\.site)(:\d+)?(/|$)
}
正则分解:
^https?://
- 支持 HTTP/HTTPS([^\s/:]+\.)*
- 匹配任意子域名(example\.com|trusted\.site)
- 主域名白名单,只允许 example.com 以及 trusted.site 访问(:\d+)?
- 允许带端口号(/|$)
- 路径开始或结束
测试验证方法
有正确的 Referer ,响应正确的图片
curl -H "Referer: https://www.example.com" https://static.example.com/image.jpg
用错误的 Referer ,响应 403 Access denied
curl -H "Referer: https://error.referer.com" https://static.example.com/image.jpg
没有 Referer ,请求头 Accept 字段从 image 开始,响应 403 Access denied (HTML no-referrer 的情况)
curl -H "Accept: image/jpg" https://static.example.com/image.jpg
没有 Referer ,请求头 Accept 字段不从 image 开始,响应正确的图片(直接下载图片或者链接单独在浏览器中打开图片)
curl https://static.example.com/image.jpg
参考文档
版权属于:谁把年华错落成诗 所有,转载请注明出处!
本文链接:https://blog.pomears.com/archives/76.html
如果博客部分链接出现 404,请留言或者联系博主修复。