nginx精准防盗链需将valid_referers与if严格限定在正则匹配静态资源的location块内,白名单含none、blocked及域名,动作推荐return 403并验证移动端无referer场景。

在 Nginx 中实现精准防盗链,关键不是全局加规则,而是把 valid_referers 和 if 判断严格限定在匹配目标文件类型的 location 块内。这样既能拦截盗链,又不会误伤 HTML、API 或登录接口等动态请求。
只对静态资源后缀生效
用正则表达式明确锁定要保护的文件类型,避免规则扩散到整个站点:
- 推荐写法:
location ~* \.(jpg|jpeg|png|gif|webp|css|js|woff2?|ttf|eot|svg|mp4|pdf|zip)$ -
~*表示忽略大小写匹配,覆盖JPG、Png等常见变体 - 不建议用
location /static/这类路径前缀——如果目录下混有 HTML 或 JSON,就可能被意外拦截 - 确保该
location块内已配置root或alias,否则文件 404 了,防盗链也就没意义
白名单必须覆盖真实访问场景
合法 Referer 不只是你的域名,还包括多种常见“无来源”情况:
-
none:用户直接输入图片 URL、从书签打开、HTTPS 页面引用 HTTP 资源时 Referer 为空 -
blocked:某些浏览器隐私模式、企业代理或防火墙会清空 Referer,值存在但协议头丢失 -
example.com和www.example.com需分开写,Nginx 不自动归一化 -
*.example.com可匹配 CDN、子站等,但不匹配example.com本身 - 多个域名用空格分隔,如:
valid_referers none blocked example.com www.example.com *.cdn.example.com;
拦截动作要语义清晰且可追踪
判断非法引用后,返回行为直接影响日志分析和用户体验:
- 首选
return 403;:状态码准确,CDN 缓存、爬虫、监控系统都能识别为拒绝 - 避免
rewrite ... break;跳转到提示图:它返回 200,掩盖真实拦截,还可能引发循环或路径错误 - 若需展示友好图片,用
error_page 403 =200 /static/forbidden.png;+internal;location,保持状态码为 403 同时呈现内容 - 可在该 location 内加日志格式,单独记录盗链尝试:
log_format referer_deny '$remote_addr [$time_local] "$request" $status $invalid_referer';
验证是否真正生效
配置 reload 后,用 curl 快速确认不同 Referer 的响应:
- 正常访问(空 Referer):
curl -I http://yoursite.com/img/logo.png→ 应返回 200 - 合法引用:
curl -I -e "https://example.com" http://yoursite.com/img/logo.png→ 应返回 200 - 模拟盗链:
curl -I -e "https://bad-site.com" http://yoursite.com/img/logo.png→ 应返回 403 - 注意移动端 WebView、PWA 加载资源时常无 Referer,测试时别漏掉这类场景











