nginx可通过valid_referers识别盗链并结合map指令实现“盗链即限速”:http块中定义valid_referers生成$invalid_referer,再用map将其映射为限速值(如盗链设50k、合法设0),location中通过limit_rate $盗链限速生效,配合limit_rate_after优化首段体验,并建议叠加limit_conn防多连接盗取。

Nginx 本身不支持“对盗链请求单独限速”,但可以通过逻辑组合实现:先用 valid_referers 识别盗链请求,再用 map 将其标记为低速率,最后在 location 中通过 limit_rate 引用该变量。这样既保留合法来源的正常体验,又让盗链者下载缓慢、难以实用,从而实质性降低其带宽消耗。
✅ 核心思路:用 map 实现“盗链即限速”
Nginx 的 limit_rate 不直接响应 Referer 判断,但 map 指令可基于 $invalid_referer(由 valid_referers 自动生成的布尔变量)映射限速值。这是最干净、安全且高效的做法。
http {
# 定义防盗链白名单,并生成 $invalid_referer(1=非法,0=合法)
valid_referers none blocked server_names *.yourdomain.com;
# 根据是否盗链,动态设置限速值
map $invalid_referer $盗链限速 {
1 "50k"; # 盗链者:仅 50KB/s(约 400Kbps),基本无法流畅下载)
0 "0"; # 合法来源:不限速(0 表示关闭限速)
}
server {
location ~ \.(zip|iso|pdf|mp4|rar|dmg)$ {
root /var/www/files;
# 关键:启用动态限速
limit_rate $盗链限速;
# 可选:前 2MB 不限速,避免首屏/预览卡顿
limit_rate_after 2m;
}
}
}
⚠️ 注意:
valid_referers必须放在http块(全局生效),map也必须在http块中定义;limit_rate和limit_rate_after必须写在同一location内,且limit_rate_after要在limit_rate之前。
?️ 进阶增强:叠加防御层级
单纯限速还不够——盗链者可能开多个连接刷带宽。建议配合以下措施:
-
限制每个 IP 并发下载数(防多线程盗取)
limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn perip 2; # 每个 IP 最多 2 个并发下载连接
-
对盗链返回替代内容(可选)
若你更倾向直接拦截,可在盗链时返回一张小图或提示页:if ($invalid_referer) { return 302 https://yourdomain.com/forbidden.png; }❗注意:
if在location中慎用;若需返回静态资源,推荐用error_page 403 = /forbidden.png;+rewrite或try_files更稳妥。 -
排除搜索引擎和空 Referer(避免误伤)
valid_referers支持none(直接访问)、blocked(被防火墙过滤的 Referer)、以及正则匹配。合理配置可放行百度、Google 等爬虫:valid_referers none blocked *.yourdomain.com ~\.baidu\. ~\.google\. ~\.bing\.;
? 效果对比(典型场景)
| 请求来源 | Referer 是否合法 | 下载速度 | 实际影响 |
|---|---|---|---|
| 你自己的网页 | ✅ | 不限速 | 正常高速下载 |
| 微信内嵌页面 | ✅(含 micromsg) |
不限速 | 用户体验不受损 |
其他网站 @@##@@
|
❌ | 50KB/s | ZIP 下载要十几分钟,基本放弃 |
| curl -H "Referer:" | ❌(空 Referer) | 50KB/s | 自动化脚本效率骤降 |
| 直接浏览器输入 URL | ✅(none) |
不限速 | 保留真实用户直接访问能力 |
? 验证是否生效
-
用
curl模拟盗链请求:curl -H "Referer: https://evil-site.com" -o /dev/null -s -w '%{speed_download}\n' https://yoursite.com/file.zip输出应明显低于 100KB/s(如
0.052MB/s ≈ 52KB/s)。 查看 Nginx access log,确认
$invalid_referer字段为1,且响应时间显著拉长。检查
nginx -t && nginx -s reload无报错,避免因map语法错误导致整站限速失效。
不复杂但容易忽略:限速只作用于单连接,真正防住盗链,靠的是“慢 + 少 + 不可用”三层压制。











