最常用、最可控的防盗链方式是在 location 块中精准校验 Referer,仅对 jpg、png 等静态资源生效,用大小写不敏感正则匹配后缀并以 $ 结尾;配置 valid_referers 白名单,通过 $invalid_referer 判断返回 403 或自定义提示图。

直接在 location 块里做 Referer 校验,是最常用、最可控的防盗链方式。关键不是“拦所有外链”,而是精准识别合法来源,并只对图片、视频、字体等易盗用资源生效。
匹配目标资源后缀(不匹配 HTML 或 API)
用大小写不敏感的正则精确匹配静态资源扩展名,结尾加 $ 防止误匹配带参数的 URL:
location ~* \.(jpg|jpeg|png|gif|webp|mp4|avi|css|js|woff2?)$ { ... }- 避免用
location /static/这类路径前缀——它不看文件类型,容易漏拦或误伤 - HTML、favicon.ico、API 接口等无需 Referer 校验,不要放进这个块
定义合法 Referer 白名单
在同一个 location 块内配置 valid_referers,支持多种来源类型:
-
none:允许用户直接在浏览器地址栏输入 URL 访问 -
blocked:接受被隐私插件或代理清空 Referer 的请求 -
example.com *.example.com:主站及全部子域(注意不带http://) -
~* \.myapp\.(com|org):用正则匹配多个二级域名
拦截非法请求并返回合理响应
校验后通过 $invalid_referer 变量判断是否放行:
- 推荐直接返回
return 403:语义清晰,日志易统计,CDN 和爬虫能准确识别拦截 - 如需显示提示图,用
error_page 403 =200 /images/forbidden.png;,而非rewrite—— 避免状态码混淆和参数丢失 - 确保提示图本身不在同一防盗链 location 下,否则可能触发循环匹配
补充建议(提升健壮性)
几个容易忽略但影响实际效果的细节:
- 把防盗链配置放在
server块或具体location块内,不要写在http全局级——避免误作用于其他站点 - 配合
expires缓存指令(如expires 7d;),减少重复校验开销 - 测试时用 curl 模拟不同 Referer:
curl -H "Referer: https://bad-site.com" https://yoursite.com/logo.png










