CC攻击的核心逻辑不是比谁带宽大,而是比谁更“真”。攻击者通过海量的代理IP池发起请求,耗尽服务器的连接数或数据库资源。要防住CC攻击,关键在于识别这些代理IP的“非人类”特征。一个真实的家庭宽带IP和一个从代理池中提取的IP,在链路特征、端口开放情况、甚至是TCP/IP堆栈指纹上都有着本质的区别。直接深入这些特征,是构建防御体系的第一步。
HTTP请求头的不一致性与缺失代理服务器在转发流量时,往往会粗暴地处理HTTP头。最明显的特征是X-Forwarded-For字段的异常。虽然这个字段通常用于记录原始IP,但在低质量代理池中,它经常被伪造或包含内部IP地址,例如“192.168.x.x”或“10.x.x.x”。更隐蔽的特征在于请求头的顺序。真实浏览器(如Chrome、Firefox)发出的请求头顺序是严格固定的,而Python的requests库或Go的http客户端发出的头顺序则完全不同。例如,真实Chrome通常以Host、Connection、sec-ch-ua、sec-ch-ua-platform、User-Agent等顺序排列,而脚本工具往往将User-Agent放在极靠前的位置,或者缺少Accept-Language、Accept-Encoding等关键协商头。直接检查请求头键名的排列顺序,比检查头内容本身更难被伪造。
TCP/IP堆栈指纹与JA3/JA4签名单纯依靠HTTP层面的特征已经不够,因为攻击者会精心构造请求头。必须下沉到传输层。JA3和JA4指纹是目前识别代理工具和模拟器最硬核的手段。JA3通过收集Client Hello包中的TLS版本、加密套件、扩展列表及其顺序生成MD5哈希。真实浏览器的指纹是特定且随版本变化的,而Python、Go、Java等语言编写的脚本,其TLS库生成的指纹是固定的。例如,一段简单的Python requests请求,其JA3指纹与真实Chrome截然不同。更高级的识别需要看TCP初始窗口大小、TTL值以及是否支持TCP Fast Open。代理IP往往部署在云服务器或低质量IDC机房,其TCP窗口大小和IP层的TTL与真实家庭宽带或移动网络存在显著差异。你可以通过被动嗅探建立真实用户的基线,一旦Client Hello的加密套件顺序出现异常(如仅支持古老的加密算法或缺少关键的扩展),即可判定为代理或脚本。
端口扫描与开放服务特征代理IP的本质是一台服务器或一台被控的肉鸡。从防御方的角度,虽然不建议主动扫描,但通过被动的流量分析可以发现端倪。大量来自代理池的IP地址,往往开放着特定的端口。例如,常见的HTTP代理端口如8080、3128、1080,或者SOCKS5代理端口1080。更隐蔽的特征在于,这些IP地址如果属于云服务商,其反向DNS查询结果会暴露其归属,如包含“compute”、“amazonaws”、“vps”等关键词。即使攻击者关闭了代理端口,其IP段所属的AS号往往集中在几家特定的廉价VPS提供商或主机托管商。通过分析攻击流量的ASN分布,如果发现大量请求集中在非主流运营商或IDC的AS域内,即可直接进行信誉标记。家庭宽带IP通常不会开放80、443之外的监听端口,而代理节点往往会留下SSH(22端口)或远程桌面(3389端口)的痕迹。
浏览器指纹与JavaScript执行环境对于能够执行JavaScript的Web环境,识别代理池变得更为直观。攻击者使用无头浏览器(如Puppeteer、Playwright、Selenium)时,虽然能模拟点击,但JavaScript执行环境会暴露其马脚。通过检测Navigator对象的属性,可以发现异常。例如,navigator.webdriver属性在自动化模式下通常为true。更底层的检测包括检查window.chrome对象是否存在且具有特定方法,或者利用Canvas指纹和WebGL指纹。代理池为了节省资源,往往在极简的Linux环境下运行无头浏览器,其WebGL渲染器字符串会显示为“Google SwiftShader”或“Mesa”等软件渲染器,而非真实的NVIDIA或AMD显卡驱动。此外,通过注入JavaScript检测浏览器的插件列表、屏幕分辨率与窗口大小的比值,也能有效区分真人和模拟器。一个真实的移动端IP,其屏幕尺寸和User-Agent必然是匹配的,而代理池经常出现移动端User-Agent却搭配桌面端分辨率的错位情况。
行为分析与流量时序特征这是最难伪造的特征。真实用户的访问具有随机性和逻辑性。他们会加载HTML,然后解析CSS和JS,再请求图片,最后可能发起AJAX请求,请求之间会有几百毫秒到几秒的间隔。而CC攻击工具,尤其是基于代理池的并发攻击,往往呈现出极高的并发度和极其规律的时序。例如,每秒请求数恒定在某个数值,或者所有代理IP几乎在同一毫秒内发起对同一URL的请求。更关键的是资源加载的完整性。真实浏览器会自动加载页面引用的所有静态资源,而简单的HTTP Flood脚本往往只攻击单一URL,不会去获取CSS或图片。通过检查Referer字段和静态资源的加载比例,可以建立模型。如果一个IP在短时间内请求了大量动态页面,却从未请求过任何关联的静态资源,或者其请求间隔精确到毫秒级且毫无波动,这几乎可以肯定是代理池发出的攻击流量。利用滑动窗口算法分析请求间隔的熵值,熵值极低的流量往往意味着脚本行为。
代理协议的残留与HTTP方法限制很多廉价代理只支持HTTP/1.0协议,或者不支持CONNECT方法。当你的服务器强制使用HTTP/2或HTTP/3时,大量来自代理池的攻击流量会因为协议协商失败而直接暴露。此外,HTTP方法的使用也是一个识别点。真实浏览器极少使用HEAD、OPTIONS、TRACE等方法,而某些扫描器或攻击脚本会频繁使用这些方法进行探测。观察一个IP是否发送了不规范的方法,或者其HTTP版本号始终停留在1.0,是识别老旧代理工具的直观指标。
利用蜜罐与计算挑战在识别出可疑特征后,可以采用计算挑战进行验证,但必须注意用户体验。一种硬核的做法是使用工作量证明(PoW)。当请求被标记为可疑时,返回一个需要客户端计算哈希值的JavaScript脚本。真实用户的浏览器在后台计算毫无感知,而脚本工具如果不具备完整的JavaScript引擎,则无法通过验证。另一种更隐蔽的方式是动态干扰:在HTML中插入随机的、不可见的链接(蜜罐链接)。真实用户不会去点击或请求这个链接,而扫描器或配置不当的代理爬虫会递归抓取所有链接。一旦某个IP请求了这个蜜罐链接,直接将其拉入黑名单。这种防御方式对代理池极其有效,因为代理池通常只是盲目的转发流量,不具备语义识别能力。
构建基于多维特征的评分系统单维度的特征容易产生误杀,必须构建动态评分机制。不要简单地设置“是代理”或“不是代理”的二元判断,而是给每个IP打分。例如:JA3指纹异常扣20分,ASN属于IDC机房扣30分,未加载静态资源扣25分,请求头顺序异常扣15分,HTTP协议版本过低扣10分。当总分超过阈值(如60分)时,触发验证码或PoW挑战;超过80分则直接重置连接。这套系统需要结合实时流处理引擎,对千万级IP进行毫秒级的特征提取和信誉更新。关键在于,这些特征库需要不断进化,因为攻击者的代理池也在不断更换IP和升级工具。只有深入到底层的TCP指纹和物理链路特征,才能在攻防对抗中占据优势。
