Nginx防CC攻击限流配置最佳实践:先限连接还是限请求

2026-08-16 36 0

Nginx防CC攻击限流配置最佳实践的第一步,是在http块里同时定义连接数与请求速率两个共享内存区,再按“连接兜底、速率平滑、突发缓冲、白名单豁免”四件套落地。Radware发布的2026年威胁分析报告显示,Web应用与API攻击同比增长187.1%,分布式真实住宅代理让低频CC更难以单机固定阈值拦住,所以这套配置要重新审视。

先给结论:Nginx防CC攻击限流配置最佳实践的三个模块与生效顺序

Nginx防CC攻击限流配置最佳实践是“limit_conn兜并发 + limit_req控速率 + burst/nodelay缓冲突发 + geo/map白名单豁免”四件套。生效顺序:连接被处理且请求头读完后先计入limit_conn并发计数,超过即拒绝;接着进入limit_req漏桶按速率排队,超出突发队列则返回拒绝;白名单IP通过空key直接跳过两个模块。

限连接还是限请求:两类CC流量特征决定先配哪一个

先回答常见疑问:nginx limit_req和limit_conn有什么区别?limit_conn限制“同一瞬间正在处理的连接数”,仅在连接被完整读取请求头后计数;limit_req用漏桶算法限制“每秒允许处理的请求速率”。防御对象不同:慢速连接耗尽型应先用limit_conn压住;短连接高频刷接口型应先用limit_req限速率。现实中两类常混合出现,应两者并举,下表给出判定法则:

流量特征优先配置原因
连接数飙升、连接被占住limit_conn直接压制并发连接,防止句柄耗尽
请求量巨大但连接短limit_req控制速率,防止CPU被打满
两者皆有先conn再req先兜住并发,再平滑速率

慢速连接耗尽型攻击可参考慢速CC攻击防护的专项处理。

limit_conn与limit_req对比示意图

模块一:limit_conn 按单IP并发连接设配额

在http块定义共享内存区,并在server或location块启用:

http {
    limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
    server {
        limit_conn perip_conn 20;
        limit_conn_status 429;
    }
}
  • $binary_remote_addr按单IP计数,共享内存区按key存储状态,官方对limit_req_zone的说明是10m约可存16万个32字节状态,limit_conn的内存估算可参照同一量级,实际以线上key数量压测为准;
  • 若按域名维度限,可将key改为$server_name,但需注意CDN回源IP会集中到少数出口,此时单IP配额要放宽;
  • limit_conn_status默认503,建议改为429更语义化;
  • NAT出口或移动网络下,一个公网IP背后可能有大量真实用户,取值不宜太小,建议先压测观察再定。

模块二:limit_req 漏桶速率与 burst/nodelay 的三种组合效果对比

先看一个可复制片段:

http {
    limit_req_zone $binary_remote_addr zone=perip_req:10m rate=10r/s;
    server {
        location /api/ {
            limit_req zone=perip_req burst=20 nodelay;
        }
    }
}

nginx burst和nodelay参数怎么设置?不同组合行为差异极大,必须按接口特点取舍:

配置写法行为效果适用场景
只配rate超过速率立即拒绝,无缓冲静态资源、可容忍丢请求
burst=N不加nodelay突发请求排队,按固定速率处理,可能超时对延迟不敏感的后台任务
burst=N nodelay配额内突发立即处理,超出立即拒绝动态API、登录接口
burst=N delay=M前M个无延迟,后续平滑限速秒杀、抢购等尖峰场景

注意:不加nodelay而burst设得很大,大量请求排队会导致客户端超时断连,反而比直接返回429更伤体验,所以不要把burst无限调大,建议先小后大逐步放宽。

模块三:白名单与自定义拒绝响应,避免误杀搜索引擎和支付回调

很多运维配完限流后发现正常用户被返回503,这时用geo+map把白名单IP的限流key映射为空字符串,空key不参与计数,从而跳过限流:

geo $whitelist {
    default 0;
    8.8.8.8 1;
    203.0.113.0/24 1;
}
map $whitelist $limit_key {
    1 "";
    default $binary_remote_addr;
}
limit_req_zone $limit_key zone=perip_req:10m rate=10r/s;

同时将拒绝状态码改为429,并用error_page返回可读提示和Retry-After头:

limit_req_status 429;
error_page 429 /rate_limit.html;
location = /rate_limit.html {
    default_type application/json;
    add_header Retry-After 30 always;
    return 429 '{"error":"Too Many Requests"}';
}

