伪造访问流量与正常用户请求的本质区别不在于“是否像人”,而在于请求序列是否呈现可预测的自动化特征。真正的攻击流量识别不能只靠单点规则,必须结合请求头完整性、行为节奏、资源消耗偏差和会话逻辑四层信号交叉验证。单看IP信誉或者User-Agent已经基本失效,因为攻击工具早已能批量伪造这些字段。

从TCP指纹和TLS握手开始过滤

大部分DDoS工具为了追求发包速度,会牺牲协议栈的完整性。正常浏览器建立TLS连接时,ClientHello中的密码套件顺序、扩展列表、椭圆曲线参数都有相对固定的组合,而脚本或攻击框架发出的握手包往往缺少extension或者顺序错乱。你可以在边缘节点记录每个SYN包的TTL、窗口大小、TCP选项顺序,再结合TLS指纹做一致性判断。同一个IP如果在短时间内出现多种不同的TCP指纹,基本可以判定为代理池或伪造源地址。

具体操作上,建议在负载均衡层开启SYN Cookie,同时对每个新建连接计算JA3指纹。把JA3指纹与已知浏览器版本库做比对,不匹配的直接降低优先级或进入验证流程。对于UDP反射类攻击,重点检查源端口和载荷长度分布。正常的DNS查询、NTP请求都有固定格式,反射放大流量往往载荷长度异常集中,或者源端口与协议不匹配。

行为节奏分析比单次请求特征更可靠

单个HTTP请求可以伪装得很像真人,但请求序列的时间分布很难伪造。正常用户浏览页面时,请求间隔呈长尾分布,有大量短间隔的资源加载,也有较长的阅读停顿。攻击工具的请求间隔通常高度均匀,或者呈现固定模式的循环。你可以在WAF或网关层对每个会话维护一个滑动时间窗口,统计请求间隔的方差和分布形态。方差极低且均值在毫秒级的,直接判定为自动化流量。

另一个有效指标是请求路径的跳转逻辑。真实用户会先请求HTML页面,再请求页面内引用的CSS、JS、图片,而且引用顺序与HTML解析顺序相关。伪造流量往往只请求目标URL,或者随机请求静态资源但不携带正确的Referer。你可以建立资源依赖图,检查请求序列是否满足“先主文档后子资源”的约束。大量只请求单一URL且从不携带Referer的会话,大概率是攻击脚本。

利用浏览器计算能力做隐式挑战

攻击工具为了维持高并发,通常不会执行JavaScript或者只执行极简的JS。你可以在页面中嵌入一段轻量级的计算任务,比如要求客户端在提交请求前完成一个基于WebCrypto的哈希计算,并把结果写入自定义Header。正常浏览器执行这段代码几乎无感,而纯脚本攻击要么无法执行,要么执行速度异常。这个方案比传统的验证码对用户体验影响小得多,而且能有效区分无头浏览器和真实浏览器。

需要注意的是,现在部分高级攻击框架也集成了无头浏览器,能够执行JS。针对这种情况,可以进一步检测浏览器环境的一致性。比如检查navigator.webdriver属性、屏幕分辨率与实际渲染尺寸是否匹配、Canvas指纹是否与User-Agent声称的浏览器版本一致。无头浏览器在这些细节上经常露出破绽,尤其是WebGL渲染器字符串和字体列表的差异。

基于资源消耗的非对称识别

DDoS的本质是用低成本请求消耗高成本资源。识别伪造流量的一个关键思路是找出那些“请求成本与响应成本严重不对等”的流量。比如一个搜索请求会触发后端数据库全文检索,而攻击者可以用极低带宽批量发送这类请求。你可以在应用层对每个接口标注资源权重,统计单位时间内同一会话触发的资源消耗总量。如果某个IP或会话的资源消耗速率远超人类操作极限,直接触发限流或隔离。

