慢速攻击把连接保持时间拉长到极限,本质是用极低的请求速率占住服务端的连接槽位,让服务端在“等数据”的超时窗口里持续消耗内存和并发名额。核心答案就一句:攻击者靠精细控制发包节奏,把单个连接的有效生命从几秒拉到超时阈值上限,再用数量堆死连接池。 下面把手法拆开讲透,顺带把防守侧的配置路径一并给出来。
连接保持时间的物理上限在哪里
一个HTTP连接从建立到关闭要走多少路
TCP三次握手完成后,服务端会为这条连接分配一个文件描述符、一块读缓冲区、一个会话结构,在收到完整请求行和头部之前,服务端进入“待读”状态,这个状态有个计时器,超时没凑齐数据就关闭连接。
业内专家指出,多数服务端把“读请求头”的超时设置在数秒到数十秒之间,攻击者要做的就是让数据发送速率恰好低于触发超时的速度阈值,又不让连接真正空闲到被keepalive机制回收。
- 建立连接:三次握手,占用一个socket
- 发送请求:先发一个不完整的请求行或不带结束符的头部
- 保持存活:每隔一段时间发一个字节或一个换行,重置计时器
- 释放条件:服务端主动超时关闭或客户端主动断开
服务端超时参数为什么是慢速攻击的命门
超时参数设得短,正常用户在高延迟链路下容易误伤;设得长,攻击者的单连接存活时间就长,行业共识认为,Web服务器对请求头的默认容忍窗口普遍偏宽松,这是慢速攻击能奏效的结构性原因。
以常见配置为例,client_header_timeout 默认值是60秒,client_body_timeout 同样是60秒,攻击者把发包间隔控制在50秒左右,一个连接就能稳稳占住近一分钟,几百个这样的连接,就能压垮一个未做连接限制的中小型服务端。
Slowloris和RUDY攻击有什么区别?连接保持的两种极端路径
Slowloris:用不完整的请求把连接吊住
Slowloris的手法很直接:向目标发一个合法的请求行,然后持续发送头部字段,但永远不发空行(\r\n\r\n)来结束头部,服务端以为请求还没发完,一直等。
GET / HTTP/1.1\r\n Host: target\r\n User-Agent: slow\r\n X-a: 1\r\n (停顿几十秒) X-b: 2\r\n (停顿几十秒) ...
每一行都算有效数据,都会重置头部超时计时器,攻击者脚本每隔一个小于超时阈值的间隔补一行,连接就永远吊在半空,由于请求头未结束,服务端不会分配工作线程去处理业务,只占用连接资源成本极低。
RUDY:用超长表单体一点点喂数据
RUDY(R-U-Dead-Yet)走的是请求体路线,先发一个带 Content-Length 的POST头部,声明一个很大的体积,然后以极慢速度发送body内容。
POST /login HTTP/1.1\r\n Host: target\r\n Content-Length: 1000000\r\n Content-Type: application/x-www-form-urlencoded\r\n \r\n a=1&(每几十秒发一小段)
服务端已经进入读取body阶段,client_body_timeout 被反复重置,只要body没读完,这条连接就一直是活跃状态,RUDY对需要处理表单的应用杀伤更明显,因为连接处于“已进入业务逻辑、但数据不全”的状态。
两种手法的连接占用对比
| 维度 | Slowloris | RUDY |
|---|---|---|
| 攻击目标 | 请求头阶段 | 请求体阶段 |
| 单连接资源占用 | 低,仅socket和缓冲区 | 略高,可能触发body缓冲区分配 |
| 发包节奏 | 每几十秒一行头部 | 每几十秒一小段body |
| 对超时参数的依赖 | client_header_timeout |
client_body_timeout |
| 典型受害场景 | 静态站点、反向代理 | 表单登录、文件上传接口 |
慢速攻击连接超时怎么配置?从服务器参数看攻防博弈
Nginx的关键参数与实操路径
Nginx默认对慢速攻击有一定抵抗力,但参数需要收紧,操作路径是修改 nginx.conf 的 http 或 server 块:
http {
client_header_timeout 10s;
client_body_timeout 10s;
keepalive_timeout 15s;
send_timeout 10s;
lingering_timeout 5s;
client_max_body_size 2m;
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 16;
limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
}
client_header_timeout 10s:请求头10秒内没发完直接断开,Slowloris失效client_body_timeout 10s:body读取间隔超过10秒断开,RUDY被截断limit_conn addr 16:单IP并发连接上限,堵住“堆数量”的路子limit_req:单IP请求速率限制,配合连接限制形成双层防护
改完执行 nginx -t 校验,nginx -s reload 生效,参数不是越短越好,跨境或移动网络场景下10秒可能误伤,建议先观察访问日志里的请求耗时分布再定。
Apache的RequestReadTimeout配置
Apache 2.4可以用 mod_reqtimeout 模块精确控制读取节奏:
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=10-20,MinRate=500 body=10-20,MinRate=500
</IfModule>
header=10-20,MinRate=500 的意思是:请求头最多等20秒,且从第10秒开始要求每秒至少500字节的到达速率,这比单纯的总超时更聪明慢速补字节的策略会被最低速率要求卡住,修改后 apachectl configtest 校验,systemctl reload apache2 重载。
反向代理层的连接池管理
如果前面有负载均衡或CDN,要在代理层也设连接上限,以Nginx upstream为例:
upstream backend {
server 10.0.0.1:8080 max_conns=100;
keepalive 32;
}
max_conns 限制到后端的总连接数,防止代理层把慢速连接无限放大到源站,代理层的 proxy_read_timeout 也要收紧,避免它自己变成慢速连接的蓄水池。
北京企业Web服务器慢速攻击防护:地域场景下的落地配置
北京地区的中小企业站点很多跑在单台云主机上,带宽和连接数都不宽裕,慢速攻击的容错空间更小,落地时优先做三件事:
- 在云安全组或WAF层启用连接数清洗规则,多数云厂商的Web应用防火墙带慢速攻击特征库,按连接保持时长和头部到达间隔判定
- 源站收口到反向代理后面,源站只监听内网地址,公网只暴露代理层,代理层统一做连接限制
- 建立基线监控,记录正常时段的平均连接保持时长,偏离基线较大比例时触发告警
成本上,云WAF的按量计费对中小站点每月支出有限,比自建清洗设备划算得多,实测路径是先开WAF观察一周攻击面,再决定是否叠加源站参数收紧。
Q&A:慢速攻击连接保持相关的常见疑问
慢速攻击和DDoS有什么区别,防护手段能共用吗
慢速攻击属于应用层资源耗尽型攻击,不靠大流量取胜,靠连接槽位占用,传统流量清洗设备对它效果有限,因为它每个包都是合法HTTP流量,防护手段要落在应用层超时参数、连接数限制和头部速率校验上,和流量型DDoS的清洗策略是两套体系,但可以在同一台反向代理上叠加使用。
把超时参数调到极短是不是就安全了
不是,超时过短会误伤高延迟用户,尤其移动网络和跨境访问场景,合理的做法是“总超时适中+最低到达速率”双约束,Apache的 MinRate 参数就是这种思路,另外单靠超时不够,攻击者可以用更多连接数来补偿单连接存活时间的缩短,所以连接数上限必须同步配置。
慢速攻击的连接保持时间最长能拉到多少
取决于目标服务端的超时配置和攻击者的发包精度,攻击者通常把发包间隔控制在超时阈值的八成左右,留出网络抖动余量,如果服务端头部超时是60秒,单连接可稳定保持约50秒;攻击者脚本精度越高,越贴近阈值上限,实际攻击中,单连接存活时间受服务端重传、内核socket回收策略等因素影响,但把连接拖到超时上限附近是稳定可实现的。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/786591.html


