CC攻击的本质是消耗服务器资源,而恶意UA(User-Agent)识别与拦截是防御体系中成本最低、见效最快的一环。很多站点被CC打挂,不是因为带宽不够,而是因为大量伪造请求带着各种自动化工具的UA直接穿透了应用层,后端脚本被无意义地反复执行。所以第一步不是堆硬件,而是把UA识别策略做细。
恶意UA的典型特征与分类
攻击流量中的UA通常有几个明显特征:一是大量请求使用完全相同的UA字符串,且该字符串与正常浏览器分布明显不符;二是UA为空或格式畸形,比如缺少Mozilla标识、版本号异常;三是使用已知的自动化工具、扫描器、压力测试工具的默认UA。常见的恶意UA包括sqlmap、nmap、masscan、python-requests、Go-http-client、curl、wget、libwww-perl、Java/1.8.0_181、Apache-HttpClient、okhttp、Scrapy、MJ12bot、SemrushBot、DotBot等。这些UA在正常用户访问中占比极低,但在攻击流量中会集中出现。
需要注意的是,攻击者也会伪造浏览器UA,比如直接复制Chrome或Safari的标准字符串。这种情况下单纯靠UA黑名单拦不住,需要结合UA的分布统计和行为特征来判断。例如正常站点访问中,Chrome版本号会呈现多样化的分布,而攻击流量往往所有请求都是同一个版本号,甚至同一个完整UA字符串。这种“UA高度集中”本身就是异常信号。
UA识别策略的四个层次
第一层是精确黑名单匹配。把已知的恶意工具UA、空UA、格式错误UA直接列入拦截规则。这一层实现简单,在Nginx、Apache、CDN边缘节点都可以配置。但缺点是只能拦截已知的、未修改的UA,攻击者一旦随机化UA就能绕过。
第二层是正则模式匹配。很多自动化工具虽然版本号会变,但UA中会保留固定的特征片段,比如“python-requests/2.28.1”中的“python-requests”、“Go-http-client/1.1”中的“Go-http-client”、“curl/7.68.0”中的“curl/”。通过正则表达式可以覆盖同一类工具的不同版本。同时可以匹配UA中出现的可疑关键词,如“bot”、“spider”、“crawler”、“scanner”、“attack”、“inject”、“exploit”等,但要注意避免误伤搜索引擎爬虫,需要配合白名单使用。
第三层是UA白名单与评分机制。对于UA为空或者明显非浏览器格式的请求,不一定要全部拦截,而是进入评分系统。例如给空UA加50分风险值,给已知恶意工具UA加100分,给格式异常UA加30分。当同一IP在短时间内累计风险值超过阈值时,触发验证码或者直接封禁。这种动态评分比单纯黑白名单更灵活,能应对UA伪造和混合攻击。
第四层是UA分布统计与基线对比。正常业务流量中,UA的分布是相对稳定的。可以按小时统计UA种类数量、Top10 UA占比、新出现UA比例。如果某个时间段内单一UA占比突然超过80%,或者UA种类数量骤降,说明很可能正在遭受CC攻击。这个策略不依赖具体UA内容,攻击者即使伪造浏览器UA,也很难模拟出正常用户的UA多样性。
Nginx层面的UA拦截配置
在Nginx中可以通过map和if指令实现灵活的UA拦截。以下是一个基础配置示例:
# 在http块中定义UA黑名单map
map $http_user_agent $block_ua {
default 0;
"~*sqlmap" 1;
"~*python-requests" 1;
"~*Go-http-client" 1;
"~*curl/" 1;
"~*wget" 1;
"~*libwww-perl" 1;
"~*Apache-HttpClient" 1;
"~*okhttp" 1;
"~*scrapy" 1;
"~*nmap" 1;
"~*masscan" 1;
"~*zgrab" 1;
"~*fuzz" 1;
"" 1;
}
# 在server或location块中调用
if ($block_ua = 1) {
return 444;
}
这里使用444状态码直接关闭连接,不返回任何内容,能节省响应带宽。但要注意if指令在Nginx中属于rewrite模块,大量使用可能影响性能,建议把UA拦截放在CDN边缘或者前置代理层处理。
对于需要更细粒度控制的场景,可以使用OpenResty或Lua脚本实现UA评分和动态拦截。例如在access阶段检查UA,计算风险值并写入共享内存,同一IP的风险值累计超过阈值后拒绝后续请求。这种方式能有效对抗UA轮换的攻击。
UA白名单与搜索引擎爬虫处理
UA拦截策略中最容易出问题的就是误伤搜索引擎爬虫。百度蜘蛛、搜狗蜘蛛、360蜘蛛、必应爬虫等都有官方公布的UA特征。需要在拦截规则中优先放行这些白名单UA。但要注意,攻击者也会伪造搜索引擎UA来绕过拦截,所以白名单不能只靠UA字符串判断,还需要配合反向DNS解析验证。例如百度蜘蛛的IP必须来自baidu.com域名的反向解析,否则即使UA正确也应当拒绝。
对于无法验证真实性的搜索引擎UA,可以采取限制访问频率的策略。正常搜索引擎爬虫的抓取频率是可控的,而伪造爬虫的CC攻击往往请求频率极高。对声称是爬虫的UA设置单独的速率限制,比如每秒不超过5个请求,超过就返回429或延迟响应。这样既不影响正常收录,又能压制伪造爬虫的攻击。
UA行为关联分析
单纯看UA字符串还不够,需要把UA和其他请求特征关联起来分析。例如一个声称是Chrome浏览器的请求,如果它的TLS指纹、HTTP头顺序、Accept-Language、Accept-Encoding等特征与真实Chrome不一致,就说明UA是伪造的。攻击者往往只修改UA字符串,而忽略了其他浏览器指纹特征。通过对比UA声称的浏览器类型与实际TLS指纹、Header顺序是否匹配,可以识别出大量伪造UA的自动化流量。
另一个有效的关联维度是UA与请求路径的关系。正常用户访问网站时,会按照页面结构依次请求HTML、CSS、JS、图片等资源,UA保持一致。而CC攻击流量往往只请求同一个URL,或者只请求动态接口,缺少静态资源请求。如果某个UA的所有请求都指向同一个动态接口,且没有后续的静态资源加载,基本可以判定为攻击流量。
UA拦截的局限性与补充手段
必须明确,UA识别只是CC防御体系中的一个环节,不能单独依赖。攻击者可以轻易修改UA,甚至从真实浏览器流量中收集大量UA进行轮换。因此UA策略必须与其他防御手段配合使用:IP频率限制、验证码挑战、TLS指纹识别、行为分析、设备指纹等。UA策略的价值在于用极低的计算成本过滤掉大部分低水平攻击流量,让后端安全系统集中资源处理更复杂的攻击。
在实际部署中,建议把UA拦截放在最前端,先过滤掉明显的自动化工具和格式异常请求。然后对剩余的流量进行频率统计和行为分析,对可疑流量弹出验证码或进行JavaScript挑战。最后在后端应用层再做一次业务逻辑级别的防护,比如接口参数校验、会话管理、数据库查询优化等。这种分层防御架构能最大化利用每一层的处理能力,避免单点失效。
UA策略的持续运营与更新
恶意UA库不是一成不变的,新的攻击工具和扫描器不断出现,旧工具的UA也可能被修改。需要定期分析拦截日志和访问日志,找出被拦截的UA中是否有误伤,同时发现新的恶意UA特征。可以建立自动化流程:每天统计访问日志中出现的新UA,与已知恶意UA库进行相似度匹配,对疑似恶意的UA进行人工审核后加入拦截规则。同时监控拦截率的变化,如果拦截率突然下降,可能意味着攻击者更换了UA策略,需要及时调整规则。
另外要关注UA拦截对业务的影响。某些合法的第三方服务、API调用方可能使用非浏览器UA,比如企业对接系统使用Java或Python客户端。在部署UA拦截前,需要梳理业务中所有合法的非浏览器访问来源,将它们加入白名单。否则拦截策略上线后可能导致正常业务中断,这种损失比CC攻击本身更严重。
UA识别与拦截策略的核心思路是:用黑名单快速过滤已知威胁,用白名单保护合法流量,用评分机制应对未知威胁,用行为分析发现伪造UA,用持续运营保持策略有效性。把这五个环节做扎实,CC攻击中的大部分自动化流量都能在到达应用层之前被拦截下来。
