Nginx通过limit_req_zone与limit_req实现基于IP的分层速率限制,主区域限15r/s+burst=30,登录等敏感路径严控至1–3r/s+burst=1–2,并支持可信代理白名单及连接数限制等协同防护。

Nginx 作为 Node.js 应用的前置反向代理,是防御 DDoS(尤其是应用层 CC 攻击)的第一道防线。关键不是“堵死所有流量”,而是对单个 IP 实施合理、分层、可调的请求速率限制,既拦住恶意刷量,又不误伤真实用户。
核心思路:用 limit_req_zone + limit_req 控制每秒请求数,结合 burst 和 nodelay 精细控制响应行为
定义全局限流区域(放在 http 块中)
这是限流的基础配置,必须先声明共享内存区,用于记录每个客户端的请求计数:
http {
# 按客户端IP做速率限制(二进制地址更省内存)
limit_req_zone $binary_remote_addr zone=ip_rate:10m rate=15r/s;
<pre class="brush:php;toolbar:false;"># 可选:为登录/注册等高敏路径单独设更严策略
limit_req_zone $binary_remote_addr zone=login_rate:10m rate=3r/s;
upstream node_backend {
server 127.0.0.1:3000; # 假设 Node.js 监听在 3000
keepalive 32;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass https://www.php.cn/link/b2673dbaad4eaf3320af4349532739d2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 启用主限流策略
limit_req zone=ip_rate burst=30 nodelay;
}
}}
说明:
-
rate=15r/s:基础阈值,适合多数 Web 应用(如博客、管理后台),API 服务可调至 5–20r/s,静态资源可放宽 -
burst=30:允许最多 30 个请求排队缓冲,应对短时合法高峰(比如页面加载带多个 JS/CSS 请求) -
nodelay:超出 burst 的请求立即返回 503,不排队等待——防止攻击者用慢速请求耗尽队列 -
zone=ip_rate:10m:10MB 内存可存储约 16 万个 IP 的状态,一般够用;若并发 IP 极多,可加大到 20m
对敏感路径做强化限流(如登录、注册、支付)
这些接口极易被暴力破解或自动化攻击,需更严格策略:
location = /login {
limit_req zone=login_rate burst=2 nodelay;
limit_req_status 429; # 返回 429 Too Many Requests 更语义化
proxy_pass https://www.php.cn/link/b2673dbaad4eaf3320af4349532739d2;
}
<p>location = /api/auth/register {
limit_req zone=login_rate burst=1 nodelay;
proxy_pass <a href="https://www.php.cn/link/b2673dbaad4eaf3320af4349532739d2">https://www.php.cn/link/b2673dbaad4eaf3320af4349532739d2</a>;
}建议:登录类接口通常设 rate=1–3r/s,burst=1–2,几乎不允许突发;同时配合 Node.js 层的验证码或设备指纹增强效果。
绕过限流的白名单(如有负载均衡或内网调用)
如果 Nginx 前还有 LVS、Cloudflare 或其他代理,$binary_remote_addr 会变成代理 IP。此时需用 $http_x_forwarded_for 并配合 geo + map 做可信源识别:
geo $is_trusted {
default 0;
10.0.0.0/8 1; # 内网段
192.168.0.0/16 1;
203.0.113.10 1; # Cloudflare 回源 IP(需替换为实际)
}
<p>map $is_trusted $limit_key {
0 $binary_remote_addr;
1 "";
}</p><p>limit_req_zone $limit_key zone=trusted_rate:10m rate=50r/s;然后在 location 中使用 limit_req zone=trusted_rate,确保内部调用和可信 CDN 不被误限。
配套防护建议(不止于限流)
单靠速率限制不够,建议组合使用:
-
连接数限制:加
limit_conn_zone $binary_remote_addr zone=conn_ip:10m;和limit_conn conn_ip 10;,防连接耗尽型攻击 -
非法方法拦截:在 server 块中加
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) { return 444; } -
日志标记限流事件:用
log_format记录$limit_rate和$limit_conn状态,便于分析攻击特征 - Node.js 层协同:Nginx 限流后仍应保留基础校验(如 JWT 过期、频率兜底),避免绕过代理直连 Node
不复杂但容易忽略细节。真正起效的关键在于:阈值要贴合业务节奏、burst 要留出合理弹性、白名单要覆盖真实架构拓扑。


















