慢速攻击并不依赖大流量,它通过长时间占用有限的TCP连接来耗尽资源。视频CDN边缘节点在处理播放器请求时,为了兼容弱网和长连接,会把超时时间设置得相对宽松,这恰好为Slowloris和Post-DOS这类慢攻击提供了可乘之机。攻击者利用少量IP就能让边缘节点的并发连接数达到上限,正常用户的视频请求被阻塞在队列之外。

一、慢攻击的核心机制与CDN中的薄弱环节
Slowloris最早被公开讨论时,主要针对Apache等传统Web服务器。它的做法是建立大量TCP连接后,每隔一段时间发送一个不完整的HTTP请求头,比如只发送X-Header: abc\r\n而不发送结尾的空行。服务器为了等待剩余的头部字段,会一直保持连接处于读取状态。每个连接占用的内存和文件描述符不多,但当攻击者同时打开数千甚至数万个连接时,服务器的连接池就会迅速耗尽。
CDN边缘节点面临的挑战更复杂。一方面,视频分发需要支持HLS、DASH等协议,播放器会频繁发起小文件请求,有些长连接会保持较长时间;另一方面,边缘节点往往部署在离用户较近的位置,单台机器的并发处理能力有限。如果攻击者从多个地理位置发起慢速连接,即使每个连接速率极低,也能穿透简单的IP限速策略。Post-DOS则更进一步,攻击者在发送完整的HTTP头部后,以非常缓慢的速度上传请求体,例如每10秒发送一个字节。反向代理为了将完整请求体转发给源站,必须把已接收的部分缓存在内存或磁盘中,导致缓冲区被长期占用。
更棘手的是,慢攻击流量在统计报表上看起来并不突出,总带宽占用可能只有几Mbps,但连接数却异常高。很多监控系统只关注流量峰值和QPS,容易忽略连接持续时间和单位时间内的字节数。因此,防护慢攻击的第一步是重新定义异常指标,而不仅仅是调整超时参数。
二、Slowloris攻击的识别与Nginx层防护配置
要防御Slowloris,最直接的手段是缩短HTTP头部读取的超时时间。Nginx提供了 client_header_timeout 指令,默认值通常是60秒,这对于视频CDN场景来说过长。攻击者可以利用这个时间窗口慢慢发送头部。将这个值调整到5到10秒,可以迫使慢速连接被及时断开。同时还需要设置 client_body_timeout 为较短时间,限制请求体的读取间隔。
http {
# 读取请求头的超时时间,超过则返回408
client_header_timeout 5s;
# 读取请求体时,两次读操作之间的超时时间
client_body_timeout 10s;
# 发送响应给客户端时,两次写操作之间的超时
send_timeout 10s;
# 每个连接的最大请求数,防止连接复用被长时间占用
keepalive_requests 100;
# 降低keepalive超时,释放空闲连接
keepalive_timeout 30s;
}
然而,仅靠超时参数并不能完全解决问题。攻击者可以每4秒发送一个字节,刚好卡在超时阈值以内。因此还需要配合连接数限制和速率限制。Nginx的 limit_conn 模块可以按IP限制并发连接数,limit_req 模块可以限制请求速率。对于视频CDN,按IP限制连接数需要谨慎,因为运营商NAT可能使大量正常用户共享同一个出口IP。更好的做法是结合自定义变量,例如根据X-Forwarded-For的哈希值来限制,或使用geo模块针对特定区域做差异化策略。
http {
# 定义共享内存区域,保存每个IP的连接数
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
# 定义请求速率限制
limit_req_zone $binary_remote_addr zone=req_per_ip:10m rate=30r/s;
server {
location /video/ {
# 每个IP最多同时保持10个连接
limit_conn conn_per_ip 10;
# 突发请求处理
limit_req zone=req_per_ip burst=50 nodelay;
# 其他代理设置
proxy_pass http://origin;
}
}
}
另外,可以使用 map 指令结合 $slow_transaction 这类变量来标记慢速连接。当请求头传输时间超过一定阈值时,直接返回444状态码断开连接,而不返回标准错误响应。这样可以减少攻击者获得的反馈信息。还可以在OpenResty中用Lua脚本实现更细粒度的检测:记录每个连接最后收到数据的时间,用一个定时器扫描长时间无数据且未完成的连接,主动关闭。
三、Post-DOS攻击的差异化防御与回源保护
Post-DOS与Slowloris虽然同属慢攻击,但防御思路有所区别。Slowloris主要在HTTP头部阶段消耗连接,而Post-DOS则在请求体传输阶段做文章。攻击者会声明一个很大的Content-Length,例如100MB,然后以极低速度上传。如果反向代理等待完整请求体后再转发给源站,那么代理服务器的内存和磁盘缓冲区会被大量占用。Nginx默认会先把请求体缓冲到临时文件,当超过 client_body_buffer_size 后写入磁盘,但攻击者可以制造大量小体积却永远不传完的请求体片段。
防御Post-DOS需要从三个方面入手。第一,限制请求体的大小,即使攻击者声明了超大体积,超过 client_max_body_size 后会快速返回413错误,避免缓冲浪费。第二,缩短 client_body_timeout,如前所述,这个参数控制两次读取请求体之间的最大间隔。第三,开启请求体缓冲到磁盘时的速率检测。Nginx核心没有直接的请求体速率限制,但可以通过 proxy_request_buffering 关闭缓冲,让源站直接处理流式上传,但这对视频上传等场景不适用。更稳妥的方式是在边缘节点使用Lua或第三方模块监控请求体的接收速率,例如每秒接收字节数低于某个阈值且持续时间过长,则主动断开。
http {
# 请求体最大8MB,防止超大请求体缓慢传输
client_max_body_size 8m;
# 请求体缓冲区大小
client_body_buffer_size 128k;
# 请求体超时缩短
client_body_timeout 5s;
server {
location /upload/ {
# 上传类接口可能需要较大body,单独调整
client_max_body_size 50m;
# 关闭代理缓冲,让流式数据直接发往源站,减少边缘缓冲压力
proxy_request_buffering off;
# 但需要保证源站能处理慢速连接
proxy_pass http://origin_upload;
}
}
}
在CDN回源链路中,防护Post-DOS还需要考虑回源连接的保护。如果边缘节点被大量慢速请求占据,回源请求也会堆积,可能导致源站过载。可以在回源层设置独立的超时参数,例如proxy_connect_timeout、proxy_read_timeout、proxy_send_timeout,并限制回源并发连接数。同时,源站自身也需要部署类似的慢攻击防护,不能只依赖CDN边缘。对于视频CDN,尤其要关注分片上传接口和鉴权回调接口,这些接口往往需要接收较大的请求体,容易成为Post-DOS的目标。
四、监控调优与正常弱网用户区分策略
慢攻击防护最大的难点是避免误伤正常用户。移动端用户在信号较弱的环境下,请求头和请求体的传输速度可能确实很慢。如果超时时间设置得过短,就会导致这些用户频繁收到408或444错误,视频起播失败率升高。因此,防护策略需要结合连接状态监控和用户行为特征来动态调整。
一个实用的方法是在边缘节点日志中记录请求头接收耗时和请求体接收耗时。Nginx的 $request_time 反映的是整个请求处理时间,但无法区分头部和体阶段。可以通过自定义日志格式,在Lua阶段记录时间戳差值。例如,在读取请求体之前记录当前时间 ngx.now(),在读取完成后再次记录,将差值写入访问日志。然后使用日志分析工具统计每个IP的平均头部耗时和请求体速率,识别出持续低速但连接数众多的IP段。这些数据可以反哺到WAF规则中,实现自动封禁。
-- 在OpenResty的access阶段记录开始时间 local start_time = ngx.now() ngx.ctx.slow_start = start_time -- 在body_filter或log阶段计算耗时 local end_time = ngx.now() local body_read_time = end_time - ngx.ctx.slow_start -- 将耗时写入变量,供日志使用 ngx.var.body_read_time = body_read_time
此外,可以在WAF或CDN控制台配置基于连接行为的规则,例如“同一IP在60秒内超过200个连接且平均每个连接传输字节数小于500,且多数连接未完成请求”则触发告警或临时限制。对于正常播放器,它们通常会快速发送完整的HTTP请求,即使弱网下也只会表现为传输时间较长但最终完成。攻击者的特征往往是故意不完成请求,或者以固定间隔发送极少量数据。因此,可以监测连接的完成率,而不是单纯看速率。
最后,持续调优是必须的。攻击者会不断调整发送间隔来绕过固定阈值,所以建议将超时时间设置为动态值,根据当前节点负载和连接队列长度自动调整。当连接数接近上限时,可以临时缩短超时并启用更严格的速率限制;负载恢复正常后自动放宽。这种自适应策略可以在OpenResty中用 ngx.shared.DICT 保存实时状态,由定时任务扫描并调整Nginx变量。对于大型视频CDN,还应该在边缘节点之间共享慢攻特征库,当一个节点识别到某个IP段正在进行慢攻击时,其他节点可以快速同步封禁。
CDN慢攻击SlowlorisPost-DOS防御修改时间:2026-09-30 13:08:00