防盗链靠nginx的valid_referers指令匹配referer字段生效;宝塔仅自动生成规则,但插入位置错误、参数错误或被重载覆盖会导致失效,且天然无法防御直接访问、伪造referer等场景。

防盗链在宝塔面板里到底靠什么生效
防盗链不是封 IP,而是靠 Nginx 的 valid_referers 指令匹配请求头里的 Referer 字段。宝塔图形界面做的只是自动生成这段规则并插入到站点配置中——但插入位置不对、参数写错、或被后续操作覆盖,都会导致“明明勾选了却没用”。
它天然不防:直接复制图片 URL 打开、Postman 手动发请求、爬虫伪造 Referer;能防的只是外站 HTML 里用 <img src="https://your.com/a.jpg?x-oss-process=image/resize,p_40"> 这种方式引用。
网站设置 → 防盗链 页面填什么才安全有效
进入站点「设置」→「防盗链」后,三个字段最容易出错:
-
URL后缀:只填真实要保护的静态资源,比如jpg,png,gif,webp,js,css;别加空格、别写.jpg(点不要)、别塞html(否则首页可能白屏) -
许可域名:必须包含你自己的主域和常用子域,例如example.com,www.example.com,*.example.com;注意example.com不自动包含cdn.example.com,得单独写或用通配符 -
允许空HTTP_REFERER请求:绝大多数站点必须勾选;微信内嵌浏览器、PWA、地址栏直输图片地址等场景都发空Referer,不勾这个,用户第一眼就看到 403 或裂图
响应资源建议填一张站内存在的 fallback 图,比如 /security.png,比纯 403 更友好,也避免 CDN 缓存错误状态码。
为什么点了保存却没生效?常见覆盖与失效原因
宝塔每次修改 SSL、伪静态、反向代理或点击「重载配置」,都可能重写 Nginx 配置文件,把你手动加的规则冲掉——而图形界面生成的防盗链规则,恰恰容易被覆盖。
真正稳妥的做法是:进入「网站」→「设置」→「配置文件」,找到 #REWRITE-END 下方或 #SSL-END 和 server { 块之间的空白处,手动补一段 location 规则:
location ~* \.(jpg|jpeg|png|gif|webp|js|css)$ {
valid_referers none blocked *.example.com example.com;
if ($invalid_referer) {
return 403;
}
}
注意:valid_referers 必须写在 location 块内,不能放在 server 根层级;none 表示允许空 Referer,blocked 表示屏蔽被篡改或无效的 Referer。
测试防盗链是否真起作用的实操方法
别只信图形界面的勾选状态,用真实请求验证:
- 在自己网站 HTML 里放一个
<img src="https://your.com/test.jpg?x-oss-process=image/resize,p_40">,打开页面看图是否正常 - 新建一个本地 HTML 文件,写一行
<img src="https://your.com/test.jpg?x-oss-process=image/resize,p_40">,用 Chrome 打开,检查 Network 面板里该请求的Referrer Policy是否为no-referrer-when-downgrade(否则可能因策略限制没带 Referer,误判为失效) - 用 curl 模拟外站引用:
curl -H "Referer: https://badsite.com" https://your.com/test.jpg -I,应返回403 - 微信里打开文章链接,确认图片仍可加载(验证空 Referer 是否放行)
最常被忽略的一点:CDN 开启后,Nginx 层的防盗链规则可能被绕过——如果 CDN 节点缓存了未校验 Referer 的响应,后续所有请求都直接返回缓存内容。此时必须在 CDN 后台同步配置 Referer 白名单,或关闭对应资源的 CDN 缓存。










