Nginx设置referer防盗链
为什么需要给图片加 referer 防盗链
图片被其他站点直接引用,会持续消耗你的服务器带宽和流量,访问量一大,源站响应也会变慢。
Nginx 设置 referer 防盗链,就是通过检查请求头里的 Referer 字段,判断图片请求是否来自允许的域名,不是就返回 403,从而保护图片资源。
本文面向零基础用户,给出可直接复制修改的配置片段、白名单写法、验证方法和常见报错排查思路。
这个方案适合有独立图片目录、又不想上复杂鉴权的站点。
它属于轻量级防护,配置一次即可长期生效。
动手前的准备
开始之前,先确认三件事。
- Nginx 已经安装并能正常访问站点图片,例如浏览器直接打开
https://你的域名/uploads/test.jpg能看到图。 - 找到 Nginx 配置文件位置。常见路径是
/etc/nginx/nginx.conf,站点配置一般在/etc/nginx/conf.d/或/etc/nginx/sites-available/。 - 知道图片的存放目录或访问路径,比如
/uploads/、/images/或/static/。
如果你用的是宝塔面板,可以直接进入 网站 -> 设置 -> 配置文件,在对应 server 块里编辑,改完保存即可。
改配置前建议先备份:
cp /etc/nginx/conf.d/your-site.conf /etc/nginx/conf.d/your-site.conf.bak
配置 referer 白名单的核心写法
防盗链的核心指令是 valid_referers,它定义哪些来源算合法。
下面是一段可以放进 server 块或 location 块的示例,重点是保护图片类后缀:
location ~* \.(gif|jpg|jpeg|png|webp|bmp|svg)$ {
valid_referers none blocked server_names
*.example.com example.com
*.yourdomain.com yourdomain.com;
if ($invalid_referer) {
return 403;
}
expires 30d;
add_header Cache-Control "public";
}
逐项说明:
valid_referers后面列出允许的来源。none表示允许没有 Referer 的请求,blocked表示允许 Referer 被防火墙或代理隐藏的请求,server_names表示允许当前 server 配置里声明的域名。*.example.com和example.com是白名单域名,把这里替换成你自己的域名和需要放行的合作站点。if ($invalid_referer)表示来源不在白名单时,执行后面的动作。return 403是直接拒绝,也可以用rewrite返回一张占位图。expires 30d是给正常图片加缓存,属于顺手优化,不影响防盗链逻辑。
如果只想保护某个目录,可以把 location 改成 location ^~ /uploads/,再在里面写同样的判断。
让配置生效并验证
配置写完后,先测试语法,再重载 Nginx:
nginx -t
nginx -s reload
如果 nginx -t 提示 syntax is ok,说明配置没问题。
验证分两步。
第一步,确认站内图片正常显示:在浏览器打开你的页面,图片应该照常加载。
第二步,模拟盗链请求:
curl -I -e "https://other-site.com/" https://你的域名/uploads/test.jpg
这里的 -e 用来伪造来源。
如果返回 HTTP/1.1 403 Forbidden,说明防盗链已经生效。
再把来源换成你自己的域名,应该返回 200 OK。
容易踩坑的几个地方
- 白名单漏写自己的域名:结果站内图片也 403。务必把主域名、带 www 的域名、以及所有会用到的子域名都列进去。
- 忽略空 Referer:很多用户从收藏夹、直接输入网址或某些 App 打开图片时,Referer 是空的。如果业务需要,就保留
none;如果要严格限制,可以去掉它,但要先确认不影响正常访问。 - CDN 回源场景:如果图片走了 CDN,回源请求的 Referer 可能是 CDN 节点域名,需要把 CDN 回源域名加入白名单,否则会出现 CDN 缓存命中失败或图片 403。
- 只改了配置文件没重载:Nginx 不会自动读取新配置,每次修改都要
nginx -t加nginx -s reload。 - 正则写法过宽:
location ~* \.(jpg|png)$会匹配所有目录下的图片,如果你只想保护/uploads/,就限定目录,避免影响站点图标等公共资源。
常见疑问
为什么加了防盗链,站内图片反而不显示了? 多半是白名单没包含当前访问域名。
检查 valid_referers 里是否写全了主域名、www 域名和实际访问入口。
返回 403 但我想返回一张提示图怎么办? 把 return 403; 换成 rewrite ^ /anti-hotlink.png redirect;,
并确保这张提示图本身不被防盗链规则拦截。
这个方案能防住直接输入图片地址的访问吗? 如果白名单里保留了 none,直接访问仍然放行。
要严格禁止,就去掉 none,但要评估对用户体验的影响。
和 Nginx 的 secure_link 有什么区别? referer 防盗链实现简单、开销低,但 Referer 可以被伪造,防护强度有限。
secure_link 通过签名校验,安全性更高,但需要后端配合生成签名,适合对防盗要求更高的场景。
小结
给图片加 referer 防盗链,关键就是 valid_referers 白名单加 $invalid_referer 判断这两步。
配置前备份、配置后 nginx -t 验证、再用 curl 伪造来源测试,基本就能稳定落地。
如果你正在处理 Nginx 设置 referer 防盗链保护图片资源,建议先按本文步骤完整执行,再根据自己是否使用 CDN、是否允许空 Referer 做微调。