nginx防盗链通过valid_referers校验referer字段,仅允许指定域名、none或blocked来源访问静态资源,配合if($invalid_referer)返回403或重写提示图,需按资源类型在location块中配置并避免全局误拦。

Nginx 防盗链中阻止跨站引用,本质就是通过校验 HTTP 请求头中的 Referer 字段,只允许来自你认可的域名(或无 Referer、被屏蔽的 Referer)访问指定资源,其他来源一律拦截。这不是绝对安全的防护,但对绝大多数盗链行为有效。
下面直接讲怎么配,不绕弯:
防盗链配置核心:valid_referers + if 判断
关键指令是 valid_referers,它定义哪些 Referer 是合法的;配合 $invalid_referer 变量,在 if 中做拦截动作。
常见合法来源写法:
-
none:允许直接输入 URL 访问(无 Referer,比如用户在地址栏敲图片链接) -
blocked:允许 Referer 存在但被代理/防火墙清空或格式异常(如不以http://或https://开头) -
server_names:自动匹配当前server_name值(推荐用这个,比硬写域名更灵活) -
*.example.com或example.com:显式指定允许的域名(支持通配符)
按资源类型精准拦截(推荐)
把防盗链规则放在 location 块里,只针对图片、视频、字体、JS/CSS 等易被盗静态资源:
location ~* \.(jpg|jpeg|png|gif|webp|bmp|mp4|mov|flv|pdf|zip|js|css|woff2?)$ {
valid_referers none blocked server_names *.yourdomain.com yourdomain.com;
if ($invalid_referer) {
return 403;
# 或者返回一张“防盗链提示图”:
# rewrite ^(.*)$ /img/forbidden.png break;
}
}
说明:
-
~*表示忽略大小写的正则匹配; -
server_names会自动识别当前server { server_name ... }里声明的所有域名(含 www 和非 www); - 如果你有多个子域名(如
blog.yourdomain.com、cdn.yourdomain.com),加*.yourdomain.com就能一并放行; -
return 403最简洁,浏览器显示“禁止访问”; -
rewrite方式适合想给盗链者一个“面子”,比如显示一张带 logo 的提示图。
注意跨站引用的特殊场景
有些“跨站”其实是合理请求,容易误拦,需提前规避:
- 单页应用(SPA)内部跳转通常不刷新 Referer → 建议保留
none; - 移动 App、小程序、桌面客户端默认不发 Referer → 若它们要调用你的资源,不能依赖 Referer 校验;
- HTTPS 页面加载 HTTP 资源时,浏览器按 Referrer Policy 会清空 Referer → 确保前后端协议一致(全站 HTTPS);
- 某些合作站点需白名单接入 → 把对方域名加进
valid_referers,例如partner-site.com或*.partner-site.com。
不建议全局配置
别在 http { } 块里写防盗链,否则所有 server 都生效,容易冲突。优先放在:
-
server { }块内(整站生效); - 或更细粒度的
location /static/、location /images/(只保护某路径)。
配置完记得:
-
nginx -t检查语法; -
nginx -s reload生效; - 用 curl 测试:
curl -H "Referer: https://bad-site.com" https://yourdomain.com/test.jpg→ 应返回 403;curl -H "Referer: https://yourdomain.com" https://yourdomain.com/test.jpg→ 应正常返回图片。
不复杂但容易忽略细节。











