恶意 Bot 识别与拦截实战配置指南

适用场景

恶意 Bot(爬虫机器人)是互联网上最常见的流量威胁之一,它们可能执行网站内容盗采、撞库攻击、CC 攻击、虚假注册和评论灌水等恶意行为。根据 Imperva 报告,2025 年全球互联网流量中有近 50% 来自自动化程序,其中约 30% 为恶意 Bot。本教程适用于网站运维人员、安全工程师和 CDN 管理员,帮助他们在 Nginx/CDN 层识别和拦截常见恶意 Bot 流量。

前置条件

  • 拥有一台运行 Nginx 的 Web 服务器(版本 1.18+)
  • 具备 root 或 sudo 权限
  • 了解基础的 Nginx 配置语法
  • 如有 CDN(Cloudflare、阿里云 CDN 等),需具备 CDN 管理控制台访问权限

原理说明

恶意 Bot 识别的核心理念是基于行为特征和请求特征的”多维度检测”。常见的检测维度包括:User-Agent 特征(模拟浏览器的 Bot 头信息异常)、请求频率与间隔(Bot 的请求间隔通常高度均匀)、请求路径模式(Bot 尝试敏感路径)、IP 信誉度(来自已知代理或数据中心的 IP)、JA3 指纹(TLS 握手指纹,模拟浏览器较难)。本教程重点实现 Nginx 层面的 User-Agent 过滤、速率限制和 GeoIP 区域封锁。

操作步骤

步骤 1:配置 User-Agent 黑名单

在 Nginx 的 http 块中创建 UA 过滤规则,拦截已知恶意 Bot 的 User-Agent:

# 在 /etc/nginx/nginx.conf 的 http 块中添加

# 定义恶意 UA 正则匹配
map $http_user_agent $bad_bot {
    default 0;
    # 已知恶意爬虫
    ~*curl 1;                           # 伪装成 curl 的 Bot(需评估,可能误杀合法 curl 调用)
    ~*wget 1;
    ~*python-requests 1;
    ~*go-http-client 1;
    ~*scrapy 1;
    ~*java/ 1;
    ~*libwww-perl 1;
    ~*masscan 1;
    ~*nikto 1;
    ~*sqlmap 1;
    ~*nmap 1;
    ~*zgrab 1;
    ~*(data_fetcher|dataforseo|zoominfo) 1;
    ~*(semrush|ahrefsbot|majestic) 0;    # 知名SEO工具,可选择放行
    ~*(mj12bot|dotbot|blexbot) 0;        # 搜索引擎 Bot,建议放行
}

server {
    # 在 server 块中使用
    if ($bad_bot) {
        return 403;
    }
}

步骤 2:创建专门的反 Bot 配置文件

将反 Bot 规则抽取为独立文件,便于管理和复用:

# 创建反 Bot 配置文件
sudo vim /etc/nginx/conf.d/antibot.conf

# 填入以下内容
# === 恶意 Bot 识别与拦截规则 ===

# 1. UA 黑名单
map $http_user_agent $blocked_ua {
    default 0;
    ~*(masscan|nikto|sqlmap|nmap|zgrab|python-requests|go-http-client|scrapy|java/) 1;
}

# 2. 空 UA 拦截(浏览器必带 User-Agent)
map $http_user_agent $empty_ua {
    default 0;
    "" 1;
}

# 3. 限制请求方法(仅允许 GET/POST/HEAD)
if ($request_method !~ ^(GET|HEAD|POST)$) {
    return 405;
}

# 在 nginx.conf 中包含此文件
# include /etc/nginx/conf.d/antibot.conf;

步骤 3:配置速率限制

基于 IP 和 URI 的速率限制是拦截爬虫 Bot 的有效手段:

# 在 nginx.conf 的 http 块中添加速率限制区域

# 按 IP 限制:每秒最多 30 个请求
limit_req_zone $binary_remote_addr zone=bot_limit:10m rate=30r/s;

# 按 IP + URI 组合限制:用于敏感路径
limit_req_zone $binary_remote_addr$uri zone=sensitive_limit:10m rate=5r/s;

# 限制登录/注册接口的速率
limit_req_zone $binary_remote_addr zone=auth_limit:10m rate=3r/m;

server {
    # 应用速率限制(在 location 中使用)
    location / {
        limit_req zone=bot_limit burst=50 nodelay;
    }

    # 保护 API 接口
    location /api/ {
        limit_req zone=sensitive_limit burst=10 nodelay;
    }

    # 保护登录接口
    location /wp-login.php {
        limit_req zone=auth_limit burst=5;
    }
    location /wp-admin {
        limit_req zone=auth_limit burst=5;
    }
}

