CC防护的核心逻辑就是对单个IP的请求频率和同一时间段内的并发连接数分别设定上限,当任一维度触发阈值时就进行拦截或限流。具体做法是:在Web服务器或WAF层面,针对每个来源IP设定"每秒请求数(QPS)"和"同时活跃连接数"两条独立的判断线,比如设置单IP每秒不超过20次请求、同时并发不超过5个连接,超过就直接返回429或触发验证码。这两个维度缺一不可——只看速率会漏掉慢速高频攻击,只看并发会放过短时脉冲式攻击,双维度组合才能精准识别真实的CC攻击行为。
很多运维人员在配置CC防护时只盯着请求速率,觉得限制了QPS就万事大吉。但实际上,攻击者可以把请求频率压得很低,比如每秒只发3次,但同时维持几百个并发连接占满服务器资源。反过来,也有人把并发数设得很高,却忽略了短时间内的请求脉冲。所以,真正有效的CC防护必须把"速率"和"并发"当作两个独立的控制变量来管理,而不是混为一谈。
一、为什么必须用双维度而不是单维度先说清楚单维度防护的漏洞。如果你只限制请求速率,比如每秒30次,攻击者完全可以用分布式的方式,每个节点每秒只发5次,总量轻松突破防线。而且慢速攻击(Slowloris类)本身就不追求高频率,而是靠长时间占用连接来拖垮服务。反过来,如果你只限制并发数,比如最多10个连接,攻击者可以在10个连接内疯狂发请求,服务器的CPU和带宽照样被打满。
双维度阈值的本质是从"时间密度"和"空间占用"两个角度同时约束。速率维度控制的是单位时间内的请求密度,并发维度控制的是同一时刻的资源占用量。两个条件是"或"的关系——满足其中任何一个就触发防护动作。这种设计能覆盖绝大多数CC攻击场景,包括高频脉冲、慢速占用、分布式低频等各种变体。
二、请求速率阈值的设定方法请求速率通常用QPS(Queries Per Second)或RPM(Requests Per Minute)来衡量。设定这个值不能拍脑袋,需要基于正常业务流量的统计数据。一般建议的做法是:先采集7到14天的正常访问日志,计算出每个IP或每个用户群体的平均请求频率和峰值,然后在峰值基础上乘以1.5到2倍作为阈值。比如正常用户峰值是每秒15次,那就设25到30次作为触发线。
对于不同类型的接口,速率阈值应该差异化设置。登录接口、搜索接口、API接口的正常频率差异很大,不能一刀切。登录接口可能正常用户一分钟才请求一两次,但搜索接口可能一秒就有好几次。所以最好的做法是按URL路径或接口类型分别配置速率限制规则。
以下是一个基于Nginx的速率限制配置示例,限制单个IP每秒10次请求:
http {
# 定义限流区域,以IP为key,10m内存大约能存16万个IP
limit_req_zone $binary_remote_addr zone=cc_limit:10m rate=10r/s;
server {
location / {
# 应用限流,burst=20表示允许短时突发20个请求
# nodelay表示突发请求不延迟处理,直接拒绝超出部分
limit_req zone=cc_limit burst=20 nodelay;
}
}
}
这里的burst参数很关键,它允许短时间内的合法突发流量通过,避免正常用户因为瞬间操作(比如页面加载同时发出多个请求)被误杀。nodelay则确保超出burst的请求被立即拒绝而不是排队等待,这在CC防护场景下更合适。
三、并发数阈值的设定方法并发数指的是同一个IP同时与服务器建立的活跃连接数量。这个指标比速率更难被攻击者绕过,因为它直接反映了资源占用情况。设定并发阈值同样需要基于正常业务数据,一般建议参考正常用户的最大并发连接数。普通Web浏览场景下,一个用户同时打开的连接通常不超过6到10个,所以可以把单IP并发上限设在10到15之间。
在Nginx中可以通过limit_conn模块来限制并发连接数:
http {
# 定义并发限制区域,以IP为key
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location / {
# 限制单个IP最多10个并发连接
limit_conn conn_limit 10;
}
}
}
需要注意的是,limit_conn限制的是正在处理中的连接,而不是已经建立的TCP连接。对于使用Keep-Alive的场景,这个限制是有效的。如果你的业务本身就需要较高的并发(比如大文件下载、视频流),那就需要对特定路径豁免或者提高阈值。
四、双维度联动的实战策略真正落地的时候,速率和并发两个维度不是孤立运行的,而是需要联动判断。最常见的策略是"任一触发即拦截",也就是只要速率超限或者并发超限,就执行防护动作。防护动作可以分级:第一级是返回429状态码并要求等待;第二级是触发人机验证(比如滑块验证码);第三级是直接拉黑IP一段时间。
在WAF产品中,通常可以通过规则引擎实现这种联动。比如设置规则:当"单IP请求速率 > 30次/秒" OR "单IP并发连接 > 15"时,触发限流策略。有些高级WAF还支持基于滑动窗口的动态阈值,比如统计过去60秒的平均速率,而不是固定的瞬时速率,这样能更好地适应流量波动。
还有一个容易被忽略的点:要区分"单IP"和"单用户"两个粒度。纯按IP限制会误伤共享IP的用户(比如公司出口、运营商NAT),所以更精准的做法是结合Cookie、Session、User-Agent等信息做多维度识别。但在纯CC防护场景下,按IP限制仍然是最基础也最有效的第一道防线。
五、阈值调优的核心原则阈值设定没有万能数字,必须根据实际业务不断调整。核心原则有三条:第一,先松后紧,上线初期把阈值设得宽松一些,观察误杀率,再逐步收紧;第二,分场景差异化,不同业务模块、不同时间段(比如促销活动期间)的阈值应该不同;第三,留有弹性,通过burst和滑动窗口机制给正常突发流量留出空间。
建议建立一套监控和反馈机制:实时统计触发限流的IP分布、触发原因(速率超限还是并发超限)、误杀率等数据,每周复盘一次。如果发现某类正常用户频繁触发,就针对性调整对应路径的阈值。如果发现某段时间攻击量激增,可以临时收紧全局阈值,等攻击过去再恢复。
另外,阈值设定还要考虑攻击成本。如果阈值设得太低,攻击者稍微换个IP就能绕过,防护形同虚设;如果设得太高,又起不到防护效果。一般来说,把阈值设在正常流量峰值的2到3倍是比较合理的起点,然后根据实际攻击情况动态调整。关键是让攻击者的成本高于他能获得的收益,这才是CC防护的终极目标。
六、常见误区和避坑指南第一个误区是把CC防护等同于DDoS防护。CC攻击是应用层攻击,模拟的是正常用户行为,流量可能不大但针对性强;DDoS是网络层和传输层的洪水攻击,靠的是海量流量。CC防护需要更精细的规则,不能只靠带宽清洗。
第二个误区是只在一层设防。只在Nginx层做限流是不够的,因为攻击者可以绕过Nginx直接打后端。应该在CDN、WAF、Nginx、应用层多层部署,每层设置不同的阈值,形成纵深防御。
第三个误区是忽略了慢速攻击。有些攻击者用Slowloris、RUDY等工具,每个请求发得很慢但一直不断开,专门占用并发连接。这种攻击不会触发速率阈值,但会把并发数打满。所以并发维度的限制在这类场景下尤为重要。
第四个误区是静态阈值一成不变。业务流量是动态变化的,节假日、促销、突发事件都会导致流量波动。静态阈值要么在高峰期误杀正常用户,要么在低峰期形同虚设。建议引入基于机器学习的动态阈值调整,或者至少做到按时间段自动切换策略。
七、总结与建议CC防护中设置请求速率和并发数的双维度阈值,本质上是从"频率"和"容量"两个角度构建防护网。速率阈值管的是"快不快",并发阈值管的是"多不多",两者配合才能覆盖各种攻击手法。具体实施时,先基于业务数据统计设定基准值,再通过burst机制和分级策略留出弹性空间,最后通过持续监控和调优不断打磨。不要指望一套规则用到老,CC防护是一个持续对抗、持续优化的过程。把双维度阈值当作基础框架,在此之上叠加多层防御、动态调整和智能分析,才能真正守住应用安全的底线。
