Nginx防盗链配置,防止API接口被恶意盗刷流量
API接口被恶意盗刷流量,通常是其他网站或脚本直接请求你的接口,导致带宽和服务器资源被白白消耗。
Nginx 自带防盗链模块,可以通过校验请求头中的 Referer 字段,只允许本站或指定域名调用接口,从而拦截跨站盗用。
本文按零基础用户的视角,讲清楚从配置到验证的完整流程。
为什么 API 接口必须做防盗链
普通页面防盗链主要是防止图片、文件被外站引用,而 API 接口更需要防盗链。
接口一旦被第三方页面或脚本直接调用,每次请求都会消耗你的服务器带宽和计算资源。
如果对方刷量频繁,轻则账单上涨,重则接口被拖垮。
Nginx 的 valid_referers 指令是官方内置模块提供的功能,不用额外安装,配置后即可对请求来源做白名单过滤。
配置前的准备事项
开始前你需要确认以下信息:
- 服务器已安装 Nginx,并知道
nginx.conf或网站配置文件的路径(常见为/etc/nginx/conf.d/或/usr/local/nginx/conf/)。 - 准备允许调用接口的域名列表,例如你自己的站点
www.example.com,以及可能用到的子域名。 - 确认接口路径前缀,比如所有
/api/开头的请求都需要保护。
如果你用的是宝塔面板,可以直接在“网站 -> 设置 -> 配置文件”里修改 server 块,流程类似。
核心配置:用 valid_referers 过滤请求来源
在 Nginx 配置文件中的 server 块里,添加或修改如下内容:
location /api/ {
valid_referers none blocked server_names www.example.com example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
这段配置的含义是:
valid_referers定义哪些来源是合法的。none表示允许请求头中不携带 Referer,blocked表示允许被防火墙或代理隐藏后的 Referer,server_names表示当前站点域名本身,后面也可以写具体的域名和通配符域名。- 当请求中的 Referer 不在合法列表里时,Nginx 会设置
$invalid_referer为 1,此时直接返回 403 状态码,拒绝访问。
修改后测试配置并重载:
nginx -t
nginx -s reload
如果 nginx -t 报错,通常是语法错误或 if 指令放错位置,请对照官方文档检查。
如何验证防盗链是否生效
配置完成后,建议用 curl 直接模拟请求,检查不同 Referer 下的返回结果。
先测试不带 Referer 的请求(none 允许时不拦截):
curl -I http://你的域名/api/user/info
如果返回 200,说明没有 Referer 的请求被放行。
再测试伪造来源的请求:
curl -I -H "Referer: http://evil.com" http://你的域名/api/user/info
如果返回 403,说明防盗链规则已经生效。
最后测试合法来源:
curl -I -H "Referer: http://www.example.com/page" http://你的域名/api/user/info
正常情况下应返回 200。
注意浏览器缓存和 HTTP/2 的响应头可能影响判断,建议多测几次。
常见误伤和避坑建议
防盗链配置最容易踩的坑是误伤 App 客户端请求。
很多手机应用、小程序或后端服务调用接口时不会带 Referer,如果你把 none 去掉,这些合法请求会被全部拦截。
建议先保留 none,再通过日志观察来源分布,后续再收紧策略。
还要注意 *.example.com 通配符只匹配子域名,不匹配根域名 example.com,所以根域名要单独写。
如果接口需要支持来自空 Referer 的请求,务必加上 none,否则 curl 和某些 HTTP 客户端会直接 403。
另外,if 指令块里最好只使用 return 或 rewrite,不要写复杂的多个指令,否则可能导致 Nginx 行为异常。
对于更严格的场景,可以结合 map 模块或使用 OpenResty 做更精细的校验,但一般情况下 valid_referers 已经足够。
最后提醒:Referer 校验只能防君子不能防小人,因为请求头可以伪造。
如果接口数据特别敏感,建议再叠加 IP 限流、Token 鉴权或签名机制,多层防护才更可靠。
配置完成后,建议观察一周的 Nginx 访问日志,确认没有误伤正常用户,再决定是否进一步缩小白名单。
如果你正在处理 Nginx 防盗链配置、防止 API 接口被恶意盗刷流量,先按本文步骤完整执行,再根据自己业务的 Referer 特征微调即可。
遇到问题时,优先检查访问日志中的 $http_referer 值,能最快定位拦截原因。