Nginx防盗链返回自定义小图需三步:一用valid_referers定义白名单(含none);二用if+rewrite内部重写盗链请求至本地图片;三为该图片配置独立location并禁用防盗链,避免循环。

要让 Nginx 在防盗链触发时返回一张自定义的小图片(比如 1×1 像素的 gif 或 png),关键在于用 valid_referers 判断来源,配合 rewrite 或 return 指令重定向到本地静态图资源,并确保该图片不被再次拦截。
配置 valid_referers 白名单
在 server 或 location 块中定义允许访问的 referer,其他来源视为盗链:
- 支持域名通配(
*.example.com)、正则(~\.google\.)、空 referer(直接访问或 HTTPS 页面引用 HTTP 资源时可能为空) - 务必包含
none,否则浏览器直接输入 URL 或书签访问也会被拦截 - 示例:valid_referers none blocked *.mydomain.com ~\.baidu\. ~\.google\.;
拦截并重写到小图资源
检测到非法 referer 后,用 if + rewrite 将请求内部重写为指定图片路径(注意是 internal rewrite,不改变浏览器地址栏):
- 推荐用
rewrite ^/.*\.(jpg|jpeg|png|gif)$ /img/anti-theft.png break; - 确保目标图片路径(如
/img/anti-theft.png)在 Nginx 的 root 下真实存在,且权限可读 - 避免用
return 302,否则会暴露图片真实路径,也可能被二次盗用
排除防盗链对小图自身的拦截
如果不加处理,上面重写的 /img/anti-theft.png 请求仍会进入同一套 referer 判断逻辑,导致死循环或 403。需单独为该图片 location 关闭防盗链:
- 新增一个精确匹配的 location:location = /img/anti-theft.png { }
- 在这个 location 内不写
valid_referers,也不套用防盗链 if 块 - 可额外加
expires max;和add_header Cache-Control "public";提升缓存效率
验证与调试建议
配置完成后 reload Nginx,用 curl 模拟不同 referer 测试响应:
- curl -H "Referer: https://bad-site.com" https://yoursite.com/test.jpg → 应返回 png 图片内容(HTTP 状态码 200)
- curl -H "Referer: https://mydomain.com" https://yoursite.com/test.jpg → 应返回原图
- 检查 Nginx error log,若出现
rewrite or internal redirection cycle,说明小图 location 未正确隔离










