Nginx入口层对登录接口实施精准限流:独立定义login_limit内存区,按IP每分钟3次+突发2次,内网IP放宽至burst=20,并配合日志监控与429响应。

针对登录接口做高强度防刷,核心是把限流控制在 Nginx 入口层,不依赖后端逻辑,响应快、拦截准、资源开销低。重点不是“越严越好”,而是“严得合理”——既要挡住暴力破解和脚本扫号,又不能误伤真实用户的手抖、重试或弱网重发。
单独定义登录专用限流区域
在 http 块中为登录接口建独立内存区,避免和其他路径共用规则:
http {
limit_req_zone $binary_remote_addr zone=login_limit:5m rate=3r/m;
limit_conn_zone $binary_remote_addr zone=login_conn:5m;
}
- $binary_remote_addr:用二进制格式存 IP,查得快、省内存
- rate=3r/m:每分钟最多 3 次,贴合人工操作节奏;比 r/s 更难被机器绕过(比如每秒 1 次,攻击者可错峰提交)
- 5m 内存:够存约 8 万个 IP,对登录这种低频路径足够,也减少资源占用
在真实登录路径精准启用限流
必须匹配实际接口路径,比如 /api/login、/auth/login 或 /login,不要写在 / 或 /api/ 这类宽泛 location 下:
location /api/login {
limit_req zone=login_limit burst=2 nodelay;
limit_conn login_conn 2;
limit_req_status 429;
proxy_pass http://backend;
}
- burst=2:允许短暂突发(比如点错两次),但无法持续高频提交
- nodelay:超出即刻拒绝,不排队——防止攻击者靠“占位”耗尽队列资源
- limit_conn 2:每个 IP 最多维持 2 个并发 TCP 连接,堵住开多线程/多进程并发爆破的路
- limit_req_status 429:返回标准 HTTP 429,语义清晰,不暴露后端状态,也方便前端统一处理
加白名单绕过内部调试和可信来源
避免自己测试或运维时被误拦,用 geo + map 实现 IP 分级控制:
geo $trusted_ip {
default 0;
192.168.10.0/24 1;
10.0.5.20 1;
}
map $trusted_ip $login_burst {
1 20;
0 2;
}
limit_req_zone $binary_remote_addr zone=login_limit:5m rate=3r/m;
limit_req zone=login_limit burst=$login_burst nodelay;
- 内网段和运维 IP 被标记为 trusted_ip=1,走宽松策略(burst=20)
- 其他所有 IP 默认按严格策略执行(burst=2)
- 规则动态生效,无需 reload Nginx
配套建议:日志与监控不可少
光有配置不够,得知道它是否真起作用:
- 开启 limit_req_log_level warn,让超限请求记入 error log,便于排查误拦
- 在 access log 中加 $limit 和 $limit_rate 变量,观察各 IP 实际触发情况
- 配合 Prometheus + nginx-vts-exporter 或自定义日志解析,设置告警:比如 5 分钟内某 IP 触发限流超 10 次,自动通知并考虑临时封禁


















