最直接有效的方式是用Nginx的limit_conn指令配合limit_conn_zone,前者执行限制、后者定义共享内存区存储IP连接状态;必须在http块顶层配置limit_conn_zone $binary_remote_addr zone=perip:10m,再在server或location中用limit_conn perip N启用,代理环境需配合real_ip_module识别真实IP。

最直接有效的方式是用 Nginx 的 limit_conn 指令,它专为限制单个 IP 并发 TCP 连接数而设计,不依赖额外组件、不阻塞工作进程,且对 keepalive、WebSocket 等长连接场景准确生效。
用 Nginx limit_conn 实现精准限连
必须配合 limit_conn_zone 使用,二者缺一不可。后者定义共享内存区并存储每个 IP 的连接计数状态,前者只是执行判断动作:
- 在 http{} 块顶层(不能放在 server 或 location 内)添加:
limit_conn_zone $binary_remote_addr zone=perip:10m;
推荐用$binary_remote_addr(二进制格式),比$remote_addr更省内存,支持 IPv6 - 在 server{} 或 location{} 块中启用限制:
limit_conn perip 5;
表示每个 IP 最多维持 5 个已建立、未关闭的 TCP 连接 - 若前端有 CDN(如 Cloudflare),需先配置
set_real_ip_from和real_ip_header X-Forwarded-For,否则统计的是 CDN 节点 IP
iptables 只能控并发,不能控“每秒”建连
iptables 的 connlimit 模块只能限制当前 ESTABLISHED 连接数,不是速率,也不适用于短连接风暴:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
- 例如防 SSH 爆破:
sudo iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP - 它只统计“同时在线”的连接,攻击者快速建连断连时完全无效
- 若要真正限制新建连接速率(如 10 连接/秒),得用
-m limit或-m hashlimit,但这是速率控制,不是连接数硬限
系统级与服务级资源需同步调优
即使规则生效,底层资源不足也会导致限流失效或服务崩溃:
- 修改用户级文件描述符上限:
编辑/etc/security/limits.conf,添加www-data soft nofile 65536www-data hard nofile 65536
(替换为实际运行 Nginx 的用户) - systemd 服务需单独配置:
运行sudo systemctl edit nginx.service,加入[Service]LimitNOFILE=65536 - 验证是否生效:
cat /proc/$(pgrep nginx)/limits | grep "Max open files"
RabbitMQ、MySQL 等服务自身不支持 IP 级连接限制
这类中间件没有内置 per-IP 连接数配置项,必须靠外围拦截:
- RabbitMQ:前置 HAProxy 或 Nginx,用
stick-table或limit_conn控制;或用 iptables + hashlimit 做粗粒度压制 - MySQL:无法按 IP 限连,只能通过
max_connections全局控制,或结合防火墙策略+应用层连接池管理 - 本质原因:连接接纳发生在 TCP accept 阶段,此时协议层尚未解析源 IP,无法做细粒度判断

















