应用层DDoS攻击排查的难点在于,攻击流量往往和正常业务请求高度相似,单看带宽或连接数很难直接定位。真正有效的排查思路不是从“流量大不大”入手,而是从“服务为什么变慢、哪些资源被耗尽、哪些请求特征异常”这三个维度反向拆解。应用层攻击通常针对HTTP/HTTPS协议本身,比如慢速连接、高频API调用、大参数请求、会话耗尽、TLS握手洪水等,这些攻击的流量绝对值可能并不高,但足以让后端应用服务器CPU、内存、数据库连接池或文件描述符耗尽。
排查的第一步是确认攻击是否发生在应用层。先观察网络层指标,如果带宽、PPS(每秒包数)、SYN队列都处于正常范围,但HTTP请求数、响应时间、错误率、后端并发连接数出现异常飙升,基本可以判断攻击集中在应用层。此时不要急着封IP,因为应用层DDoS往往使用大量真实IP或代理IP,单纯封禁效果有限,而且容易误伤正常用户。更合理的做法是先抓取应用服务器的实时状态,包括Web服务器的工作进程数、请求队列长度、响应码分布、每个URI的请求频率、每个来源IP的并发连接数和请求速率。
在Nginx环境下,可以通过配置自定义日志格式快速输出排查所需字段。以下配置能记录请求耗时、后端响应时间、客户端IP、请求URI、User-Agent和响应状态码:
log_format ddos_debug '$remote_addr - $request_uri - $status - '
'$request_time - $upstream_response_time - '
'$http_user_agent - $connection - $connection_requests';
access_log /var/log/nginx/ddos_debug.log ddos_debug;
开启后观察日志,重点找几类异常:同一URI在短时间内被大量不同IP请求;同一IP对某个URI维持大量长连接但请求间隔很长;大量请求携带相同或高度相似的User-Agent;大量请求返回404或502/504;请求耗时显著增加但后端响应时间正常,说明请求在队列中等待。这些特征分别对应不同类型的应用层攻击。
慢速攻击是最容易被忽视的一类。Slowloris通过建立大量连接并缓慢发送HTTP头部,占用Web服务器的连接槽位。Slow POST攻击则声明一个很大的Content-Length,然后以极低速率发送请求体,让服务器一直等待接收完整数据。排查时重点看连接数中处于“reading”或“writing”状态的连接占比。在Nginx中,可以通过stub_status模块查看当前活跃连接、读写连接和等待连接。如果waiting连接数很低,而reading/writing连接数持续接近worker_connections上限,且每个连接的请求数很少,基本可以确认是慢速攻击。缓解措施包括设置client_header_timeout、client_body_timeout的较小值,限制单个IP的最大连接数,以及使用limit_req模块限制请求速率。
高频API调用攻击更常见于业务接口。攻击者可能针对搜索接口、登录接口、短信发送接口、数据导出接口等资源消耗较大的端点发起海量请求。排查时按URI聚合请求次数和平均响应时间,找出请求量突增且响应时间明显变长的接口。这类攻击的流量特征往往表现为请求集中在少数几个URI上,且请求参数高度随机化或完全固定。针对这种情况,单纯依靠IP限速不够,因为攻击者可能使用IP池。更有效的方式是对接口做业务级别的限流和降级,比如对登录接口增加验证码、对搜索接口做结果缓存、对非核心接口直接返回静态降级页面。同时可以在网关层配置基于URI和请求方法的多维度限流策略。
会话耗尽攻击主要针对需要维持服务端状态的Web应用。攻击者通过脚本快速创建大量会话,填充应用服务器的内存或数据库中的会话表。排查时观察应用服务器的内存使用率和会话存储的增长趋势。如果内存持续上涨且GC后无法回收,同时活跃用户数并没有对应增长,说明存在会话滥用。应对方法包括缩短会话过期时间、启用会话惰性创建、对会话ID的生成增加校验、限制单个IP可创建的会话数量。对于分布式会话存储,还要检查是否存在大量无效会话写入导致存储节点负载升高。
TLS握手洪水攻击在应用层排查中容易被忽略。攻击者发起大量TLS握手请求但不完成握手,或者反复发起握手,消耗服务器CPU资源进行非对称加密运算。排查时观察服务器的CPU使用率是否主要集中在加密相关进程,同时网络层连接数高但HTTP请求数低。在Nginx中可以通过ssl_handshake_timeout和ssl_session_cache参数优化握手性能,并在前置负载均衡或防火墙层限制单IP的TLS握手速率。如果条件允许,启用TLS 1.3可以减少握手往返次数,降低单次握手的计算开销。
排查过程中需要建立一套快速响应流程。首先在负载均衡或反向代理层开启详细访问日志,保留原始请求头信息。然后按时间窗口分析请求分布,找出异常URI、异常User-Agent、异常Referer、异常请求方法。很多应用层攻击工具会使用默认的脚本语言User-Agent,或者完全不带User-Agent。Referer字段如果大量为空或指向不存在的页面,也可能是自动化攻击的特征。请求方法方面,如果出现大量HEAD或OPTIONS请求,而业务本身并不需要这些方法,可以直接在Web服务器层拒绝。
针对已经确认的攻击流量,可以采取分层过滤策略。第一层在网络边界或云防护服务中过滤明显的恶意特征,比如非浏览器User-Agent、异常的TLS指纹、已知的恶意IP段。第二层在反向代理层配置基于URI和IP的速率限制,对突发流量进行削峰。第三层在应用代码中对核心接口增加业务级校验和限流,比如对需要登录的接口检查令牌有效性,对公共接口增加简单的挑战机制。第四层在后端服务中设置资源隔离,防止单个接口的异常调用拖垮整个服务。
应用层DDoS排查还有一个重要环节是事后复盘。攻击结束后,需要保留攻击期间的日志样本和流量镜像,分析攻击工具的特征、攻击目标的分布、攻击时长的规律。这些信息可以帮助后续优化防护策略。例如,如果发现攻击集中在某个时间段且请求头中带有特定的X-Forwarded-For格式,可以在下次攻击前提前配置对应的过滤规则。同时要检查攻击期间是否有业务数据异常,比如是否有大量无效注册、垃圾评论、恶意爬虫行为伴随发生,因为应用层DDoS有时被用作掩盖其他攻击行为的烟幕。
在实际排查中,不要过度依赖单一指标。带宽、连接数、请求数、响应时间、错误率、资源使用率需要交叉验证。一个应用层攻击可能同时表现为连接数上升、请求数上升、响应时间上升,但带宽变化不大。另一个攻击可能只表现为某个接口的响应时间上升,其他指标都正常。因此排查思路的核心是建立多维度的观测能力,并能在攻击发生时快速切换视角,从整体到局部逐步缩小范围。
对于中小型业务,如果没有专门的流量分析平台,可以利用Nginx或Apache的日志配合命令行工具进行快速分析。例如使用awk统计每个URI的请求次数,使用sort和uniq找出请求最频繁的IP,使用grep过滤特定状态码的请求。以下命令可以快速统计访问量最高的前20个URI:
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
统计请求最频繁的前20个IP:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
这些基础命令在紧急情况下比复杂的分析系统更直接有效。关键是排查人员要清楚每个指标背后的含义,以及不同攻击类型对应的指标组合。应用层DDoS的排查不是一次性的动作,而是一个持续观察、快速判断、动态调整的过程。只有把日志、监控、限流、降级这些手段结合起来,才能在攻击发生时保持服务的可用性。
