Nginx通过valid_referers指令基于Referer头设置$invalid_referer变量,配合if和root/alias实现防盗链;需置于匹配静态资源的location块中,支持域名、通配符、正则及none/blocked规则,多规则为“或”关系。

想防止别人盗用你的图片、CSS、JS等静态资源?Nginx 的 valid_referers 指令配合 root(或 alias)就能高效实现防盗链,关键不在复杂配置,而在理解 referer 判断时机和路径匹配逻辑。
valid_referers 是怎么工作的?
它不直接拦截请求,而是根据 HTTP Referer 请求头,设置内置变量 $invalid_referer:合法来源时为空字符串,非法时为 "1"。后续靠 if 判断这个变量来决定是否返回 403 或重定向。
- 支持精确域名(
www.example.com)、带通配符(*.example.com)、正则(~\.google\.)、以及空 referer(none) - 注意:空 referer 常见于直接访问 URL、HTTPS 页面引用 HTTP 资源(因安全策略丢失 referer)、或用户手动输入地址,需按业务决定是否允许
- 多个规则是“或”关系,满足任一即视为合法
为什么 root/alias 的位置影响防盗链效果?
防盗链规则必须写在能匹配到静态资源的 location 块里,且该 location 需明确指定资源根目录(root)或映射路径(alias)。如果写在 upstream 或 server 级别,Nginx 不知道该去哪找文件,valid_referers 就失去上下文。
- 推荐用
location ^~ /static/这类前缀匹配,避免正则 location 优先级干扰 -
root /var/www/html;表示请求/static/js/app.js对应文件路径是/var/www/html/static/js/app.js -
alias /var/www/assets/;表示同样请求对应的是/var/www/assets/js/app.js(注意 alias 会截掉 location 路径前缀)
一个可直接用的防盗链配置示例
以下配置限制仅允许本站及指定域名访问 /static/ 下所有文件,非法请求返回 403:
location ^~ /static/ {
valid_referers none blocked www.example.com example.com *.example.com;
if ($invalid_referer) {
return 403;
}
root /var/www/html;
expires 1y;
add_header Cache-Control "public, immutable";
}
-
blocked匹配被防火墙或代理 stripped 的 referer(常见于某些浏览器隐私模式) - 把
return 403换成rewrite ^(.*)$ /403.png break;可返回默认提示图,更友好 - 务必测试:用 curl -H "Referer: http://evil.com" 模拟盗链请求验证是否生效
容易踩的坑
常见问题不是指令不会用,而是细节没对上:
- HTTPS 站点引用 HTTP 资源时,现代浏览器默认不发送 referer,导致误判——要么全站 HTTPS,要么在
<meta>中加referrerpolicy="no-referrer-when-downgrade" -
valid_referers不支持端口号(如localhost:8080),开发环境建议用域名或临时关闭防盗链 - CDN 回源时,真实 referer 可能被 CDN 改写为自身域名,需在 CDN 后台配置透传原始 referer(如阿里云 CDN 的 “Referer 白名单” 配合回源请求头设置)

















