Nginx防盗链返回403需用valid_referers定义合法来源(支持none、server_names、通配符及正则),通过$invalid_referer变量判断,再在location中用if($invalid_referer){return 403;}实现拦截。

<p>在 Nginx 中实现防盗链并返回 403,核心是通过 <strong>valid_referers</strong> 指令识别合法来源,再用 if 判断非法请求并拒绝访问。</p>
<H3>配置 valid_referers 定义合法 Referer</H3>
<p>在 server 或 location 块中设置允许的来源域名(支持通配符和正则),Nginx 会将结果存入内置变量 $invalid_referer(值为 1 表示非法):</p>
<ul>
<li>允许空 Referer(直接输入 URL 访问):添加 <strong>none</strong></li>
<li>允许本站域名及子域名:用 <strong>server_names</strong> 或 <strong>*.example.com</strong></li>
<li>支持正则匹配:如 <strong>~* \.(baidu|google)\.com$</strong>(注意 ~* 表示忽略大小写的正则)</li>
</ul>
<H3>用 if 判断并返回 403</H3>
<p>不能在 if 中直接 return 403(可能触发重定向或报错),推荐写法是:</p>
<ul>
<li>先定义 <strong>if ($invalid_referer) { return 403; }</strong></li>
<li>确保该 if 放在 location 内,且在 try_files 或 proxy_pass 等指令之前</li>
<li>若需拦截特定后缀(如图片、CSS),建议把防盗链逻辑放在匹配静态资源的 location 块里</li>
</ul>
<H3>完整示例(拦截图片盗链)</H3>
<p>以下配置放在 server 块内即可:</p>
<pre><code>location ~* \.(jpg|jpeg|png|gif|webp|css|js)$ {
valid_referers none blocked server_names *.example.com ~\.google\.;
if ($invalid_referer) {
return 403;
}
}</code></pre>
<p>说明:<strong>blocked</strong> 表示 Referer 被防火墙或浏览器过滤后的“无效但非空”情况;<strong>~\.google\.</strong> 是正则匹配 google 相关域名。</p>
<H3>验证与注意事项</H3>
<p>配置后需 <strong>nginx -t && nginx -s reload</strong> 生效。测试时可用 curl 模拟不同 Referer:</p>
<ul>
<li>正常访问:<strong>curl -H "Referer: https://example.com" https://yoursite.com/image.jpg</strong></li>
<li>盗链模拟:<strong>curl -H "Referer: https://evil.com" https://yoursite.com/image.jpg</strong> 应返回 403</li>
<li>注意:HTTPS 站点下,HTTP Referer 可能被浏览器策略清空,导致误拦,必要时保留 <strong>none</strong></li>
</ul>