valid_referers 仅校验 Referer 合法性,需配合 if 和 $invalid_referer 实现防盗链;它防懒爬虫但不防伪造,应与 token 验证、限流、UA 过滤等组合使用。

在 Nginx 中,valid_referers 指令本身**不能直接拦截爬虫或采集器**,它只校验 HTTP 请求头中的 Referer 字段是否合法。很多恶意采集器(尤其是直链访问图片、CSS、JS 等静态资源的工具)会伪造或清空 Referer,而真实浏览器通常携带有效来源。因此,合理利用 valid_referers 配合 if 和返回状态码,可有效阻止**无 Referer 或非法 Referer 的盗链行为**——这是资源被批量采集的常见入口。
明确 valid_referers 的作用范围
valid_referers 是一个“设置变量”的指令,它只影响内置变量 $invalid_referer 的值(为 1 表示不匹配,0 表示匹配)。它本身不拒绝请求,必须配合 if 才能做响应控制。注意:if 在 location 块中使用是安全的,但在 server 或 location 外部应避免。
- 匹配成功 →
$invalid_referer = 0 - 匹配失败(空 Referer、非法域名、非 HTTP/HTTPS 协议等)→
$invalid_referer = 1 - 默认允许空 Referer;如需禁止空 Referer,需显式加入
none参数
典型防盗链配置示例
以下配置放在 location 块中(例如针对图片、字体、视频等易被盗用的静态资源):
location ~* \.(jpg|jpeg|png|gif|webp|woff2|ttf|mp4|pdf)$ {
valid_referers none blocked server_names
*.example.com example.com
~\.google\.
~\.baidu\.
<pre class="brush:php;toolbar:false;">if ($invalid_referer) {
# 返回 403 禁止访问(更隐蔽)
return 403;
# 或返回一张占位图(用户体验更好)
# rewrite ^(.*)$ /static/blocked.png break;
}
}
-
none:允许空 Referer(如用户直接在地址栏输入 URL);若要禁止,就别写它 -
blocked:允许 Referer 被防火墙、隐私插件等移除后只剩协议+域名(无 path)的情况 -
server_names:允许本服务器所有配置的server_name -
*.example.com和example.com:显式放行主站及子域名 -
~\.google\.:正则匹配 Google 搜索结果页(方便 SEO 图片展示)
重要限制与注意事项
valid_referers 有天然局限,不能替代真正的反爬策略:
- Referer 可被任意伪造(curl -e "https://baidu.com" ...),所以它防的是“懒爬虫”,不是专业攻击者
- HTTPS 页面引用 HTTP 资源时,浏览器可能不发送 Referer(Referrer Policy 限制),导致误杀
- 移动端 App、微信内嵌页、PWA 等场景 Referer 不稳定,需谨慎放行
- 不要对 API 接口或登录页使用此规则,否则会影响正常调用或第三方授权流程
- 日志中可加
$invalid_referer字段排查拦截情况:log_format main "... $invalid_referer";
更有效的组合防御建议
单靠 valid_referers 力度有限,推荐搭配以下手段提升防护效果:
- 对关键资源启用 Token 验证(如
/img/xxx.jpg?t=xxx&sign=yyy),Nginx 用ngx_http_secure_link_module校验 - 用
limit_req限制单 IP 单位时间请求数,防暴力遍历 - 结合 User-Agent 黑名单(
map+if ($bad_ua)),拦截已知采集 UA(如 Python-urllib、Scrapy) - 前端资源加上
Referrer-Policy: strict-origin-when-cross-origin减少泄露,同时服务端不过度依赖 Referer











