valid_referers本身不拦截请求,仅设置$invalid_referer变量(1为非法),须配合if判断执行return 403或rewrite;必须置于匹配图片后缀的location块内,如location ~* .(jpg|png|webp)$,且白名单需含none、blocked及合法域名。

valid_referers 本身不拦截请求,只判断 Referer 是否合法,并设置内置变量 $invalid_referer(值为 1 表示非法)。真正起作用的是配合 if 判断后执行的返回或重写动作。配置必须放在匹配图片资源的 location 块内,不能写在 server 根层级。
精准匹配图片后缀,避免误伤其他资源
防盗链规则要聚焦在真实易被盗的文件类型上,不能宽泛覆盖整个静态目录:
- 用正则精确匹配主流图片格式:location ~* \.(jpg|jpeg|png|gif|webp|bmp|svg|ico)$,~* 表示忽略大小写
- 避免使用 location /static/ 或 location /assets/ 这类路径——它可能把 JS、CSS、字体甚至 Vue 的 history fallback 一起拦掉
- 如需保护视频或 PDF,建议单独建一个 location 块,例如:location ~* \.(mp4|pdf|zip)$,便于独立维护和灰度调整
白名单必须包含 none 和 blocked,否则自家页面会打不开
valid_referers 是“满足任一即放行”的逻辑,不是“只允许这些”。漏掉关键类型,会导致大量合法访问被拒:
- none:允许 Referer 为空的场景,比如用户直接输入图片 URL、点书签、HTTPS 页面引用 HTTP 图片(浏览器主动清空 Referer)
- blocked:覆盖微信内嵌浏览器、某些代理或防火墙修改后的 Referer(如只剩 localhost 或 /path)
- 域名或通配符:example.com、*.example.com(* 只能放开头)
- 可选加主流搜索引擎:~\.google\. ~\.baidu\. ~\.bing\.,注意点号必须转义,且以 ~ 开头
拦截动作要写对位置,且提示图需单独豁免
仅写 valid_referers 不会生效,必须搭配 if 判断并给出响应:
- 返回 403 禁止访问:if ($invalid_referer) { return 403; }
- 重定向到提示图(推荐):if ($invalid_referer) { rewrite ^/.*$ /images/hotlink-denied.png break; }
- 提示图本身必须跳过防盗链校验,否则会循环失败。需额外加一段:location = /images/hotlink-denied.png { }(空块即可,不写 valid_referers)
- 如果 location 中用了 try_files(如 Vue 的 history fallback),防盗链 if 必须写在 try_files 之前,否则先返回 404,根本走不到拦截逻辑
CDN 场景下必须双层配置才真正有效
如果网站已接入 CDN,单靠 Nginx 配置大概率失效,因为 CDN 默认不透传 Referer:
- 在 CDN 控制台开启 Referer 白名单功能,并填入你的主域和子域(如 example.com、*.example.com)
- 在 CDN 回源设置中启用「透传 Referer」或「保留原始 Referer 头」
- Nginx 层规则仍需保留——作为 CDN 拦截失败时的兜底,形成双重防护