步骤 4:配置 GeoIP 区域封锁

如果业务仅面向中国大陆用户,可以封锁来自境外 IP 的流量,大幅降低恶意 Bot 攻击面:

# 安装 GeoIP2 模块
# Ubuntu:
sudo apt install libnginx-mod-http-geoip2

# 下载 GeoIP2 数据库(免费版)
sudo mkdir -p /etc/nginx/geoip
# 从 https://dev.maxmind.com/geoip/geolite2-free-geolocation-data 下载
# 或使用国内镜像源

# 在 nginx.conf 中配置
geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb {
    $geoip2_data_country_code source=$remote_addr country iso_code;
}

map $geoip2_data_country_code $blocked_country {
    default 1;        # 默认封锁
    CN 0;             # 中国放行
    HK 0;             # 中国香港放行(按需)
    TW 0;             # 中国台湾放行(按需)
    MO 0;             # 中国澳门放行(按需)
}

server {
    if ($blocked_country) {
        return 403;
    }
}

步骤 5:配置 JS Challenge(高级 Bot 检测)

对于无法通过 UA 和速率限制识别的”聪明 Bot”,可以使用 JS Challenge 方式验证。Nginx 本身不支持该功能,但可以结合第三方方案:

# 方案一:使用 Cloudflare 的 JS Challenge
# 在 Cloudflare 控制台配置 WAF 规则
# Security → WAF → Create Rule
# 条件: Threat Score > 0  或  Bot Score < 30
# 动作: JS Challenge

# 方案二:使用开源 nginx-bot-detection 模块
# https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker
# 该方案基于定期更新的恶意 IP 和 UA 数据库
git clone https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker.git /usr/local/nginx-bot-blocker
cd /usr/local/nginx-bot-blocker
sudo bash install-ngxblocker -x

# 安装后自动生成每日更新的黑名单配置文件

步骤 6:验证配置并重载 Nginx

# 测试配置语法
sudo nginx -t

# 重载 Nginx
sudo systemctl reload nginx

# 查看实时访问日志(检查拦截效果)
sudo tail -f /var/log/nginx/access.log | grep "403"

# 统计被拦截的 Bot 数量
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

配置验证

完成配置后,通过以下方法验证 Bot 拦截效果:

验证 1:模拟恶意 Bot
# 使用 python-requests 访问网站(应被拦截)
curl -A "python-requests/2.28" https://www.wafai.cn/
# 期望输出:403 Forbidden

验证 2:空 UA 拦截
curl -A "" https://www.wafai.cn/
# 期望输出:403 或返回默认空 UA 的 deny 页面

验证 3:速率限制测试
# 使用 for 循环模拟快速请求
for i in {1..60}; do curl -s -o /dev/null -w "%{http_code}
" https://www.wafai.cn/; done | sort | uniq -c
# 期望:超过 30r/s 后出现 503(Service Temporarily Unavailable)

验证 4:查看真实拦截日志
sudo tail -100 /var/log/nginx/access.log | grep "403"
# 确认恶意 Bot 的 IP 和 UA 被正确记录

常见问题

Q1:User-Agent 过滤误封了正常搜索引擎(如百度、Google),如何处理?

在 map 块中将已知搜索引擎 Bot 的匹配值设为 0。常见的搜索引擎 Bot 包括:Baiduspider、Googlebot、Bingbot、Sogou、YandexBot 等。建议使用 nslookup 反向解析搜索引擎 IP 来验证其真实性,并配合 $blocked_ua 和搜索引擎 IP 范围白名单双重校验。

Q2:速率限制导致正常用户访问网站时遇到 503,如何优化?

首先检查 burst 参数是否过小。burst 表示允许临时超过限制的请求数队列。建议对于首页等公共页面使用 burst=50 nodelay;对于 API 接口使用 burst=10-20。同时,可以基于 cookie(已登录用户)设置更高的速率上限,区分人类用户和 Bot 访问。

总结

恶意 Bot 识别与拦截是网站安全运营的必修课。本教程从 User-Agent 过滤、速率限制、GeoIP 区域封锁和 JS Challenge 四个层次构建了多层防护体系。在实际运维中,建议结合 CDN WAF(Cloudflare 或阿里云 WAF)与 Nginx 本地规则形成联动防御——CDN 层拦截已知 Bot IP 和大流量攻击,Nginx 层补充行为分析和速率限制。同时,维护一个定期的 Bot 行为分析流程,根据访问日志不断优化识别规则。