valid_referers 防盗链通过校验 referer 请求头实现,需精准匹配资源类型、白名单包含 none/blocked/主域/搜索引擎,并配合 if($invalid_referer) 拦截,且须避开通配路径、确保提示图豁免及 cdn 透传。

用 valid_referers 防盗链,本质是检查请求头里的 Referer 是否来自可信来源,再拦截非法引用。它不加密、不鉴权,但配置快、见效快,能挡住大多数自动盗链和粗放爬虫。
精准匹配要保护的资源类型
防盗链必须聚焦在真实易被盗的文件上,不能“一锅端”整个静态目录,否则可能把 CSS、JS、字体甚至前端路由 fallback 一起拦掉。
- 只匹配图片:用
location ~* \.(jpg|jpeg|png|gif|webp|bmp|svg|ico)$,~*表示忽略大小写 - 单独保护视频或大文件:如需防 MP4、PDF、ZIP 盗链,建议另起一个
location ~* \.(mp4|pdf|zip)$块,便于独立调整和灰度验证 - 避免写
location /static/或location /assets/这类宽泛路径——它们会覆盖大量非目标资源,引发误拦
白名单必须包含 none 和 blocked
valid_referers 是“满足任一即放行”,不是“只允许这些”。漏掉关键类型,自家页面图片都会打不开。
- none:允许 Referer 为空的合法场景,比如用户直接输入图片地址、点书签、HTTPS 页面引用 HTTP 图片(浏览器会清 Referer)
-
blocked:覆盖微信内嵌浏览器、某些代理或防火墙修改后的 Referer(如只剩
localhost或/path) - 你的主域和子域:
example.com和*.example.com(通配符仅支持前缀) - 可选加主流搜索引擎:
~\.google\.com$、~\.baidu\.com$,注意点号要转义,且以~开头
配合 if 拦截并正确响应
valid_referers 本身不拦截,只设置内置变量 $invalid_referer(值为 1 表示非法)。真正起效靠 if ($invalid_referer) 后的动作。
- 返回 403 禁止访问:
if ($invalid_referer) { return 403; } - 重定向到提示图(更友好):
if ($invalid_referer) { rewrite ^/.*$ /images/hotlink-denied.png break; } - 提示图本身必须豁免校验,否则会循环失败:额外加一段
location = /images/hotlink-denied.png { }(空块即可) - 如果 location 中用了
try_files(如 Vue 的 history fallback),防盗链if必须写在它前面,否则先返回 404,根本走不到拦截逻辑
上线前务必验证关键场景
配置 reload 后不等于生效,漏测一步就可能线上出问题。
- 本地打开网页,确认图片正常加载(查是否漏了
none或协议不一致导致 HTTPS 页面引用 HTTP 图片失败) - 用 curl 模拟盗链:
curl -H "Referer: https://bad-site.com" https://yoursite.com/test.jpg,看是否真返回 403 - Nginx 日志里加上
$invalid_referer $http_referer字段,观察误拦率和真实盗链特征 - 若已接入 CDN,确认 CDN 控制台开启了 Referer 透传;否则合法请求也会被拦











