CC攻击的变种越来越狡猾,单靠连接数限制或者源速率限制任何一招都防不住。真正有效的方案是把连接数限制和源速率限制组合起来用,形成协同防御体系。具体来说,就是在网络层对单个源IP的并发连接数设上限,同时在应用层对请求频率做细粒度限速,两层联动、动态调整阈值,才能把慢速CC、分布式CC、协议层CC这些变种全部压住。下面我把这套协同防御的逻辑、配置方法、实战参数和常见坑全部讲透。
一、为什么单一限制手段防不住CC变种
传统CC攻击靠大量HTTP请求打垮服务器,早期防御只要限制连接数就够了。但现在攻击者学聪明了,变种主要有三种:第一种是慢速CC,每个连接占着不放,请求间隔拉长,连接数不高但资源消耗大;第二种是分布式CC,用几万个肉鸡IP每个只发少量请求,单IP连接数和速率都不超标;第三种是协议层CC,直接打TCP握手或TLS握手,绕过应用层检测。只限制连接数,慢速CC能穿透;只限制速率,分布式CC能绕过。所以必须两招一起上,互为补充。
二、连接数限制的核心逻辑和配置要点
连接数限制是第一道防线,主要在四层和七层同时生效。四层(TCP层)限制单个源IP的并发连接数,七层(HTTP层)限制单个源IP同时打开的会话数。关键参数有三个:单IP最大并发连接数、全局最大连接数、连接超时时间。实战建议:单IP并发连接数设为50-200,全局连接数根据服务器承载能力设定,连接超时设为30-60秒。太低会误杀正常用户,太高形同虚设。
以Linux防火墙iptables为例,限制单IP并发连接数的规则如下:
iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 100 --connlimit-mask 32 -j DROP iptables -A INPUT -p tcp --syn -m hashlimit --hashlimit-above 50/sec --hashlimit-mode srcip --hashlimit-name conn_limit -j DROP
上面第一条限制单个IP同时最多100个连接,第二条用hashlimit模块限制每秒新建连接不超过50个。实际部署时要根据业务流量基线调整数值,电商大促期间需要临时放宽。
三、源速率限制的精细化策略
源速率限制是第二道防线,重点在应用层做请求频率控制。这里有两个维度:一是全局速率,即整个系统每秒处理的请求总量上限;二是单源速率,即每个IP每秒允许的请求数。更精细的做法是按URL路径做差异化限速,比如登录接口限制更严,静态资源接口可以放宽。
在Nginx层面做源速率限制非常高效,核心配置如下:
# 定义限速区域,按源IP限速
limit_req_zone $binary_remote_addr zone=per_ip:10m rate=10r/s;
# 定义全局限速区域
limit_req_zone $server_name zone=global:10m rate=5000r/s;
server {
location /login {
limit_req zone=per_ip burst=20 nodelay;
limit_req zone=global burst=500 nodelay;
}
location /api/ {
limit_req zone=per_ip burst=30 nodelay;
}
}
rate=10r/s表示每个IP每秒10个请求,burst=20允许短时突发20个请求。nodelay参数让突发请求立即处理而不是排队延迟。对于CC变种攻击,建议对敏感接口(登录、搜索、下单)单独设更低的rate值,比如3-5r/s。
四、协同防御的联动机制设计
连接数限制和源速率限制不是各自为战,而是要联动。具体联动逻辑分三层:第一层,当某个IP的连接数接近阈值但速率不高时,触发慢速CC预警,系统自动降低该IP的速率限制值;第二层,当大量IP同时出现中等速率请求但单IP不超标时,触发分布式CC预警,系统提升全局速率限制并收紧单IP连接数;第三层,当连接数和速率同时飙升时,直接触发封堵策略,将可疑IP加入临时黑名单。
实现联动可以用脚本监控加自动规则下发。比如用Python监控Nginx的access log,实时统计每个IP的连接数和请求频率:
import re
from collections import defaultdict
import time
ip_stats = defaultdict(lambda: {'conn': 0, 'req': 0, 'last_time': 0})
def analyze_log(log_line):
# 解析IP和时间戳
match = re.search(r'(\d+\.\d+\.\d+\.\d+).*\[(.*?)\]', log_line)
if not match:
return
ip = match.group(1)
# 统计逻辑
ip_stats[ip]['req'] += 1
# 连接数通过状态码判断,200表示活跃连接
if ' 200 ' in log_line:
ip_stats[ip]['conn'] += 1
def check_and_block():
for ip, stats in ip_stats.items():
if stats['conn'] > 150 or stats['req'] > 30:
# 调用防火墙API封禁IP
block_ip(ip)
print(f"Blocked {ip}, conn={stats['conn']}, req={stats['req']}")
while True:
check_and_block()
time.sleep(5)
这段代码是简化示意,生产环境需要接入实时日志流处理框架,比如用Flink或自建的流计算引擎,延迟控制在秒级以内才有实战价值。
五、针对不同CC变种的参数调优建议
慢速CC变种:重点收紧连接超时时间到15-30秒,同时降低单IP速率限制到3-5r/s,开启TCP KeepAlive检测僵尸连接。分布式CC变种:重点做IP信誉库比对,对已知IDC段、代理段做全局速率压降,同时启用行为分析,识别请求模式异常(比如User-Agent统一、请求间隔过于规律)。协议层CC变种:在SYN Cookie和TLS握手阶段就做速率限制,四层直接拦截,不让请求到达七层。
具体参数参考表:
慢速CC——单IP连接数上限80,单IP速率5r/s,连接超时20秒;分布式CC——全局速率3000r/s,单IP速率10r/s,启用IP画像;协议层CC——SYN速率100/s/IP,TLS握手速率50/s/IP,启用SYN Cookie。
六、部署架构和注意事项
协同防御建议部署在三个位置:最外层CDN或高防IP做四层连接数限制和SYN速率限制,中间层WAF做七层源速率限制和行为分析,最内层Nginx或应用服务器做细粒度限速和连接管理。三层形成纵深防御,任何一层被突破还有下一层兜底。
需要注意的坑有四个:第一,阈值设得太死会误杀正常大流量用户,必须留burst缓冲;第二,不要只看单指标,要看连接数和速率的组合特征,单一指标容易被绕过;第三,IP信誉库要持续更新,攻击者会不断换IP段;第四,日志要保留至少30天,用于事后溯源和规则优化。另外,协同防御不是设好就不管了,需要每周根据攻击日志复盘调整参数,攻击手法在变,防御策略也要跟着迭代。
七、总结和行动建议
CC变种防御的核心就是"连接数+速率"双维度协同,缺一不可。先在四层把连接数卡住,再在七层把请求频率管住,中间用联动机制把两层串起来,最后用行为分析做智能兜底。中小企业可以直接用云WAF的现成规则,大型业务建议自建联动系统,把防火墙、WAF、Nginx的数据打通,做到秒级响应。记住,没有一劳永逸的防御配置,持续监控、持续调优才是真正的安全感。
