香港服务器被恶意爬虫抓取怎么处理?Nginx限速、WAF拦截与源站防护实战

前阵子我在看一台香港站点服务器的访问日志时,发现一个很典型的问题:页面没上热搜,广告也没猛投,但 access.log 一直在疯涨。带宽并没有先被打满,CPU 也不是一直 100%,可 PHP-FPM、MySQL、磁盘 I/O 都开始抖,页面偶尔还会变慢。
最后一查,不是正常用户暴增,而是恶意爬虫在反复抓取。
这类流量最烦的地方在于,它不像传统攻击那样“猛一下就把你打挂”,它更像钝刀子割肉:不断扫目录、抓搜索页、翻分页、试接口、碰登录口、拉图片、拉 PDF,甚至伪装成正常浏览器。OWASP 近年的自动化威胁项目也专门在研究这类真实世界里的自动化攻击;Cloudflare 的源站防护文档同样明确提到,过多请求会拉高延迟、增加成本,严重时能把源站拖离线。
很多人一遇到这个问题,第一反应就是:“我把 robots.txt 一封,不就行了吗?”
这恰恰是最容易踩的坑。robots.txt 只能约束守规矩的爬虫,不是安全机制。 Google 官方文档写得很清楚:robots.txt 主要是告诉爬虫哪些 URL 不要抓,它不是防止页面被搜索引擎收录或阻止恶意抓取的安全手段;如果你真的不想让页面进入搜索结果,应该用 noindex,或者直接做密码保护/登录保护。
所以,香港服务器被恶意爬虫频繁抓取,正确思路不是“只靠一个开关解决”,而是分成四步:
先识别谁是正常爬虫,谁是假爬虫;再做限速;再做拦截;最后给源站减压。
一、先说结论:恶意爬虫最怕的,不是单纯封 IP,而是“分层处理”
我自己更推荐把方案拆成 5 层:
第 1 层:区分“该放行的”和“该拦的”
真正的搜索引擎爬虫、监控机器人、支付回调、CDN 回源,不应该误杀。
Cloudflare 现在有 verified bots 机制,能帮助你识别一部分“已验证的好爬虫”;如果你前面套了 Cloudflare,也可以在规则里优先放过这些已识别的正常机器人。
第 2 层:Nginx 限速
limit_req 适合限制请求速率。Nginx 官方文档说明,这个模块本质上是按 key 做请求处理速率限制,使用的是漏桶算法。
第 3 层:Nginx 限连接
limit_conn 适合限制同一来源的并发连接数。Nginx 官方文档明确说,它可以按定义的 key 限制连接数量,常见就是按单 IP 限。
第 4 层:WAF / CDN 挑战与源站隐藏
如果前面用了 Cloudflare 这类代理,官方建议你在源站只允许 Cloudflare 的 IP 访问,否则别人可以绕过前面的防护,直接打你源站。
第 5 层:日志联动封禁
对于扫目录、撞路径、疯狂 404、反复访问 /search、/wp-login.php、/xmlrpc.php 这类行为,应该用日志联动工具或防火墙规则自动封。
在内核层面,nftables 也支持基于 token bucket 的速率限制,这一层适合兜底。
二、什么样的香港服务器,更适合扛这类恶意抓取?
这个问题很多人会忽略。
其实恶意爬虫不一定先吃满带宽,它经常先吃动态资源。
比如:
- WordPress 被不停抓文章页、标签页、搜索页
- 外贸站被不停拉产品详情页、筛选页、图片页
- 接口站被不断打 API、文档页、下载页
- 站点被反复扫不存在的路径,制造大量 404
这时候,真正吃紧的往往不是“网卡先爆”,而是:
- Web 并发处理能力
- PHP / Java / Node 进程数
- 数据库查询压力
- 磁盘随机读写
- 缓存命中率
所以我一般会把配置这样分:
方案 1:轻量企业站 / 展示站
适合公司官网、着陆页、小型外贸站
示例配置:
- CPU:Intel E-2334(4 核 8 线程)
- 内存:32GB DDR4
- 硬盘:960GB NVMe SSD
- 带宽:100M BGP,附带 15M 直连 CN2 优化
- 系统:Ubuntu 22.04 + Nginx
这类配置能扛普通站点的日常抓取和小规模异常访问,但前提是前面要配好 CDN、缓存和限速。
如果恶意爬虫主要在扫静态页,这个级别已经够用。
方案 2:主力业务站 / WordPress / 独立站
适合跨境电商、内容站、产品页较多的网站
示例配置:
- CPU:AMD EPYC 4585PX(16 核 32 线程)
- 内存:64GB DDR5-5600
- 硬盘:960GB NVMe SSD
- 带宽:100M BGP,附带 25M 直连 CN2 优化
- 系统:Ubuntu 22.04 / Debian 12 + Nginx + Redis
这类配置更适合处理:
- 动态页面较多
- 数据库查询频繁
- 抓取路径复杂
- 海外访客 + 国内访问都要兼顾的场景
方案 3:中大型站 / API 站 / 下载站
适合接口较多、资源文件较多、图片或附件多的业务
示例配置:
- CPU:AMD EPYC 4585PX 或更高主频平台
- 内存:128GB
- 硬盘:2 × 960GB NVMe SSD(建议 RAID1)
- 网络:1G 端口 + 前置 CDN / WAF
- 架构:Nginx 反向代理 + Redis 缓存 + 数据库读写优化
这类场景如果还裸奔不上防护,光靠加 CPU 没用。
真正关键的是:把恶意请求尽量挡在源站前面。
三、现场排查时,我最先看的不是封禁规则,而是日志
我一般先跑这几个命令,先确认到底是谁在抓、抓了什么、抓得多快。
# 统计来源 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
# 统计最常被访问的 URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -30
# 看常见 UA
awk -F\" '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -30
# 找高频 404
awk '($9 ~ /404/){print $1,$7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -30
# 重点看容易被抓爆的路径
grep -E 'wp-login|xmlrpc|search|api|\.php|\.env|admin' /var/log/nginx/access.log | tail -100
我看日志时最关注 5 种特征:
- 同一 IP / 同一网段频繁请求
- 大量请求集中在搜索页、筛选页、分页页、接口页
- 大量 404 / 403 / 301 / 302
- UA 很假,或者 UA 很随机
- 请求节奏不像人,像程序批量跑
如果你一上来就全站封,很容易把正常搜索引擎也一起误伤。
尤其是外贸站、博客站,误伤真爬虫之后,收录和抓取效率会掉得很难看。
四、先做“轻防护”:robots.txt、noindex、密码保护,各管各的
这一层不是主防御,但非常有必要。
1)robots.txt:只管“礼貌爬虫”
它适合告诉正常爬虫:
- 后台别抓
- 搜索结果页别抓
- 测试目录别抓
- 参数页别抓
比如:
Disallow: /admin/
Disallow: /search
Disallow: /wp-admin/
Disallow: /tmp/
Disallow: /*?replytocom=
Disallow: /*?sort=
但我要再强调一次:
这不是防恶意爬虫的核心手段。 Google 官方明确说明,robots.txt 不是安全机制。
2)noindex:防止页面被收录
如果是搜索页、筛选页、临时页、重复页,不想进搜索结果,就用:
或者在响应头里下发。Google 官方支持这两种方式。
3)密码保护:真正不该公开的内容,直接上鉴权
如果是后台、内部文件、测试环境、导出目录、备份目录,别想着靠 robots。
Google 官方建议很明确:真正敏感内容该密码保护。
五、真正好用的核心:Nginx 限速 + 限连接
这一层是我处理恶意爬虫最常用、最稳的办法。
先给全站做基础限速
http {
limit_req_zone $binary_remote_addr zone=perip_req:20m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=perip_conn:20m;
server {
listen 80;
server_name example.com;
limit_req_status 429;
limit_conn_status 429;
location / {
limit_req zone=perip_req burst=20 nodelay;
limit_conn perip_conn 20;
try_files $uri $uri/ /index.php?$args;
}
}
}
这套思路的意思很简单:
- 一个 IP 正常看网页,可以看
- 但如果它一秒几十次、几百次连续打,就会被限
- 并发连接也不能无限开
Nginx 官方文档里对这两个模块的定义很清晰:limit_req 限的是请求处理速率,limit_conn 限的是连接数。
再对高风险路径做更严的限制
比如:
/search/wp-login.php/xmlrpc.php/api//cart/checkout- 带筛选参数的列表页
示例:
http {
limit_req_zone $binary_remote_addr zone=search_zone:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=login_zone:10m rate=1r/s;
server {
location /search {
limit_req zone=search_zone burst=5 nodelay;
include fastcgi_params;
}
location = /wp-login.php {
limit_req zone=login_zone burst=3 nodelay;
include fastcgi_params;
}
location = /xmlrpc.php {
deny all;
}
}
}
这里有个经验值很重要:
全站不要一上来限得太死,重点路径要限得更狠。
因为恶意爬虫最喜欢钻的,不是首页,而是:
- 搜索入口
- 动态筛选页
- 登录页
- 评论接口
- XML-RPC
- 各种带参数的 URL
六、只拦 IP 不够,还要把“源站直连”堵死
很多香港服务器明明已经套了 CDN / WAF,但还是被抓得很惨。
一查发现,问题不是规则没开,而是源站 IP 暴露了。
也就是说:
- 前面访问域名走了 CDN
- 但别人拿到你真实源站 IP 后
- 直接跳过 CDN
- 继续打你源站
这时候你前面的很多限速、挑战、机器人识别,相当于白做。
Cloudflare 官方明确建议:如果你的域名启用了代理,源站就应该允许 Cloudflare IP,并阻断其他直连来源,否则会存在绕过代理直接访问源站的问题。
这一层我建议你这么做:
1)域名接入 CDN / WAF
让大部分请求先到前端代理层。
2)源站防火墙只放行 CDN 回源 IP
这样别人就算知道源站 IP,也很难直接打进去。
3)对未知机器人做 challenge
Cloudflare 现在有 Bot Fight Mode,这类功能就是专门拿来对付自动化流量的,小站点也能先用起来。官方文档里也明确写了,它是一个用于识别并缓解机器人流量的简单免费方案。
4)给正常搜索引擎机器人留白名单
Cloudflare 也支持 verified bots / known bots 相关能力,别把真 Googlebot、Bingbot 一起拦掉。
七、日志联动封禁,才是把坏爬虫“打疼”的关键
如果只是限速,它会慢一点。
如果加上日志联动封禁,它才会真正难受。
我现场一般会这么做:
触发条件
满足任意一种,就进入封禁队列:
- 60 秒内访问超过设定阈值
- 连续刷
/search - 连续扫不存在路径,404 太多
- 频繁访问后台口
- 高频请求带明显脚本特征 UA
- 请求节奏极不自然
封禁时间
别一上来永久封。
可以这样分层:
- 第一次:封 10 分钟
- 第二次:封 1 小时
- 第三次:封 24 小时
- 重复违规:拉黑更久
工具
这一层可以用日志联动工具处理,也可以在 nftables 层做兜底。
nftables 官方文档说明,limit 使用的是 token bucket filter 机制,可以做按速率匹配;如果速率超限,再配合 drop 规则即可。
如果你习惯用 Fail2Ban,这类工具也适合监控 Nginx 日志后自动封禁可疑 IP;Fail2Ban 官方仓库里甚至有针对 nginx-limit-req 的过滤配置示例。
八、别只顾着封,还要顺手把站点“变得不值得抓”
这一点特别实用。
恶意爬虫之所以抓得欢,往往是因为你的站点太容易抓,而且每抓一次都能把源站拖进去算一遍。
所以除了拦截,我还会顺手做 6 个优化:
1)给静态资源加缓存
图片、CSS、JS、字体文件,尽量走 CDN 缓存。
不要让这些资源频繁回源。
2)给动态页做缓存
例如:
- WordPress + Redis Object Cache
- Nginx FastCGI Cache
- 商品详情页缓存
- 列表页缓存
3)禁止无意义参数制造无限 URL
比如:
?sort=?replytocom=?utm_xxx=- 重复筛选参数
- 随机拼接 query string
不然爬虫会帮你“生成”无限页面。
4)关闭没用的入口
比如:
xmlrpc.php- 不用的 API
- 测试目录
- 备份目录
- 历史后台路径
5)把搜索页做限制
站内搜索是最容易被滥刷的。
建议:
- 未登录用户限频
- 对超长关键词直接拒绝
- 对连续搜索做 challenge
- 搜索结果页 noindex
6)分页和筛选页不要无限放开
电商站和博客站经常死在这里。
一个筛选页 5 个参数互相组合,爬虫一跑,就是海量动态 URL。
九、一个比较稳的落地方案,我会这样配
如果让我给“香港服务器被恶意爬虫抓得厉害”的客户做一套实战方案,我一般会按下面来:
适合中小型官网 / WordPress / 外贸站
推荐配置:
- AMD EPYC 4585PX(16核32线程)
- 64GB DDR5-5600
- 960GB NVMe SSD
- 100M BGP + 25M CN2 优化
- Ubuntu 22.04
- Nginx + PHP-FPM + Redis
- 前置 CDN / WAF
落地步骤
第 1 天:先止血
- 开 CDN 代理
- 关闭源站直连
- 对
/search、/wp-login.php、/xmlrpc.php做严格限速 - 开基础 IP 限频
- 查日志,抓前 20 个恶意来源
第 2 天:开始清理结构
- robots.txt 调整
- 搜索页、筛选页加 noindex
- 关掉无用目录
- 加缓存
- 去掉无意义参数页
第 3 天:做自动化
- 日志联动封禁
- 高风险 URI 自动黑名单
- 周期检查异常 IP / UA / 404 比例
- 观察 CDN 命中率和源站 CPU 曲线
这样做完后,很多站点的体感变化会很明显:
- 源站 QPS 降下来
- PHP-FPM 更稳
- MySQL 慢查询减少
- 带宽更平滑
- 页面打开速度恢复
- 抓取异常明显下降
十、别把“防恶意爬虫”理解成只封几个 UA
很多人会在 Nginx 里写一堆 python、curl、scrapy、aiohttp、Go-http-client 的 UA 黑名单,然后觉得自己防住了。
这种方法有用,但只够算最表层。
因为真正麻烦的爬虫,往往会:
- 伪装成正常浏览器
- 轮换 UA
- 轮换 IP
- 控制速率
- 走代理池
- 专打动态页和高成本接口
所以更有效的思路永远是:
识别正常机器人 → 限速 → 限连接 → challenge → 日志联动封禁 → 源站隐藏 → 页面缓存和结构优化
这一套下来,才是真正能落地、能长期稳定跑的方案。
如果你的香港服务器已经被恶意爬虫频繁抓取,不要只盯着 robots.txt,也不要只会封几个 IP。
正确做法是把问题拆开:
- robots.txt / noindex 负责告诉正常爬虫怎么抓
- Nginx limit_req / limit_conn 负责限速限并发
- CDN / WAF / Bot 防护 负责把坏流量挡在源站前面,并识别 verified bots
- 源站只放行代理回源 IP,避免被绕过防护直打源站
- 日志联动封禁 + 缓存优化,负责长期稳定运行
对于大多数中型站点来说,一台 AMD EPYC 4585PX + 64GB DDR5 + NVMe SSD + 100M BGP / 25M CN2 这类香港服务器,再配上上面这套思路,已经能把大多数恶意抓取问题压下去。