适用场景
恶意 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 行为分析流程,根据访问日志不断优化识别规则。