CC攻击防护中,基于User-Agent黑白名单进行快速过滤是一种非常实用且高效的防御手段。核心逻辑很简单:通过识别请求头中的User-Agent字段,将已知的恶意爬虫、攻击工具、异常客户端列入黑名单直接拦截,同时将搜索引擎蜘蛛、合法浏览器等列入白名单予以放行。这种方法在Web应用防火墙(WAF)、Nginx反向代理、CDN节点等多个层面都能落地实施,响应速度快、资源消耗低,是应对CC攻击的第一道防线。下面我会从原理、配置方法、实战技巧、常见问题等多个维度,把这套方案讲透。

什么是CC攻击以及为什么要用User-Agent过滤

CC攻击(Challenge Collapsar)本质上是一种针对Web服务的高频请求型DDoS攻击。攻击者利用大量代理或肉鸡,模拟正常用户不断向目标服务器发送HTTP请求,耗尽服务器的连接数、CPU和带宽资源,导致正常用户无法访问。CC攻击的特点是请求量不一定巨大,但频率高、持续性强,而且很多时候请求看起来和正常访问非常相似。

User-Agent是HTTP请求头中的一个字段,用来标识发起请求的客户端类型,比如浏览器版本、操作系统、搜索引擎爬虫等。攻击者在发动CC攻击时,通常会使用脚本工具、自定义爬虫或者某些特定的客户端来发送请求,这些工具的User-Agent往往具有明显的特征,比如包含"python-requests"、"curl"、"wget"、"scrapy"、"Go-http-client"等关键词,或者使用随机生成的异常UA字符串。通过对这些特征进行识别和过滤,可以在请求到达应用层之前就将大量恶意流量挡在门外。

User-Agent黑白名单的核心思路

黑名单机制:将已知的恶意User-Agent字符串、正则表达式模式加入黑名单,凡是匹配到黑名单规则的请求直接返回403或444状态码,连接直接关闭。黑名单适合快速拦截已知攻击工具,比如常见的爬虫框架、漏洞扫描器、压力测试工具等。

白名单机制:将合法的客户端User-Agent加入白名单,只有匹配白名单的请求才被允许通过,其余一律拦截。白名单适合安全性要求极高的场景,比如后台管理系统、API接口等只允许特定客户端访问的服务。但白名单的维护成本较高,因为浏览器版本更新频繁,UA字符串会不断变化。

实际部署中,更推荐采用"白名单为主、黑名单为辅"的混合策略。先放行已知合法的UA,再对剩余请求进行黑名单检测,这样既保证了正常访问不受影响,又能有效拦截恶意流量。

Nginx层面实现User-Agent过滤的具体配置

Nginx是最常用的反向代理和Web服务器,在Nginx层面做User-Agent过滤是最直接的方式。以下是具体的配置方法:

# 定义黑名单User-Agent,使用map指令提高效率
map $http_user_agent $bad_bot {
    default 0;
    "~*python-requests" 1;
    "~*curl" 1;
    "~*wget" 1;
    "~*scrapy" 1;
    "~*Go-http-client" 1;
    "~*Java" 1;
    "~*libwww-perl" 1;
    "~*Baiduspider" 0;
    "~*Googlebot" 0;
    "~*Bingbot" 0;
    "~*Slurp" 0;
    "~*YandexBot" 0;
    "~*DuckDuckBot" 0;
    "~*Sogou" 0;
    "~*360Spider" 0;
    "~*YisouSpider" 0;
}

# 在server块中应用过滤规则
server {
    listen 80;
    server_name example.com;

    # 拦截黑名单请求
    if ($bad_bot) {
        return 403;
    }

    # 也可以用更精细的方式:只允许白名单通过
    # map $http_user_agent $allow_ua {
    #     default 0;
    #     "~*Mozilla/5.0" 1;
    #     "~*Chrome/" 1;
    #     "~*Firefox/" 1;
    #     "~*Safari/" 1;
    #     "~*Edge/" 1;
    # }
    # if ($allow_ua = 0) {
    #     return 403;
    # }

    location / {
        proxy_pass http://backend;
    }
}

上面的配置中,map指令比if指令效率更高,因为map是在请求处理阶段一次性计算的,而if是在每个请求中动态判断。正则匹配使用"~*"表示不区分大小写的正则匹配。需要注意的是,Nginx的if指令在某些场景下有陷阱,但用于简单的返回403是没有问题的。

在CDN和WAF层面配置User-Agent规则

如果你的网站使用了CDN服务(如国内主流的CDN厂商),大多数CDN平台都提供了基于User-Agent的访问控制功能。通常在CDN控制台的"访问控制"或"安全配置"模块中,可以直接添加自定义规则:

第一步:创建一条自定义规则,类型选择"User-Agent过滤"。第二步:设置匹配条件,比如User-Agent包含"python-requests"或"curl"。第三步:设置动作,选择"拦截"或"返回403"。第四步:设置优先级,建议将这类规则放在较高优先级,确保在其他规则之前执行。

WAF(Web应用防火墙)层面的配置更加灵活。以ModSecurity为例,可以编写自定义规则:

