上一篇 下一篇 分享链接 返回 返回顶部

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

发布人:Minchunlin 发布时间:2026-04-20 09:21 阅读量:328


前阵子我在看一台香港站点服务器的访问日志时,发现一个很典型的问题:页面没上热搜,广告也没猛投,但 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 种特征:

  1. 同一 IP / 同一网段频繁请求
  2. 大量请求集中在搜索页、筛选页、分页页、接口页
  3. 大量 404 / 403 / 301 / 302
  4. UA 很假,或者 UA 很随机
  5. 请求节奏不像人,像程序批量跑

如果你一上来就全站封,很容易把正常搜索引擎也一起误伤。
尤其是外贸站、博客站,误伤真爬虫之后,收录和抓取效率会掉得很难看。

四、先做“轻防护”:robots.txt、noindex、密码保护,各管各的

这一层不是主防御,但非常有必要。

1)robots.txt:只管“礼貌爬虫”

它适合告诉正常爬虫:

  • 后台别抓
  • 搜索结果页别抓
  • 测试目录别抓
  • 参数页别抓

比如:

User-agent: *
Disallow: /admin/
Disallow: /search
Disallow: /wp-admin/
Disallow: /tmp/
Disallow: /*?replytocom=
Disallow: /*?sort=

但我要再强调一次:
这不是防恶意爬虫的核心手段。 Google 官方明确说明,robots.txt 不是安全机制。

2)noindex:防止页面被收录

如果是搜索页、筛选页、临时页、重复页,不想进搜索结果,就用:

<meta name="robots" content="noindex, nofollow">
 

或者在响应头里下发。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 里写一堆 pythoncurlscrapyaiohttpGo-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 这类香港服务器,再配上上面这套思路,已经能把大多数恶意抓取问题压下去。

目录结构
全文