高可用架构最怕的不是被打死,而是被“钝刀子割肉”。DDoS负责把带宽或连接资源占满,CC负责把服务器计算资源耗光,两者一旦混合,往往呈现为“慢连接、假死、间歇性502”的状态。很多人盯着流量图看,发现带宽没跑满,CPU却飙到100%,这就是典型的CC藏在正常流量里。真正的协同防护不是各管各的,而是要在架构层、协议层、应用层三层同时做联动清洗。
把“首包丢弃”前置到四层入口绝大多数DDoS混合攻击利用的是TCP三次握手的特性。SYN Flood打过来,如果你直接回SYN-ACK,不仅消耗带宽,还会在服务器上留下大量半开连接。高可用架构的第一道防线应该在负载均衡器或四层网关做“首包丢弃”策略。具体做法是:对新建连接的SYN包先静默丢弃一次,等待客户端重传。真实的客户端协议栈会重传,而绝大多数反射放大攻击和伪造源IP的SYN Flood不会重传。这个动作几乎没有计算开销,却能过滤掉70%以上的伪造流量。如果使用LVS的DR模式,可以在内核参数中调整net.ipv4.tcp_syncookies=1,并配合iptables的recent模块做源IP新建连接频率限制。关键点在于,首包丢弃的策略必须和后续的CC防护联动,因为攻击者一旦发现SYN Flood打不进去,会立刻切换到HTTP层的慢速攻击。
用“连接饥饿”反制慢速CC慢速CC攻击的核心不是并发量大,而是占着连接不释放。攻击者发完HTTP请求头后,每隔十几秒再发一个字节,让连接一直保持在ESTABLISHED状态。传统做法是调小timeout,但调太小会误伤移动端弱网用户。更有效的做法是在反向代理层实施“连接饥饿”策略。以Nginx为例,不仅要设置client_header_timeout和client_body_timeout,还要利用limit_rate_after和limit_rate的组合,对单个连接在传输超过一定字节后强制限速。更进一步的技巧是使用ngx_http_limit_conn_module对每个IP的并发连接数做硬限制,但这个模块的问题是只能限制并发数,无法识别连接的真实活跃度。真正有效的做法是结合Lua脚本,在access阶段统计每个IP的连接平均传输速率,如果连续多个请求窗口内平均速率低于阈值,直接将该IP的连接标记为“僵尸连接”并主动reset。这种动态识别比固定阈值有效得多,因为攻击者很难模拟正常用户的传输节奏。
七层指纹识别比验证码更管用CC攻击发展到今天,大部分工具已经能自动处理302跳转和JS验证码。所以单纯依赖验证码弹出,只会让正常用户流失。真正硬核的做法是在应用网关层做无感知的浏览器指纹校验。具体实现是在CDN或网关层注入一段极简的JS,采集客户端的屏幕分辨率色深、WebGL渲染器字符串、Canvas指纹以及navigator属性的一致性。正常浏览器的这些属性之间存在强关联,而脚本工具和Headless浏览器在这些维度上会暴露出明显的不一致。比如一个声称自己是Chrome 120的客户端,其WebGL渲染器字符串却是SwiftShader,或者Canvas指纹熵值极低,这几乎可以断定是模拟器。这套逻辑做成异步校验,客户端在加载页面的同时,网关已经完成指纹评分。评分低的流量不直接拦截,而是将其调度到独立的“慢速队列”服务器,让攻击者感觉自己打中了,但实际上消耗的是隔离资源。这种策略在电商大促期间尤其有效,因为攻击者很难在短时间内模拟出高熵值的浏览器环境。
利用TCP协议栈特征做源认证在四层和七层之间,还有一个被很多人忽略的防护层:TCP协议栈指纹。不同操作系统和网络环境下的TCP初始窗口大小、TTL值、TCP选项顺序都有显著差异。攻击工具发包通常是调用raw socket,其协议栈行为与真实操作系统完全不同。可以在负载均衡器上部署一个轻量级的包特征采集模块,对每个新建连接的SYN包提取TTL、Window Size、MSS、SACK Permitted选项以及时间戳的偏移量,组成一个五元组特征向量。然后用一个简单的在线分类器判断这个连接是否来自真实操作系统。这个判断在三次握手完成之前就能做出,对于特征明显异常的连接,直接不发SYN-ACK,节省后端资源。这套方案的关键在于特征库需要定期更新,因为攻击工具也在不断改进协议栈模拟能力。但至少目前,绝大多数CC工具在TCP选项顺序和时间戳处理上仍然存在明显破绽。
业务粒度的速率基线自学习任何固定阈值的限流在混合攻击面前都会失效。攻击者会精准地将请求速率控制在阈值以下,同时分散到大量IP上。真正有效的做法是建立业务粒度的速率基线模型。具体来说,不是对整个站点做QPS限制,而是对每个API端点、每个页面路径分别建立时间序列模型。系统需要持续统计每个URL在过去7天同一时段的历史请求分布,计算出均值、标准差和峰值系数。当实时流量偏离基线超过3个标准差时,不是直接拦截,而是触发“挑战模式”,对该URL的访问临时加入前述的浏览器指纹校验。这种自学习模型必须能区分正常的流量尖刺和攻击。比如秒杀活动带来的流量尖峰,其特点是请求高度集中在少数几个URL上,且客户端指纹评分普遍较高;而CC攻击虽然也会集中在某些URL,但指纹评分分布会呈现两极分化。利用这个差异,可以在模型中加入指纹评分维度,大幅降低误报率。
高可用架构下的联动清洗机制单点防护永远有盲区。真正的高可用架构必须让四层清洗、七层清洗和业务风控三者联动。实现方式是在流量入口处部署一个决策中心,这个中心不处理实际流量,只接收各层的统计数据。四层设备上报每秒SYN包速率和半开连接数,七层设备上报各URL的响应时间分布和状态码比例,业务风控上报登录失败率和异常订单比例。决策中心用这些指标计算出一个“全局威胁指数”,当指数超过阈值时,自动下发策略到各层。比如四层检测到SYN Flood,决策中心会通知七层进入“紧缩模式”,收紧连接超时和速率限制;七层检测到某个URL响应时间异常升高,决策中心会通知四层对该URL的源IP段做临时限速。这种联动不是简单的事件通知,而是基于策略模板的自动化编排。策略模板需要预设好各种攻击组合的应对方案,比如“高SYN+高HTTP 200”是一种模式,“低SYN+高HTTP 502”是另一种模式,每种模式对应不同的清洗参数组合。这套机制的核心价值在于,当攻击手法在DDoS和CC之间快速切换时,防护体系能在秒级完成策略切换,而不是等运维人员告警后再手动调整。
源站隐藏与回源链路保护很多人以为用了CDN就万事大吉,实际上攻击者通过DNS历史记录、证书透明度日志、甚至网站邮件头中的源站IP信息,很容易找到真实服务器地址。一旦源站IP暴露,所有CDN防护都形同虚设。高可用架构必须做到严格的源站隐藏。具体措施包括:源站只允许CDN节点的回源IP段访问,其他所有IP一律在防火墙层丢弃;定期更换源站IP,并在更换后立即清理所有DNS历史记录;使用专用的回源域名,这个域名不做任何公开解析,只在CDN配置中使用;对于必须对外暴露的API,使用独立的边缘节点做反向代理,绝不直接暴露源站。此外,回源链路本身也需要防护。攻击者可以绕过CDN直接对源站发起HTTPS Flood,因为SSL握手对CPU的消耗极大。在源站前端部署一层专门处理SSL卸载的网关集群,并启用TLS会话复用和0-RTT,能有效降低SSL握手带来的资源消耗。这层网关只做SSL卸载和基础的四层防护,不处理任何业务逻辑,即使被打满,也不会影响后端应用服务器。
应急场景下的降级与隔离策略再完善的防护体系也可能被突破,所以必须预设应急降级方案。当攻击流量超过清洗能力时,第一优先级是保住核心交易链路。可以在网关层实施“业务分级隔离”,将URL分为核心、重要、非必要三个等级。当系统负载达到警戒线时,自动对非必要服务返回静态缓存页面,释放资源给核心服务。更进一步的做法是利用容器化架构的弹性能力,在攻击发生时将核心业务快速扩容到独立的干净集群,同时将被攻击的集群作为“蜜罐”继续消耗攻击者资源。切换的关键在于会话状态的同步,必须确保用户在切换过程中不会掉线。这需要将会话信息存储在共享的Redis集群中,并且切换操作通过DNS权重调整来实现,而不是修改负载均衡配置。整个切换过程可以做到对用户完全透明,攻击者看到的只是目标网站的响应变慢了,但实际上核心用户已经被迁移到了安全区域。
持续演进的防护体系攻击手法在不断进化,防护体系也必须持续演进。建议每季度做一次全链路的攻防演练,用真实的攻击工具测试各层防护的有效性。演练中要特别关注各层之间的策略传递延迟,以及在高负载下决策中心本身的稳定性。很多防护体系在低负载时表现完美,一旦决策中心自身成为瓶颈,整个防护体系就会崩溃。因此决策中心必须采用分布式架构,各节点之间通过共识算法保持状态一致,任何单点故障不影响策略下发。同时,所有防护日志需要统一收集到时序数据库中,用于离线分析攻击趋势和优化基线模型。这套体系建成后,DDoS和CC的协同攻击就不再是无解的问题,而是一个可以被量化、被拆解、被逐步自动化的工程挑战。
