CC攻击防御中的挑战:WebSocket over HTTP/2的协议混淆
摘要:# 当WebSocket穿上HTTP/2的马甲:CC攻击的“隐身衣”有多难防? 前两天,我帮一个做在线教育的客户排查问题,他们那套实时互动系统突然卡得不行,后台CPU直接拉满,但流量监控上愣是看不出什么异常峰值。折腾了大半夜,最后抓包分析才发现——攻击者…
当WebSocket穿上HTTP/2的马甲:CC攻击的“隐身衣”有多难防?
前两天,我帮一个做在线教育的客户排查问题,他们那套实时互动系统突然卡得不行,后台CPU直接拉满,但流量监控上愣是看不出什么异常峰值。折腾了大半夜,最后抓包分析才发现——攻击者把WebSocket流量伪装成HTTP/2的流,混在正常请求里,像泥鳅一样滑进了防护规则。
我当时心里就一个念头:这年头,连攻击都开始玩“协议混淆”了。
一、这玩意儿到底是个啥?先别被术语唬住
说白了,WebSocket over HTTP/2(后面我就简称WS/2了)就是把原本明晃晃的WebSocket长连接,塞进了HTTP/2的“管道”里传输。
正常WebSocket握手多明显啊?客户端发个Upgrade: websocket的请求,服务器回个101 Switching Protocols,然后两边就建立起一条持久连接,开始双向通信。这套流程在传统WAF和CC防护眼里,简直就是“我是攻击流量,快来拦我”的活靶子。
但WS/2不一样。它利用HTTP/2本身就支持多路复用(一个连接里能同时跑多个请求/响应流)的特性,把WebSocket的数据帧伪装成HTTP/2的DATA帧,在已有的HTTP/2连接里悄咪咪地传。从外层看,这就是个普通的HTTPS连接(HTTP/2必须走TLS),里面具体在传什么,传统基于请求特征识别的防护设备很难一眼看穿。
——这就好比,以前攻击者开着一辆写着“我是坏人”的卡车冲卡,现在他们把武器拆成零件,伪装成快递包裹,混在每天成千上万的正常快递里送进来。
二、为什么这成了CC防护的“盲区”?
很多客户上了高防IP或者云WAF,就觉得高枕无忧了。但现实往往是,PPT上吹得天花乱坠的方案,真遇到这种“非标”攻击,第一反应可能是懵的。我总结了一下,WS/2混淆攻击让防护方头疼,主要是因为这几点:
1. 特征“隐身”,传统规则直接失效 传统CC防护的核心逻辑是什么?是识别异常。比如,单个IP短时间内建立大量HTTP连接、请求频率过高、请求的URL有规律等等。但WS/2攻击,它可能就维持着那么几个、几十个合法的HTTP/2连接,然后在里面源源不断地发起WebSocket请求(伪装成流)。每个流单独看,可能都符合业务逻辑(比如模拟心跳包、发送聊天消息),但汇聚到服务端,处理这些“伪WebSocket”逻辑的代码就把CPU拖垮了。
你的防护设备还在数“开了多少辆卡车”,人家已经在“每条高速公路的每辆车里塞满了违禁品”。
2. 加密隧道,内容检测难度飙升 HTTP/2强制TLS加密。这意味着,所有流量在传输过程中都是密文。中间的网络设备(包括很多透明代理型的高防)如果没有配置对应的SSL证书进行解密,就只能看到一堆加密的数据包在跑来跑去,根本不知道里面是正常的API调用还是攻击流量。
你要检查内容?得先解密。解密就涉及到证书部署、性能开销,还有隐私合规问题。很多企业在这一步就卡住了。
3. 资源消耗点“下沉”,打到七层以下 普通的HTTP CC攻击,消耗的是Web服务器(如Nginx、Apache)的连接池、线程池资源。防护方案通常在七层做限流、人机验证就能缓解。 但WS/2攻击,一旦成功建立连接,它的攻击点可能直接穿透到了应用层业务逻辑。比如,它模拟的是你游戏里的移动指令、聊天室的发言、协同编辑的字符——处理这些逻辑的是你后端的业务服务器(Node.js、Go写的服务)。这里往往是业务核心,资源昂贵,且通用的防护产品很难深入到这里做精细化的规则判断。
说白了,攻击成本变低了(几个连接就能持续施压),而你的防御成本和复杂度却大大提高了。
三、那怎么办?总不能躺平吧?
当然不能。虽然难,但也不是无解。我结合最近处理过的几个案例,说几个我觉得比较有实操性的思路,不一定全,但希望能给你点启发。
第一招:釜底抽薪,在“握手”环节设卡
WS/2虽然隐蔽,但它终究要完成WebSocket的“升级”过程。在HTTP/2里,这个升级是通过CONNECT方法加上特定的协议头(:protocol)来完成的。防护设备如果支持HTTP/2深度解析,可以在这里做文章:
- 严格校验Upgrade路径:非业务必需的WebSocket端点,直接拒绝
CONNECT。 - 频率限制:对单个HTTP/2连接内发起WebSocket升级的频率进行限制。一个正常的客户端,不会在一秒内反复建立几十个WebSocket子流。
- 行为基线:为每个客户端IP或用户Session建立正常的WebSocket使用基线(如连接时长、消息频率、数据包大小)。一旦偏离基线,就引入二次验证或限速。
第二招:以“动”制“动”,在业务层做动态指纹 这是比较进阶的做法,需要研发团队配合。既然攻击者模拟的是正常用户行为,那我们就给真正的正常用户行为加上一些“暗号”。
- 比如,在真正的客户端SDK里,对WebSocket发送的某些关键消息,加入一个由时间戳、会话ID等生成的动态Token,服务端先验Token再处理逻辑。
- 或者,在连接建立后,先发起一次简单的“挑战-应答”,比如服务器发一个随机数,客户端用特定算法计算后返回。这个计算过程可以很轻量,但对纯模拟的攻击程序来说,就多了一道需要逆向分析的屏障。
第三招:资源隔离与熔断 这是最后一道防线,也是保证业务不彻底崩溃的底线思维。
- 给WebSocket服务单独部署、单独限流:别让它和主要的Web API服务抢资源。用独立的服务器或容器组来承载WS服务,并设置明确的CPU、内存、连接数阈值。
- 实现快速失败与熔断:当检测到某个WebSocket连接的消息处理异常频繁,或后端服务响应时间飙升时,果断断开该连接,甚至暂时熔断整个WebSocket服务入口,优先保障核心HTTP API的可用性。壮士断腕,好过全身瘫痪。
四、几句大实话
- 没有银弹:别指望买一个产品就能一劳永逸。防护WS/2这类混淆攻击,一定是“网络层拦截+应用层策略+业务层加固”的组合拳。
- 监控比防护更重要:你得先能“看见”。确保你的监控系统能清晰地展示HTTP/2连接数、WebSocket子流数量、后端处理服务的CPU/内存指标。异常往往是从这里先冒头的。
- 默认拒绝,最小化开放:仔细梳理你的业务,到底哪些功能必须用WebSocket?能不用就不用,能少用就少用。每一个开放的端口和协议,都是潜在的风险点。
最后说点感性的。网络安全这事儿,有时候就像打地鼠。HTTP/1.1的CC攻击防住了,大家就转向HTTP/2;明文的防住了,就全都钻加密隧道。WS/2混淆不会是终点,后面肯定还有更花哨的玩法。
作为防守方,我们能做的,不是追求一个绝对安全的“铁桶”,而是让自己变得足够敏锐和灵活——攻击来的时候能快速发现、准确定位、有效响应。这背后考验的,其实是你对自身业务流量深刻的理解,和一套随时准备应变的运维体系。
行了,技术细节就聊这么多。如果你的线上业务还没遇到过这种攻击,恭喜你,运气不错。但最好也检查一下,你的防护体系,真的准备好应对这只“穿着马甲的地鼠”了吗?

