直接用limit_conn模块可按IP限制并发连接数,防御爬虫攻击:需在http块中定义limit_conn_zone $binary_remote_addr zone=perip:10m,再在server或location中配置limit_conn perip 3,并建议设limit_conn_status 429和limit_conn_log_level error提升可观测性。

直接用 limit_conn 模块就能实现,核心是按客户端 IP 建立连接计数器,超出即拒收新连接,不消耗后端资源,对爬虫类并发攻击很有效。
配置 limit_conn_zone 定义计数区域
在 http{} 块中添加:
limit_conn_zone $binary_remote_addr zone=perip:10m;
说明:
• $binary_remote_addr 是客户端真实 IP 的二进制表示,比 $remote_addr 更节省内存;
• zone=perip:10m 表示分配 10MB 共享内存存储 IP 连接状态,约可容纳 30 万个独立 IP(按平均 32 字节/IP 计算);
• 这一步必须放在 http 级,否则后续指令无法识别该 zone。
在 server 或 location 中启用连接限制
例如在下载或 API 接口路径下限制单 IP 最多 3 个并发连接:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">location /api/ {
limit_conn perip 3;
# 可选:配合限速,防止单连接耗尽带宽
limit_rate 200k;
}
}
注意:
• limit_conn perip 3 表示每个 IP 同时只能建立 3 个活跃连接(HTTP/1.1 下一个 TCP 连接可复用多个请求,但 HTTP/2 下每个流算独立连接,需留意协议差异);
• 若需更宽松策略,比如允许办公网出口 IP(如企业 NAT)最多 20 连接,可结合 $http_x_forwarded_for 或自定义变量,但要注意伪造风险;
• 不建议设为 1,否则正常浏览器多标签页或前端资源并行加载易触发 503。
优化拒绝行为与日志可观测性
让防护更可控、问题更易排查:
- 设置拒绝时返回 429 而非默认 503,便于前端区分限流原因:
limit_conn_status 429; - 降低日志级别避免刷屏,只在真超限时记 error:
limit_conn_log_level error; - 若同时要防全站连接泛滥,可叠加虚拟主机级限制:
limit_conn_zone $server_name zone=perserver:10m;limit_conn perserver 1000;(整台 server 最多 1000 连接)
验证与常见误区提醒
用 ab 或 wrk 测试是否生效:
ab -c 10 -n 50 http://example.com/api/test
观察 access.log 中是否大量出现 429 或 503 状态码。关键注意点:
• 该限制仅作用于已建立的 TCP 连接,不阻断三次握手,所以 SYN Flood 类攻击需靠系统层(如 net.ipv4.tcp_syncookies)或防火墙;
• 若后端使用长连接(如 WebSocket),连接计数会持续占用,需评估 timeout 设置;
• 使用 CDN 或反向代理时,$binary_remote_addr 可能变成 CDN 节点 IP,此时应改用 $http_x_forwarded_for 并确保可信来源头已校验。











