limit_conn模块通过限制单个IP并发TCP连接数防御CC攻击,需先在http块用limit_conn_zone定义共享内存区(如$binary_remote_addr zone=conn_per_ip:10m),再在server或location中用limit_conn conn_per_ip 10启用,仅统计ESTABLISHED状态连接。

使用 Nginx 的 limit_conn 模块可以有效限制单个客户端 IP 的并发连接数,是防御简单 CC(Challenge Collapsar)攻击的基础手段之一。它不依赖请求内容或频率,而是直接控制 TCP 连接数量,在连接建立阶段就拦截超额请求,开销低、生效快。
配置 limit_conn_zone 定义共享内存区域
必须先定义一个用于存储连接状态的共享内存区域,Nginx 才能跨 worker 进程统计连接数:
http {
# 基于 $binary_remote_addr 限流(精简 IPv4/IPv6 地址为固定长度二进制,节省内存)
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
}说明:
- zone=conn_per_ip:10m 表示创建名为 conn_per_ip 的共享内存区,大小为 10MB;
- $binary_remote_addr 比 $remote_addr 更高效,避免字符串哈希冲突和内存浪费;
- 10MB 约可存储 16 万个 IP 的连接状态(按默认每个条目约 64 字节估算)。
在 server 或 location 中启用 limit_conn
在需要防护的上下文中引用已定义的 zone,并设定每个 IP 允许的最大并发连接数:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">location / {
# 每个 IP 最多保持 10 个并发连接
limit_conn conn_per_ip 10;
# 可选:配合 limit_req 防止高频短连接(如刷首页)
limit_req zone=req_per_ip burst=20 nodelay;
proxy_pass http://backend;
}}
关键点:
- limit_conn 限制的是当前活跃的 TCP 连接数(即处于 ESTABLISHED 状态的连接),不是请求数;
- 若后端是长连接服务(如 WebSocket、HTTP/2 流),需根据实际业务合理设值,避免误伤正常用户;
- 多个 limit_conn 指令会叠加生效(例如 server 和 location 同时配置,则取更严格的那个)。
区分可信来源与真实客户端 IP
若服务器前有 CDN、WAF 或反向代理(如 Nginx → Nginx),$binary_remote_addr 将始终是上一跳地址(如 CDN 节点 IP),导致限流失效:
- 确保
real_ip_header和set_real_ip_from正确配置,使 Nginx 能识别真实客户端 IP; - 推荐用
$binary_remote_addr替代$remote_addr,即使经过代理也应同步更新该变量; - 若使用 Cloudflare,需开启
real_ip_header CF-Connecting-IP;并添加其 IP 段到set_real_ip_from。
验证与调试技巧
上线前务必验证是否生效:
- 用
ab -n 100 -c 50 http://example.com/模拟 50 并发请求,观察返回状态码(超限连接会直接返回 503); - 检查 Nginx 错误日志:
limiting connections by zone "conn_per_ip"表示触发限流; - 通过
nginx -t校验语法,重启后用ss -tn | grep :80 | wc -l辅助观察连接数趋势。
注意:limit_conn 对 HTTPS 的 SNI 连接、HTTP/2 多路复用也有效,但无法区分同一 IP 下不同用户的浏览器会话——如需更细粒度控制,需结合 cookie 或 token 配合 limit_req 使用。