更精细的做法是在后端埋点记录每个请求的CPU时间、内存分配、数据库查询次数。把这些指标与请求参数关联起来,建立基线模型。当某个参数组合导致的资源消耗显著偏离同类请求的分布时,说明该请求可能是被构造出来专门打高消耗路径的。例如攻击者可能发现某个分页参数传极大值会导致全表扫描,正常用户不会这样操作,但攻击脚本会反复尝试。

会话逻辑与状态机校验

正常用户与Web应用交互时,会遵循应用定义的状态流转。比如登录前必须先获取CSRF Token,提交表单前会先请求验证码接口,支付前会先创建订单。攻击脚本往往跳过中间步骤直接请求最终接口。你可以在服务端为每个会话维护状态机,记录当前所处的业务阶段。如果请求到达时状态不匹配,比如未获取Token就提交登录,或者未创建订单就请求支付回调,直接标记为异常流量。

这个方案需要应用层配合,但效果非常显著。因为攻击者即使完全模拟了HTTP头和行为节奏,也很难在短时间内逆向出完整的业务状态流转逻辑。尤其是那些带有动态Token、签名参数、时间戳校验的接口,攻击脚本要伪造出合法的状态序列成本极高。你可以在关键接口上强制要求前置步骤产生的临时凭证,并设置短有效期,这样即使攻击者抓取了真实流量重放,也会因为凭证过期而失败。

利用机器学习和统计模型做实时判定

规则引擎能挡住已知攻击模式,但对变种和混合型攻击力不从心。你可以在边缘节点采集每个请求的多维特征:请求头字段数量、Header顺序、Cookie长度、URL参数个数、请求体大小、HTTP版本、是否携带特定Header等。把这些特征输入一个轻量级的在线模型,比如随机森林或梯度提升树,输出一个风险分数。模型可以每天用当天的标注数据更新,适应新的攻击手法。

特征工程的重点不是追求复杂,而是选择那些攻击工具难以同时伪造的特征组合。比如“请求头字段数量少”加上“Cookie长度异常长”加上“请求间隔极短”这三个特征组合在一起,正常用户几乎不可能出现。你还可以加入时间维度的特征,比如该IP在过去一小时内的请求总数、唯一URL数、资源类型分布。这些聚合特征能捕捉到单个请求层面看不到的攻击模式。

源地址验证与反向探测

对于伪造源IP的流量,尤其是UDP反射攻击和SYN Flood,可以在收到请求后主动发送一个带随机Cookie的探测包到源地址。如果源地址是伪造的,探测包不会得到正确响应。对于TCP流量,可以利用SYN Cookie机制验证源地址真实性。对于UDP流量,可以在应用层实现类似的握手验证,要求客户端在第一个请求中携带服务端下发的随机数。

反向探测的一个变种是发送一个HTTP重定向或JS挑战,要求客户端携带新的Cookie重新请求。伪造源地址的攻击者收不到这个响应,自然无法完成后续请求。这个方法对代理池也有效,因为代理节点虽然能收到响应,但攻击脚本如果不在代理上处理Cookie和重定向,就无法通过验证。你可以在检测到可疑流量时自动触发这个验证流程,而不是对所有流量都做,以降低对正常用户的影响。

多层联动的实际部署建议

上述方法单用任何一层都可能被绕过,但组合起来能大幅提高攻击成本。建议的部署顺序是:先在网络层做TCP指纹和TLS指纹过滤,挡掉最粗糙的伪造流量;然后在WAF层做行为节奏和请求序列分析,识别自动化脚本;再在应用层做状态机校验和资源消耗监控,挡住针对业务逻辑的攻击;最后用机器学习模型做兜底,处理变种和未知模式。

实际运维中,你需要为每个检测层设置独立的日志和告警,记录被拦截流量的特征分布。定期分析这些数据,找出攻击工具的变化趋势,反向更新规则和模型。同时要建立白名单机制,避免误伤搜索引擎爬虫和合作伙伴的API调用。对于无法确定的可疑流量,可以引入延迟响应或降低服务优先级,而不是直接丢弃,这样既能保护正常用户,又能消耗攻击者的资源。