在server块中限制单个ip最大并发连接数,核心是先在http块定义limit_conn_zone $binary_remote_addr zone=perip:10m;,再在server块中配置limit_conn perip 8;,统计活跃tcp连接(含keepalive、http/2),并需代理环境下改用$realip_remote_addr配合realip模块识别真实ip。

在 Server 块中限制单个 IP 的最大并发连接数,核心是把 limit_conn 指令写进 server{} 里,并确保它引用的共享内存区已在 http{} 块中正确定义。
必须先在 http 块定义共享内存区
这一行不能放在 server 或 location 里,否则会启动失败:
- 用
$binary_remote_addr作为键,比$remote_addr更省内存(IPv4 固定 4 字节) - 例如:
limit_conn_zone $binary_remote_addr zone=perip:10m; -
zone=perip:10m表示分配 10MB 共享内存,约支持 16 万~32 万个独立 IP 的状态记录 - 如果日志出现
limit_conn: cannot add connection,说明内存不够,可调大到20m或更高
在 server 块中启用限制
把限流规则直接加在 server{} 内部,作用于该虚拟主机所有请求:
- 例如:
limit_conn perip 8;—— 每个 IP 最多维持 8 个活跃 TCP 连接 - 这个“连接数”包含 keepalive 空闲连接、HTTP/2 多路复用流,不是请求数
- 值设为 1 容易误伤正常用户(比如浏览器多标签页),常见合理范围是 3~10
- 可搭配:
limit_conn_status 503;(超限时返回 503)和limit_conn_log_level error;(方便定位攻击源)
代理环境下要还原真实 IP
如果 Nginx 前面有 CDN、WAF 或负载均衡,$binary_remote_addr 拿到的是代理节点地址,需改用真实客户端 IP:
- 确认已加载
http_realip_module(主流编译版默认包含) - 配置可信上游网段:
set_real_ip_from 10.0.0.0/8;、set_real_ip_from 192.168.0.0/16;等 - 指定头字段:
real_ip_header X-Forwarded-For;(或X-Real-IP,依上游实际为准) - 把共享内存区改为:
limit_conn_zone $realip_remote_addr zone=perip:10m;
建议叠加其他防护手段
单靠连接数限制无法覆盖所有攻击场景:
- 短连接刷量(建连→发请求→断开)不累积连接数,需配合
limit_req控制每秒请求数 - 静态资源路径(如
/static/、/assets/)慎用过低限值,避免 JS/CSS 加载失败 - 可同时配置 server 总连接上限(如
limit_conn server_total 500;),防止单一 IP 占满全部槽位 - 生产环境建议结合防火墙连接新建速率限制(如 iptables 每分钟新建连接 ≤15)











