最简单可靠的方式是valid_referers配合$invalid_referer和return 403,必须置于静态资源location块中,按后缀或路径前缀精准匹配,白名单需包含none、blocked及主域子域,响应推荐return 403以确保语义清晰、日志可查。

直接在静态资源的 location 块里用 valid_referers 配合 $invalid_referer 和 return 403,是最简单、最可靠的方式。它不依赖额外模块,所有主流 Linux 发行版开箱即用,重点是写对位置、留全白名单、响应明确。
防盗链必须放在静态资源 location 里
不能写在 http 或 server 根层级——valid_referers 只在能定位到真实文件的上下文中生效。推荐两种匹配方式:
-
按后缀匹配(通用):适合资源分散存放,例如
location ~* \.(jpg|jpeg|png|gif|css|js|woff2|ttf|svg|mp4|pdf)$ { ... } -
按路径前缀匹配(集中管理):适合资源统一放在
/static/或/assets/下,例如location ^~ /static/ { ... }
注意:该 location 内必须有 root 或 alias 指向实际文件路径,否则 Nginx 找不到资源,防盗链就形同虚设。
白名单要覆盖真实访问场景
合法 Referer 不只是“你家网站”,很多正常请求也会触发 none 或 blocked。漏掉它们,会导致用户打不开图、内网调试失败、企业网关下访问异常:
-
none:浏览器地址栏直接输入链接、收藏夹打开、HTTPS 页面跳转到 HTTP 资源时 Referer 被清空 -
blocked:隐私插件、企业防火墙、某些代理或 WebView 会把 Referer 改成localhost、about:blank或空字符串 -
主域和子域分开写:例如
example.com不匹配www.example.com,得都列上;或用*.example.com(注意它不包含主域) -
正则要严谨:比如允许百度来源,用
~\.baidu\.(com|cn)$,避免~baidu误匹配含 “baidu” 字样的非法域名
拦截动作要语义清晰、日志可查
推荐用 return 403,而不是 rewrite 跳转:
-
return 403返回标准拒绝状态码,CDN、爬虫、监控系统都能准确识别;Nginx 日志中$status和$invalid_referer一目了然 - 若需展示友好提示图,改用
error_page 403 =200 /images/forbidden.png;,既保持拒绝语义,又返回自定义内容 - 避免在同一个
location中混用多个if或嵌套rewrite,容易引发重写循环或路径错乱
配置完一定要验证边界情况
reload 后,用 curl 快速测几类典型请求:
- 合法来源:
curl -H "Referer: https://example.com/page.html" https://example.com/logo.png→ 应返回200 - 盗链来源:
curl -H "Referer: https://evil-site.net" https://example.com/logo.png→ 应返回403 - 空 Referer:
curl https://example.com/logo.png→ 若含none,应返回200 - 被屏蔽的 Referer:
curl -H "Referer: localhost" https://example.com/logo.png→ 若含blocked,应返回200
注意:Referer 可被客户端轻易伪造,这种防护只防“懒盗链”,不能替代 secure_link 等签名机制。











