小皮面板(phpStudy 面板)没有一键「防盗链」开关,防图片被盗用的正确做法是在站点的 Nginx 配置文件里用 valid_referers 校验 Referer,或是在 Apache 的 .htaccess 里加 RewriteCond 条件,把外站引用的图片请求直接返回 403 或替换成占位图。以下给出可直接粘贴的配置和验证命令。
防盗链的原理是什么
结论:防盗链的本质是校验 HTTP 请求头里的 Referer 字段,判断图片是被哪个域名引用的,不是自己站点就拒绝。
Referer(引用来源)是浏览器在请求图片、脚本等子资源时自动带上的上一页地址。用户在自己站点页面里看图,Referer 是本站域名;被别站 <img src> 直接引用时,Referer 就是对方域名。服务器端匹配白名单,不匹配的请求返回 403 或换成占位图,对方页面上就只剩一个破图或占位提示,带宽和流量也就不再被白嫖。
这个方案有两个固有短板,先说清:一是 Referer 是客户端自愿上报的,用图片代理、伪造 Referer 的采集程序能绕过;二是部分客户端(旧版 App、HTTPS 跳 HTTP、隐私模式)会不带 Referer,处理不当会误伤正常用户。所以配置里必须放行空 Referer。
Nginx 环境怎么配置防盗链
结论:打开小皮面板的站点配置文件,在 server { } 内加一个针对图片后缀的 location 块,用 valid_referers 加 $invalid_referer 判断即可。
操作路径:小皮面板 → 网站 → 找到目标站点 → 管理 → 修改 → 配置文件(即 vhosts.conf 里的对应 server 段),改完点保存,面板会自动执行 nginx -t 校验并 reload;如果没自动重载,到软件管理里对 Nginx 点「重启」。
location ~* \.(jpg|jpeg|png|gif|webp|bmp|svg)$ {
valid_referers none blocked server_names *.example.com example.com;
if ($invalid_referer) {
return 403;
# 更友好的做法:返回占位图
# rewrite ^/ /static/nohotlink.png break;
}
expires 30d;
add_header Vary Referer;
}
参数含义:none 放行不带 Referer 的请求,blocked 放行被防火墙或代理抹掉协议头的 Referer,server_names 自动匹配本站 server_name 里配置的所有域名。把 example.com 换成你自己的域名,同时把需要放行的搜索引擎图片域名、CDN 回源域名按 *.baidu.com、*.google.com 这种写法追加进去。
add_header Vary Referer; 这行别省。它告诉 CDN 和浏览器「同一个 URL 在不同 Referer 下内容可能不同」,避免 CDN 把一次 403 缓存下来,导致本站用户也打不开图。
Apache 环境怎么配置
结论:Apache 下不需要改主配置,在网站根目录放一个 .htaccess,用 RewriteCond 匹配 Referer 再用 RewriteRule 拦截即可。
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?baidu\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp|bmp|svg)$ - [F,NC]
[F] 直接返回 403;想要换成占位图,把最后一行改成 RewriteRule \.(jpg|jpeg|png|gif|webp)$ /static/nohotlink.png [R,L]。[NC] 表示域名匹配不区分大小写,!^$ 那一行就是放行空 Referer 的条件,删掉它会误伤直接输入图片链接访问的用户。前提是 Apache 已开启 mod_rewrite 且站点配置里 AllowOverride 允许 .htaccess 生效,小皮面板默认的 Apache 站点一般已满足。
配置完怎么验证生效
结论:用 curl -I -e 模拟不同 Referer 请求同一张图片,看返回码是 200 还是 403,比开浏览器刷新更准。
curl -I -e "https://www.example.com/post/1.html" https://www.example.com/uploads/a.jpg
# 2. 模拟外站盗用,应返回 403
curl -I -e "https://evil-site.com/" https://www.example.com/uploads/a.jpg
# 3. 不带 Referer,应返回 200(因为你写了 none)
curl -I https://www.example.com/uploads/a.jpg
三条结果都符合预期,说明规则已生效。如果第二条仍是 200,按顺序排查三点:规则是否加在了正确的 server 段;Nginx 是否真的 reload 成功(面板里看配置校验结果);浏览器/CDN 缓存是否还没过期,加个 ?v=2 参数绕开缓存重测。
防盗链最容易踩的几个坑
结论:防盗链配错导致的投诉,九成出在「白名单漏了正常来源」和「规则范围开太大」这两件事上。
- 漏掉空 Referer:不放行
none,用户在微信里打开、在地址栏直接输入图片地址、从 HTTPS 页面跳到 HTTP 图片时都会拿到 403,看起来像站点挂了。
- 漏掉 CDN 回源域名:站点挂了 CDN 后,回源请求的 Referer 可能是 CDN 自己的域名,不放行会导致全站图片 403。
- 规则写得过宽:直接对整站
location / 做 Referer 校验,会把 CSS、JS、字体文件一起拦掉,页面样式直接崩。只针对图片后缀或 /uploads/ 目录生效。
- 忘了搜索引擎图片收录:百度、Google 图片搜索的 Referer 域名要放行,否则站点的图片永远进不了图片搜索流量。
- 防盗链挡不住专业采集:伪造 Referer 或用图片代理的程序可以绕过。这类情况要上更硬的方案:给图片地址加带时间戳的签名(Nginx 的
secure_link 模块),过期即失效;或者把图片挪到对象存储,用私有读 + 临时签名 URL。
配完规则后建议先在自己站点抽样打开 10 张图片确认正常,再去站长类社区发帖请人帮忙从外站引用测试。像 GJ 站长论坛这类面向站长和运维的社区,问答区常有同类配置的排错讨论,把自己的 location 段和 curl -I 结果一起贴出来,定位会快很多;发帖前记得先上传头像,否则账号是发不了帖的。
总结一句:小皮面板不提供防盗链开关,Nginx 用 valid_referers 加 $invalid_referer 返回 403,Apache 用 RewriteCond 加 [F],两者都必须放行空 Referer 并追加 CDN、搜索引擎白名单,改完用 curl -I -e 三条命令验证,再靠签名 URL 或对象存储兜住会伪造 Referer 的那批流量。