需分两层实现:一、用limit_conn在tcp连接层面限制单ip并发数,如limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn perip 5; 二、用limit_req在http请求层面控速率,如limit_req_zone $binary_remote_addr zone=rate:10m rate=10r/s; limit_req zone=rate burst=20 nodelay;。

Linux 限制单个 IP 的最大并发连接和速率,需分两层实现:**连接数控制**(TCP 连接层面)和**请求速率控制**(HTTP 请求层面),二者目标不同、机制不同,不能互相替代。
一、用 Nginx 限并发连接(limit_conn)
限制的是「已建立、未关闭」的 TCP 连接数,适用于防连接耗尽、慢速攻击、长轮询滥用等场景:
-
必须在 http{} 块顶层定义 zone:
limit_conn_zone $binary_remote_addr zone=perip:10m;——$binary_remote_addr比$remote_addr更省内存;10m 内存约支持 16 万个独立 IP 计数 -
在 server 或 location 中启用规则:
limit_conn perip 5;——表示单个 IP 最多维持 5 个并发连接;超限时默认返回 503 -
注意生效前提:
仅对已完成请求头解析、尚未返回响应的连接计数;HTTP/2 下效果减弱(一个连接复用多 stream);若走 CDN,需配合
set_real_ip_from和real_ip_header X-Forwarded-For修正源 IP
二、用 Nginx 限请求速率(limit_req)
限制的是单位时间内的 HTTP 请求新建频率,适合防爬、爆破、CC 攻击:
-
先定义速率区域:
limit_req_zone $binary_remote_addr zone=rate:10m rate=10r/s;——每秒最多 10 个请求,超出进入 burst 队列 -
绑定到具体路径并配置缓冲:
limit_req zone=rate burst=20 nodelay;——允许最多 20 个请求排队;nodelay表示不延迟处理达标请求,超限立即拒 -
关键细节:
burst不是“额外放行”,而是令牌桶溢出缓冲;无nodelay时,排队请求会按固定间隔(如 100ms)释放;建议搭配limit_req_status 429;提供明确反馈
三、用 firewalld 做基础连接速率限制(系统级)
适合在应用层(如 Nginx)之前做第一道过滤,针对 SYN 新建连接限速:
-
添加 rich rule 限新建连接:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="80" protocol="tcp" limit value="5/s" accept'——每秒最多放行 5 个新 TCP 连接(SYN 包),超限丢弃(不回 RST) -
注意适用范围:
仅作用于
NEW状态连接;不区分请求内容;必须加--permanent才持久化;重启 firewalld 后需重载:firewall-cmd --reload
四、常见误区与避坑提示
避免配置失效或策略错位:
-
limit_conn和limit_req不能混用在同一 location 且逻辑冲突——前者卡连接入口,后者控请求频次,应分层部署(如全站限连 + API 路径限速) -
iptables -m connlimit只能控并发连接数,不是每秒连接数;短连接攻击(快速建连断连)下几乎无效 - 不要把
limit_conn和limit_rate放同一 location:前者让连接排队等待,后者拖慢响应,容易导致连接长期占用、新请求被持续拒绝 - 验证是否生效:用
curl -I http://your-site/多次触发,观察响应码;查 Nginx error log(需配limit_conn_log_level warn;);用ss -tn src IP查实时连接数











