防盗链Nginx规则保护产品原图防止盗用下载
产品原图被其他网站直接引用,既消耗服务器带宽,又影响品牌形象和搜索权重。
通过 Nginx 的 valid_referers 指令可以快速拦截非本站来源的图片请求,让外站无法直接盗用下载。
本文会从准备条件、规则写法到验证方法完整演示,零基础用户也能照做,配置完成后正常情况下只有自己站点页面和直接访问能显示图片,其他来源一律返回 403。
配置前先确认Nginx版本和图片目录
Nginx 防盗链基于 ngx_http_referer_module 模块,默认已编译,无需额外安装。
先登录服务器确认 Nginx 版本:
nginx -v
同时确认你的产品原图放在哪个目录。
比如常见的路径是 /var/www/html/uploads/product/,访问地址对应 https://yourdomain.com/uploads/product/xxx.jpg。
如果项目用了 CDN 或对象存储,先记下源站的回源域名,后面配置会用到。
编写针对原图目录的防盗链规则
打开站点的 Nginx 配置文件,
一般位于 /etc/nginx/conf.d/ 或 /usr/local/nginx/conf/,
建议在 server 块内新增一个 location,
只对图片目录生效:
location ~* /uploads/product/.*\.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked server_names *.yourdomain.com yourdomain.com;
if ($invalid_referer) {
return 403;
}
}
这段规则的解释:
valid_referers定义允许哪些来源访问图片。none表示允许直接输入网址或没有Referer头访问;blocked表示允许Referer被隐藏的请求;server_names加上具体域名表示允许本站域名来源。$invalid_referer是 Nginx 内置变量,当请求来源不在允许列表时变1,此时返回403。- 正则只匹配
/uploads/product/下的图片文件,其他目录不受影响。
保存配置后先测试语法:
nginx -t
通过后重载 Nginx:
nginx -s reload
如果你的产品图分布在多个目录,可以增加一条正则同时匹配,例如:/uploads/(product|images)/。
绕开三个常见的防盗链误伤场景
第一个坑:不允许空 Referer。 很多新手去掉 none 只留自家域名,结果用户在浏览器直接访问图片链接时看不到图,因为地址栏输入时没有 Referer。
建议保留 none,避免误伤正常访客。
第二个坑:CDN 回源被拦截。 如果网站挂了 CDN,CDN 节点向源站请求图片时会带上 CDN 域名作为 Referer,源站会把 CDN 当成盗链。
这种情况要把 CDN 域名加入 valid_referers:
valid_referers none blocked server_names *.yourdomain.com yourdomain.com *.cdnprovider.com;
第三个坑:移动端或社交软件抓取。 微信、QQ 等内置浏览器有些场景会发送空 Referer,去掉 none 会导致分享时缩略图无法显示。
如果你的业务很依赖社交分享,建议用更温和的方式,比如对 $invalid_referer 返回自定义图片而不是 403,既减少带宽损耗又不打断分享。
用一条命令验证盗链是否被拦截
改完配置后,用 curl 模拟不同来源测试。
在本地终端执行:
模拟正常来源访问:
curl -I -H "Referer: https://yourdomain.com" https://yourdomain.com/uploads/product/a.jpg
模拟外站盗链访问:
curl -I -H "Referer: https://evil-site.com" https://yourdomain.com/uploads/product/a.jpg
正常来源应返回 HTTP/1.1 200 OK,盗链来源应返回 HTTP/1.1 403 Forbidden。
如果用浏览器验证,可以右键图片查看服务器响应。
还有一点需要注意:防盗链只限制浏览器发起的引用请求,不能阻止别人通过工具直接下载。
如果产品原图价值很高,建议在源图上加水印,并限制图片访问权限或使用临时签名 URL。
常见疑问与进一步建议
伪静态文件名会影响匹配吗? 如果图片地址经过伪静态重写,
前端 URL 末尾没有 .jpg,
Nginx 的 location 就要放在 rewrite 之前,
或者直接按实际处理后的路径配置。
防盗链规则放在 server 里还是 http 里? 放在对应站点的 server 块里最安全,只影响这个站点;
放在 http 块会影响所有虚拟主机,容易误伤。
用了宝塔面板怎么操作? 可以在“网站 -> 设置 -> 配置文件”中直接编辑新加的 location 规则,修改后点“保存”并重载 Nginx。
产品原图防盗链配置完成后,建议每隔一段时间查看 Nginx 访问日志,确认是否有大量 403 请求。
如果发现误拦截,优先检查是否漏掉了 CDN 域名或白名单来源。
此时再按本文的避坑说明调整 valid_referers 列表,就能在保护和体验之间找到平衡。