# ModSecurity规则示例
SecRule REQUEST_HEADERS:User-Agent "@pm python-requests curl wget scrapy" \
    "id:1001,phase:1,deny,status:403,log,msg:'Blocked malicious User-Agent'"

# 白名单规则:放行搜索引擎爬虫
SecRule REQUEST_HEADERS:User-Agent "@pm Googlebot Bingbot Baiduspider" \
    "id:1002,phase:1,pass,nolog"

ModSecurity的@pm操作符表示"包含任意一个模式",适合做黑名单匹配。通过组合多条规则,可以实现非常精细的过滤策略。

如何构建和维护高质量的黑白名单

名单的质量直接决定了过滤效果。一个好的黑名单应该具备以下特点:覆盖面广但误杀率低、定期更新、分层管理。以下是构建名单的具体建议:

第一,收集攻击样本。通过分析Web服务器的访问日志,提取CC攻击期间的User-Agent字段,统计出现频率最高的异常UA。通常攻击工具的UA不会频繁更换,所以只要抓到一次就能长期拦截。

第二,区分爬虫和攻击。并非所有非浏览器UA都是恶意的。搜索引擎爬虫、网站监控工具、RSS阅读器等都会使用非浏览器UA,这些需要加入白名单或单独放行。建议维护一份完整的合法爬虫UA列表,包括Googlebot、Bingbot、Baiduspider、YandexBot、Sogou Spider、360Spider、DuckDuckBot、facebookexternalhit等。

第三,使用正则而非精确匹配。攻击者可能会在UA中加入随机字符或变换大小写来绕过精确匹配,所以黑名单规则应该使用正则表达式。比如".*python.*"、".*bot.*"(注意要排除合法bot)等模式。

第四,建立动态更新机制。可以写一个简单的脚本,定期从公开的威胁情报源、安全社区获取最新的恶意UA特征,自动更新到配置文件中。也可以结合行为分析,当某个UA的请求频率异常高时,自动将其加入临时黑名单。

User-Agent过滤的局限性和补充手段

必须客观地说,单靠User-Agent过滤无法完全防御CC攻击。原因有三:第一,攻击者可以伪造User-Agent,把恶意请求伪装成正常浏览器;第二,高级CC攻击会使用真实的浏览器内核或模拟完整的浏览器指纹,UA看起来完全正常;第三,有些合法客户端(比如某些APP内嵌浏览器)的UA也可能被误判。

所以User-Agent过滤应该作为多层防御体系中的一环,而不是唯一手段。建议配合以下措施一起使用:

频率限制:对同一IP或同一Session在单位时间内的请求次数进行限制,超过阈值直接限流或封禁。Nginx中可以用limit_req模块实现。

# Nginx频率限制示例
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

server {
    location / {
        limit_req zone=one burst=20 nodelay;
        proxy_pass http://backend;
    }
}

验证码挑战:当检测到可疑请求时,返回一个验证码页面或JavaScript挑战,只有通过验证的请求才能继续访问。这对自动化攻击工具非常有效。

IP信誉库:结合IP地理位置、历史行为、代理检测等信息,对来自高风险地区或已知代理池的IP进行额外过滤。

行为分析:通过分析请求的时间分布、页面访问路径、鼠标轨迹等行为特征,识别出机器自动化访问和真实用户访问的区别。

实战中的常见问题和解决方案

问题一:误杀正常用户。有些用户使用的浏览器或插件会修改UA,或者使用了比较冷门的浏览器,导致被误判。解决方案是建立反馈机制,当用户报告被误拦截时,及时将其UA加入白名单,同时在日志中记录误杀情况,定期分析优化规则。

问题二:规则冲突。当黑名单和白名单规则存在重叠时,需要明确优先级。一般原则是白名单优先于黑名单,即如果一个UA同时匹配了白名单和黑名单,以白名单为准放行。

问题三:性能影响。如果黑名单规则过多,每个请求都要进行大量正则匹配,会增加CPU开销。解决方案是使用map指令预编译规则、合理分组、只对必要的请求进行检测(比如先通过IP频率筛选,再对高频IP做UA检测)。

问题四:攻击者伪造常见UA。当攻击者把UA改成"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"这类常见浏览器UA时,仅靠UA过滤就失效了。这时候必须依赖频率限制、行为分析等其他手段来识别。

总结和最佳实践建议

CC防护中基于User-Agent的黑白名单过滤是一种成本低、见效快、易于实施的基础防御手段。它特别适合作为第一层过滤,在流量到达应用服务器之前就剔除大量明显的恶意请求。但它不是银弹,必须和频率限制、验证码、行为分析、IP信誉等手段组合使用,形成纵深防御体系。

最佳实践总结:第一,优先使用map+正则的方式在Nginx层实现,性能最优;第二,白名单放合法浏览器和搜索引擎爬虫,黑名单放已知攻击工具和异常客户端;第三,定期更新名单,结合日志分析持续优化;第四,设置误杀反馈通道,避免影响正常用户体验;第五,永远不要只依赖单一手段,多层防御才是王道。

做好这些,你的CC防护能力至少能提升一个档次,大部分低级和中级的CC攻击都能被有效挡在外面。