Nginx拦截恶意爬虫,保护CMS服务器资源
恶意爬虫会在短时间内抓取大量页面,导致CMS服务器CPU、内存和带宽被占满,正常用户访问变慢甚至打不开。
本文从零基础出发,介绍在Nginx层拦截恶意爬虫的完整流程,你只需要一台已安装Nginx的服务器,按照步骤修改配置并重载服务,即可过滤掉大部分低质量爬虫流量。
准备:确认环境和日志位置
先确认Nginx是否在运行,以及网站配置文件的存放路径。
原生Nginx通常在 /etc/nginx/conf.d/ 或 /etc/nginx/sites-available/,宝塔面板则在 /www/server/panel/vhost/nginx/。
nginx -v
systemctl status nginx
ls /etc/nginx/conf.d/
建议先备份当前配置,避免改错后无法恢复:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
同时查看访问日志,找出高频可疑IP和User-Agent,为后面写规则提供依据:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
tail -1000 /var/log/nginx/access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -nr | head -20
配置拦截规则:按User-Agent和请求频率过滤
Nginx拦截恶意爬虫最直接的方式是匹配User-Agent,把已知的采集工具、扫描器、空User-Agent请求返回403。
在http块或站点server块中加入以下片段:
map $http_user_agent $bad_bot {
default 0;
~* (semrush|ahrefs|majestic|mj12bot|dotbot|blexbot) 1;
~* (python-requests|curl|wget|scrapy|go-http-client) 1;
"" 1;
}
然后在server块中引用这个变量:
if ($bad_bot) {
return 403;
}
对于请求频率过高的IP,可以用limit_req做限速。
先在http块定义共享内存区:
limit_req_zone $binary_remote_addr zone=cms_limit:10m rate=5r/s;
再在server或location中启用:
location / {
limit_req zone=cms_limit burst=10 nodelay;
try_files $uri $uri/ /index.php?$query_string;
}
宝塔面板用户可以直接在“网站” -> “设置” -> “配置文件”中粘贴上述规则,保存后点击“重载配置”。
避坑:规则顺序和误伤问题
拦截规则要放在server块靠前位置,否则可能被后面的location覆盖。
如果网站使用CDN,$binary_remote_addr拿到的是CDN节点IP,不是真实访客IP,需要先配置set_real_ip_from和real_ip_header,否则限速会误伤所有用户。
不要直接封禁整个User-Agent包含bot的请求,Googlebot、Bingbot等正规搜索引擎爬虫也包含bot,误封会影响网站收录。
建议只针对明确已知的恶意采集器名称做精确匹配。
修改后务必用nginx -t测试语法:
nginx -t
看到syntax is ok和test is successful后再重载:
systemctl reload nginx
验证:确认拦截生效且正常访问不受影响
用curl模拟恶意User-Agent,应返回403:
curl -A "python-requests" -I http://你的域名/
再用正常浏览器User-Agent访问,应返回200:
curl -A "Mozilla/5.0" -I http://你的域名/
观察日志中403状态码的数量变化,确认拦截规则确实在生效:
tail -f /var/log/nginx/access.log | grep " 403 "
如果服务器资源占用明显下降,且正常用户访问速度恢复,说明配置达到了预期效果。
常见问题
问:加了规则后网站打不开怎么办?
先执行nginx -t查看报错行,常见原因是map或limit_req_zone写在了server块内,应移到http块。
问:拦截后搜索引擎不收录了?
检查是否误封了Googlebot或Bingbot的User-Agent,把对应关键词从$bad_bot匹配中移除即可。
问:宝塔面板保存后不生效?
确认点击的是“重载配置”而不是仅“保存”,必要时重启Nginx服务。
问:能完全挡住所有恶意爬虫吗?
不能。Nginx层拦截主要针对已知特征和频率异常,高级爬虫会伪装User-Agent,建议配合robots.txt、验证码和WAF做多层防护。