nginx 防 cc 攻击需同时配置 limit_req 限频和 limit_conn 限连:前者用 limit_req_zone 定义请求速率池,后者用 limit_conn_zone 定义连接数池,并在 server 或 location 中并行启用,配合 burst、nodelay 及合理 zone 大小,才能有效拦截高频请求与空闲连接攻击。

用 Nginx 防 CC 攻击,光靠限速或光限连接都不够。CC 攻击常分两类:一类是高频刷接口(比如每秒几十次 POST /login),靠 limit_req 拦;另一类是建大量空闲连接卡住服务(比如开 200 个长连接不发数据),靠 limit_conn 拦。两者配合,才能覆盖攻击的“频率+连接”双路径。
在 http 块中定义两个共享内存区
必须先声明资源池,Nginx 才能跟踪每个 IP 的状态:
-
请求速率池:用
limit_req_zone $binary_remote_addr zone=cc_req:10m rate=15r/s;→ 基于二进制 IP 地址建桶,10MB 内存支持约 16 万个独立 IP,允许每秒 15 个请求 -
连接数池:用
limit_conn_zone $binary_remote_addr zone=cc_conn:10m;→ 同样按 IP 统计当前活跃 TCP 连接数,不设速率,只记数量
在 server 或 location 中同时启用双限制
单加一个没用,要并行生效才形成夹击:
-
limit_req zone=cc_req burst=30 nodelay;→ 允许突发 30 个请求(比如页面加载带多个资源),超了立刻 503,不排队耗 CPU -
limit_conn cc_conn 8;→ 同一 IP 最多保持 8 个并发连接。攻击者开 50 个 curl 占位?第 9 个就直接拒绝 - 建议统一返回码:
limit_req_status 429;和limit_conn_status 429;→ 比默认 503 更语义清晰,也方便前端做重试控制
针对敏感路径做更严策略
首页可宽松,但登录、下单、API 接口必须收紧:
- 登录页
location = /login:rate 设为 3r/s,burst=2,limit_conn 仅 2 → 正常用户点一次登录,失败后重试一两次没问题;机器人扫号直接卡死 - API 接口
location /api/:rate=5r/s + burst=5 + limit_conn 5 → 兼顾 App 短时批量请求,又防脚本轮询 - 静态资源如
location ~* \.(js|css|png)$可放宽甚至不限连,但建议关日志减压
注意几个关键细节
参数配错,防护就形同虚设:
-
burst 不是并发上限:它是“漏桶里最多能堆几个请求”,和
limit_conn的连接数完全无关 - nodelay 要搭配 burst 用:否则 burst=30 时,Nginx 会把多余请求匀到后续 30 秒慢慢处理,反而助长攻击
- zone 大小别抠门:10MB 是底线,IP 量大时建议 20–30MB,否则键冲突导致漏放
-
不要只在 server 块配:若后端有多个 location(如 /、/admin、/api),需在每个需要防护的位置单独写
limit_req和limit_conn