这样搜索引擎爬虫(如Googlebot)、支付回调IP都可通过白名单豁免,避免误杀。

配完之后怎么验证:日志字段、压测方法与要盯的三个指标

把Nginx防CC攻击限流配置最佳实践落到线上后,先看这三个指标:拒绝率、延迟排队量、误伤申诉来源。配置完成后,在log_format中加入$limit_req_status,然后按状态分布评估:

log_format main '$remote_addr $request $status $limit_req_status';
  • PASSED表示正常通过,DELAYED表示排队延迟,REJECTED表示被拒绝;
  • awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -20可以快速统计独立IP请求Top榜,从access.log里找出发起CC的IP;
  • 上线初期建议先观察一段时间(dry-run模式),再逐步收紧阈值;
  • 持续盯三个指标:拒绝率(是否过高)、延迟排队量(是否影响体验)、误伤申诉来源(是否有白名单遗漏)。

Nginx限流拦不住的部分:分布式真实IP代理池与拟真Bot的能力边界

回到“nginx能防住cc攻击吗”这个问题:单机Nginx依赖IP维度的共享内存计数,面对海量分布式住宅代理和低频拟真请求时,每个IP频次都低于阈值,即可绕过;同时共享内存区、源站带宽和系统句柄会先被耗尽。Radware 2026年报告显示,大量攻击流量通过真实住宅代理模拟正常用户发起低频CC,所以继续调大burst不是解法。单机限流的能力边界就在这里——它仍是兜底,但无法单独抵御工业化、分布式的CC攻击。分布式低频攻击可参考应用层攻击防护方案。

边缘侧配额前移与源站限流兜底的分工

当攻击源高度分散、单IP频次难以设阈时,需要在边缘侧完成请求完整性校验、Bot识别与跨地域配额前移。RockCloud高防CDN与智能WAF正好承担源站限流之前的那一层清洗职责,而源站Nginx限流规则仍应保留作为最后一道兜底。相关方案可参考Layer 7 DDoS

分层职责可简化为下表:

层级职责手段
边缘请求完整性校验、Bot识别、配额前移高防CDN、智能WAF
源站单IP并发与速率兜底Nginx limit_conn/req

若日志显示攻击源已高度分散,可在RockCloud基石云一侧做配额前移,源站规则保留兜底,边缘侧可启用智能WAF防护

常见问题

nginx limit_req和limit_conn有什么区别?

limit_conn限制并发连接数,仅当连接被完整读取请求头后才计数;limit_req基于漏桶算法限制请求速率。连接数暴涨优先配limit_conn,请求量巨大优先配limit_req,两者通常要配合使用。

nginx限流配置后正常用户被返回503怎么办?

先用geo+map将白名单IP的key映射为空字符串以跳过计数,再将limit_req_status改为429,配合error_page返回可读提示。检查是否把CDN回源IP或NAT出口IP误伤,必要时放宽burst或rate。

nginx burst和nodelay参数怎么设置?

不加nodelay时,突发请求会排队延时,可能超时断连;加nodelay后突发请求在配额内立即处理,超出立即拒绝。建议动态接口用burst小值加nodelay,尖峰场景用delay参数实现两阶段限速,不要无限调大burst。

nginx能防住cc攻击吗?

单机Nginx能防住部分基于单IP高频或连接耗尽的CC,但面对分布式住宅代理的低频拟真攻击作用有限。它应作为兜底,与边缘高防CDN和WAF配合,才能形成完整防线。

nginx限流按IP限还是按域名限?

按IP限可精准控制单客户端,但NAT出口会误伤多人共用IP;按域名限可保护整个站点,但无法区分单个攻击者。生产环境通常按IP限,并对白名单和CDN回源IP做特殊处理。

怎么从access.log里找出发起CC的IP?

使用awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -20统计高频IP,再结合状态码和请求路径筛选。配置log_format加入$limit_req_status,可区分正常、延迟和拒绝的请求来源。

相关文章

动态验证码在抗CC攻击中的实践应用:哪些路径弹、什么阈值触发
如何防止源站真实IP暴露:5个泄漏点自查与回源收口
Nginx防CC攻击限流配置最佳实践:先限连接还是限请求
慢速CC攻击防护怎么做?连接层四步定位与限流
Layer 7 DDoS 攻击威胁解析:2026 年企业应用层安全防护实践指南
2026年DDoS威胁工业化升级:企业如何借助高防CDN构建无感清洗与应用层防护?

评论(0)

暂无评论

发布评论