当某个IP在较长时间内保持连接却很少发包,就该怀疑它是不是在“占着茅坑不拉屎”。慢速攻击的可怕之处在于它不像DDoS那样用海量流量砸垮你,而是用极低的速率慢慢耗干你的连接池,让正常访客全部被拒之门外。
慢速攻击为什么难抓:它伪装得太像正常用户
检测慢速攻击可关注每连接平均发送速率,这句话背后藏着一个安全运营人员的心酸,传统DDoS防御设备盯着流量带宽和包量,每秒几百G的洪水一眼就能识别,但慢速攻击不一样攻击者把一个HTTP请求拆成碎片,每隔几十秒才发一个字节,整整一个小时都占着连接不放。
服务器眼里,这是一个“活着”的连接,超时阈值没触发,连接池却在悄悄被榨干,正因如此,很多运维团队发现网站突然打不开,登录服务器一看,CPU和带宽都正常,可连接数爆表这正是慢速攻击的典型症状。
慢速攻击的三种老祖宗形态业内早已剖析清楚:
- Slowloris:最经典的方式,把HTTP请求头拆开,只发送
\r\n保持连接存活,让服务器永远等不到完整的请求头。 - Slow POST:把
Content-Length声明得很大,然后以极慢的速度挤牙膏一样发送POST请求体。 - Slow Read:客户端声明自己接收能力极弱,服务器拼命响应,数据包却全堵在发送缓冲区里,耗尽服务器资源。
行业共识认为,这三种手法虽然实现路径不同,但本质都是让单连接长时间存活且长期维持低速率,这恰好暴露了检测方法的切入点:既然攻击者对速率有“追求”,那我们就盯速率指标。
建立速率基线:搞清楚“每连接平均发送速率”到底怎么看
要让检测慢速攻击可关注每连接平均发送速率这个策略落地,第一步不是上设备,而是先回答一个问题:你网站的正常用户,平均每个连接的发送速率是多少?
写得很直白如何计算每连接平均发送速率并识别异常行为,这个指标在Linux下用ss -i就能看到,注意观察每个TCP连接的bytes_acked和rtt字段:
ss -tinp | grep -A1 'ESTAB' | head -20
输出中每行的bytes_acked表示对方确认收到的字节数,配合连接建立时间,就能算出大概的每秒发送速率,正常浏览网页的用户,加载一个页面通常在几秒内完成,平均速率在几KB/s到几十KB/s之间,而慢速攻击的连接,平均速率往往低于每秒几十字节,甚至几分钟才发一个ACK包。
实操上建议分三步走:
- 在nginx的
log_format中增加$request_time和$body_bytes_sent字段,记录每个请求的耗时和传输字节数。 - 用
tshark -i eth0 'tcp.analysis.ack_rtt'抓包分析ACK包的到达间隔分布。 - 通过ELK或Grafana建立可视化看板,按源IP聚合统计“连接持续时间/总发送字节数”的比值。
当某个IP的连接平均速率低于全站基线的一个数量级,而且连接存活时间特别长时,优先级就该拉到最高。
区分正常慢速与恶意扫描:速率不是唯一判据
但别急着封IP,有些正常业务本来就“慢”比如用户填写长表单、观看视频缓冲、甚至在页面上发呆半小时不操作,检测慢速攻击可关注每连接平均发送速率,但要综合多个维度交叉验证,别让速率指标一把尺子量到底。
判断一个低速率连接是攻击还是正常业务,可以从以下特征逐一比对:
- 连接并发数:正常用户通常只有1-5个并发连接,恶意攻击者往往对一个IP同时建立几十上百个连接。
- 请求完整性:攻击者的请求头永远发不完,正常用户即使慢,也会在合理时间内完成首包交互。
- UA和Referer:攻击工具的User-Agent多是空值或默认值,正常浏览器会带上完整的UA信息。
- 时间规律性:攻击者的发包间隔非常规律,像节拍器一样精准,而正常用户的行为是随机分布的。
还有一类场景需要单独拿出来说服务器响应慢导致正常用户发送速率变低怎么处理,这种情况下,服务器资源被慢速攻击耗尽,正常用户的请求排队等待,表现出的现象同样是每连接速率极低,这时候单看速率指标会误伤一大片。
解决思路是看建连时间,正常用户如果发现网站卡顿,会刷新页面重新建立连接,连接寿命短且新旧连接交替频繁,而慢速攻击的连接寿命极长,建连时间和发送速率双低,两者结合判断就能快速锁定真凶。
检测慢速攻击的落地工具:从开源方案到商用设备
明确了检测原理,接下来考虑怎么落地,对于预算有限的团队,直接上开源方案(比如nginx+Lua脚本统计连接状态)就能达到基本效果:
-- 在access_by_lua_file中增加速率统计 local connections = ngx.shared.conn_dict local key = ngx.var.remote_addr connections:incr(key .. ":bytes", ngx.var.request_length, 0) connections:incr(key .. ":conns", 1, 0)
每30秒检查一次,如果某个IP的连接数超过阈值且平均每连接发送字节数低于50字节/秒,直接对该IP返回444状态码关闭连接,这里用Lua共享字典做计数,对性能影响极小,单机可承载上万个并发连接的统计。
对于大型业务,可以考虑商用WAF产品,比如国内云厂商的Web应用防火墙都内置了慢速攻击防护策略,选型时关注一个核心参数:是否支持自定义速率阈值,有些产品只提供“低/中/高”三个档位,不够灵活;好的产品应该允许你按URI路径、按源IP段分别设置速率基线。
还有一种思路是利用负载均衡层做限速,比如在Nginx的limit_req模块中,按IP限制每秒请求速率,配合limit_conn限制并发连接数,慢速攻击一般要占用大量连接又很少发请求,limit_conn恰好能精准打击这种“占着连接不干活”的行为。
来看一个实际防御效果对比表:
| 防护策略 | 对Slowloris效果 | 对Slow POST效果 | 误杀正常用户概率 |
|---|---|---|---|
| 仅限制连接数 | 有效 | 部分有效 | 中等 |
| 仅限制请求速率 | 无效 | 有效 | 低 |
| 每连接平均速率检测 | 有效 | 有效 | 低 |
| 持续完整请求头超时 | 有效 | 无效 | 极低 |
从检测到清洗:慢速攻击的自动化处置流程
检测只是第一步,发现攻击后怎么处置同样讲究,针对那些每连接平均发送速率异常低的IP,建议遵循以下处理路径:
第一阶段:观察和标记。 首次触发阈值不立即封禁,先加入观察名单,记录连接行为,有些扫描器或爬虫也表现出低速率特征,但它们不会长时间维持连接,3-5分钟内会自动断开,这类来源标记为“疑似”即可。
第二阶段:被动防御。 对观察名单中的IP启用延迟响应策略故意让服务器的ACK响应变慢,慢速攻击工具大多有超时等待机制,通常几十秒内收不到响应就会自动重连,反复几次后攻击者自己就放弃了,这一招对付当前常见的Slowhttptest工具尤其有效,因为它默认超时设置在30秒左右。
第三阶段:主动拦截。 当确认攻击特征后,在防火墙层面直接封禁IP,并在WAF中加入针对该IP的会话丢弃规则,封禁时要注意保留证据,记录攻击IP、攻击时长、平均发送速率、连接数峰值等数据,方便后续溯源。
运维人员还要会看日志分析报告数据,比如nginx的错误日志中会反复出现“upstream timed out”且同一IP出现频率异常高的记录,这也是配合速率检测的旁证。
慢速攻击检测的核心,始终离不开对连接生命周期的精细管理,每个连接的平均发送速率就像一个心率监测器低于正常范围,说明问题正在发生,把这条指标纳入日常监控体系,配合并发连接数、请求完整度、IP维度的综合判断,就能在攻击产生实际影响之前把它扼杀在摇篮里,防护策略不是越激进的越好,而是用最短的时间找到那个吞吐量极低却死死拽住服务器资源不放的连接,一切问题自然迎刃而解。
检测慢速攻击的常见问题解答
Q:设置了很高的连接数上限,慢速攻击是不是就没影响了?
A:不一定,慢速攻击的胃口在于占据连接池的“半壁江山”,哪怕服务器能承载10万并发连接,攻击者用2万个低速连接把处理线程占满,正常请求照样排队等待,连接数上限设置得越高,攻击者发起慢速攻击的成本反而越低因为每个连接消耗的资源更少了,检测慢速攻击可关注每连接平均发送速率正是为了弥补这一空白。
Q:云服务商自带的基础防护能防住慢速攻击吗?
A:大多数云厂商的免费基础防护只针对流量型DDoS,对慢速攻击的识别能力有限,慢速攻击的流量总量极小,无法触发带宽告警,云清洗设备常常视而不见,多数情况下,需要购买增值的WAF或应用层防护服务,或者自行部署nginx层的速率检测逻辑来弥补这一缺失。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/786549.html


