面对CC攻击,如何通过HTTP/2协议的多路复用特性优化防护
摘要:# 当CC攻击撞上HTTP/2:多路复用这把双刃剑,怎么用才不伤手? 先说句大实话:现在很多搞防护的,一听说“多路复用”就两眼放光,觉得找到了抗CC的“银弹”。可真到流量洪水涌过来的时候,不少方案反而因为这个特性栽了跟头——配置不对路,防护直接变漏斗。…
当CC攻击撞上HTTP/2:多路复用这把双刃剑,怎么用才不伤手?
先说句大实话:现在很多搞防护的,一听说“多路复用”就两眼放光,觉得找到了抗CC的“银弹”。可真到流量洪水涌过来的时候,不少方案反而因为这个特性栽了跟头——配置不对路,防护直接变漏斗。
我自己看过不少被打趴的站点,问题往往不是没上防护,而是配错了。尤其是HTTP/2这玩意儿,用好了是防护利器,用岔了就是给自己挖坑。
一、先别急着“优化”,你得知道CC攻击现在怎么玩
很多人还停留在“CC就是疯狂发请求”的老观念里。早不是那样了。
现在的攻击者精得很。他们早就摸透了HTTP/1.1的弱点——浏览器对同一个域名的并发连接数有限制(一般是6个)。所以传统CC攻击就像开六条车道不停塞车,虽然烦人,但好歹有个上限。
但HTTP/2把游戏规则改了。
它通过多路复用,允许在单个TCP连接上并行交错地发送多个请求和响应。说白了,就是一条车道能同时跑无数辆车。这对正常用户是福音,页面加载嗖嗖快。
可攻击者一看:哟,这不就是为我量身定做的攻击协议吗?
我前两天刚分析过一个案例。某电商站上了HTTP/2,没调防护策略,结果被攻击者用几十个“长连接”就拖死了服务器。每个连接开上几百个流(stream),疯狂请求那些最耗资源的动态页面——商品搜索、订单查询、详情页接口。服务器资源瞬间被榨干。
这种感觉你懂吧?就像你以为给大门加了把好锁,结果人家发现你厨房窗户压根没关。
二、多路复用怎么就成了防护的“加速器”?
别慌,特性本身没错,关键看你怎么用。
1. 真正的优势:识别效率的质变
在HTTP/1.1时代,防护系统看到一个IP建了6个连接,每个连接慢悠悠地发请求,其实不太好判断——这是真实用户在浏览,还是攻击者在试探?
但HTTP/2下,攻击行为往往更“显形”。
因为攻击工具为了追求效率,会在一个连接里疯狂创建流。正常用户浏览网站,流的创建是有节奏的:点开页面,加载完主要资源,停一会儿,再点下一个链接。而攻击流呢?通常是机械的、均匀的、高并发的创建请求。
防护系统只要会“听节奏”,就能分辨出交响乐和机关枪的区别。
我见过一个配置得挺聪明的案例。他们的WAF没去死磕每个请求,而是盯着每个TCP连接的生命周期行为:
- 建立连接后,瞬间迸发出上百个流?
- 每个流都直奔耗资源的API去?
- 几乎没有流空闲,持续不断?
符合这几个特征,直接把这个连接(连同背后的IP)扔进“慢速响应”队列,或者干脆reset掉。因为正常用户根本不会有这种使用模式——除非他是在用脚本刷你网站。
2. 资源消耗的“降维打击”
这一点很多人没想到。
HTTP/1.1下,防护系统要维护海量的TCP连接状态,内存和CPU开销巨大。一个IP开6个连接,10万个攻击IP就是60万个连接。光维持这些连接表就能把防护设备拖垮。
换成HTTP/2呢?攻击者可能用10万个IP,每个只建1个连接。但防护系统这边,需要维护的连接数直接降到原来的1/6。省下的资源,可以更从容地做深度包检测、行为分析这些“精细活”。
说白了,就是把原来用来“数人头”的算力,拿来“查身份证”了。
三、三个容易踩坑的配置误区(我几乎每个都见过)
误区一:无脑调高流并发数限制
有些管理员觉得,既然支持多路复用,就把服务器端的SETTINGS_MAX_CONCURRENT_STREAMS(最大并发流数)调到很高,比如1000。心想:反正我资源够。
这简直是给攻击者递刀子。
攻击工具发现你能接受这么多流,立马在每个连接里开满。服务器线程池、数据库连接池瞬间被这些“空转”的流占满。正常用户的请求?排队等着吧。
正确的做法是:设置一个合理的、偏保守的流并发上限。比如100-200。这个数足够满足正常用户的并发需求(一个页面加载通常也就几十个资源),但又不至于让攻击者一棍子把你捅穿。
误区二:忽略流超时(stream timeout)
HTTP/2的流是有生命周期的。但很多默认配置里,流超时设得很长(甚至不设)。
攻击者就钻这个空子:创建一堆流,发个请求头就卡住,不发送请求体,也不关闭。服务器傻等着,资源一直被占用。
你得在防护层(或者Web服务器配置里)加上流空闲超时。比如,一个流如果10秒内没有任何活动,强制关闭。正常用户操作不会这么“卡顿”,但能有效掐死那些“挂机”的攻击流。
误区三:只防“请求频率”,不防“连接行为”
这是最典型的思维定式。
很多防护规则还停留在“1秒内同一个IP超过100个请求就封”的层面。但在HTTP/2下,一个IP可能只发50个请求,却用了200个流(有些流可能只是建立还没发请求)。
你得看连接层面的异常:
- 一个连接里,流创建的速度是不是均匀得不像人工?
- 流的目标是不是高度集中在几个特定URL?
- 流的生命周期是不是异常地“整齐划一”?
把这些维度加进防护策略,才能抓住那些“伪装”得更深的攻击。
四、给你一个能落地的配置思路(别照搬,得调)
我以Nginx(作为反向代理+防护层)为例,说几个关键配置点。其他平台原理相通。
http {
# 1. 限制每个连接的并发流数
http2_max_concurrent_streams 100; # 别设太高,100-200是甜点区
# 2. 流超时控制
http2_recv_timeout 20s; # 流接收超时
http2_idle_timeout 10s; # 流空闲超时,关键!
# 3. 在location块里,加一些针对性的限制
location ~ \.php$ {
# 限制单个连接对动态页面的请求速率
limit_req_zone $connection_zone zone=conn_dynamic:10m rate=10r/s;
limit_req zone=conn_dynamic burst=20;
# 这里才是重点:用$connection变量来区分不同连接
# 而不是传统的$remote_addr(IP)
}
}
当然,这只是一个基础框架。真正的防护还得结合:
- 请求特征过滤:那些明显是扫描工具User-Agent的,带奇怪参数的,直接拒掉。
- 人机验证挑战:对可疑连接,不直接封,而是弹出一个简单的JS挑战。正常浏览器能过,攻击脚本通常过不了。
- 源站隐藏:前面用高防IP/高防CDN接流量,真实源站IP别暴露。这是底线,但很多人还是没做到。
五、最后说点“政治不正确”的
很多人觉得上了HTTP/2,网站变快了,防护也得“与时俱进”上最复杂的策略。
其实吧,有时候“退一步”反而更安全。
我见过一个金融类站点,业务逻辑复杂,对CC攻击特别敏感。他们的做法很“复古”:在防护层,对可疑IP直接降级回HTTP/1.1。因为HTTP/1.1的并发限制,反而成了天然的“流量整形器”。
攻击成本一下子提高了——攻击者得用更多IP、更多连接才能达到同样效果。而防护系统检测大规模IP集群,可比检测单个IP的复杂连接行为要容易得多。
这招有点“以退为进”的意思,但确实管用。你的业务适合吗?得自己掂量。
说到底,技术特性本身没有好坏。多路复用是让网络更快更高效的工具,不是洪水猛兽。关键看用它的人,是不是真的理解流量背后的“人性”——哪些是真实用户的手指滑动,哪些是脚本的机械轰鸣。
防护这件事,从来不是配置完就一劳永逸的。你得像老中医一样,时不时号号脉,看看日志,调调方子。那些号称“全自动、零干预”的防护方案,我劝你多留个心眼。真到了关键时刻,还是得靠懂行的自己。
行了,就聊这么多。配置的时候多想想,别让优化成了漏洞。

