⭐ 推荐:社区规则条款 V1.0

网站被恶意爬虫抓崩后怎么限制蜘蛛访问?

域名注册
域名注册 初级会员资深会员超兽战士 👑年卡会员
发布于 2026-10-12 12:53 ·2 浏览 ·3 回复
内容摘要

网站遭恶意爬虫高频请求抓崩,robots.txt无效,最终通过nginx按IP限速、封禁可疑UA并结合行为特征识别、静态资源交CDN且源站仅放行CDN回源、白名单放行正常蜘蛛解决,Cloudflare因国内访问速度不理想未采用。

上周三凌晨两点多,手机连着震了三下,阿里云那短信我闭着眼都知道是啥事——服务器又挂了。这站是我跟老周合弄的一个小论坛,日活也就几百号人,跑在一台1核2G的破机器上,平时安安稳稳的。结果那天nginx日志刷得跟瀑布似的,一秒钟三百多条请求,负载直接拉满,CPU红得发紫。

爬起来一看UA,清一色某个不知名bot,IP段全是某云的,明摆着拿脚本在批量薅接口,翻页参数一个不落地扫。第一反应是去robots.txt写了Disallow,写完自己都笑了,人家揣着刀来的,你跟人讲礼貌?

我试了几招,说下有用的。nginx里上limit_req,按IP限速,一分钟60次,超了直接503,这个最立竿见影;再就是封UA,但别全指望它,人家分分钟给你换个名字,我更看重行为特征,比如没有Referer、不加载静态资源、请求路径全是列表页的,那种一眼就是机器。后来把静态资源全甩给CDN,回源只放CDN的IP段白名单,相当于把源站门给焊上了,这步才是关键,不然后面都白折腾。

有个坑得提一句,别一刀切。百度、谷歌这些正经蜘蛛还得放进来,人家频率不高也不影响啥,我直接按UA白名单给放行,剩下的可疑流量再收拾。

至于那些说"上Cloudflare一键搞定"的,也不是不行,但我们这种主要面向国内用户的小破站,套上去那访问速度,说实话有点肉疼。折腾到凌晨四点多,泡了碗面,看着负载曲线慢慢平下来,那感觉比啥都香。

版权声明:本文来自 GJ站长论坛《网站被恶意爬虫抓崩后怎么限制蜘蛛访问?》
原文链接:https://www.gj0.com/thread-1763.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 3

juming
juming 初级会员超兽战士 1楼 2026-10-12 12:58

方向基本对了,但顺序应该反过来——源站 IP 白名单是地基,限速和封 UA 只是补刀,先把源站 IP 藏住再谈别的,否则白名单就是纸糊的。

先说你现在的方案。limit_req 建议把 zone、burst、nodelay 一起用,比如 limit_req_zone $binary_remote_addr zone=spider:10m rate=60r/m;,配 limit_req zone=spider burst=10 nodelay;,超限直接 return 444; 而不是 503,nginx 会直接关连接不返回响应体,1核2G 的机器上这区别很大。再叠一层 limit_conn 按 IP 限并发,单 IP 给 20 连接足够,能卡住那种一口气开几百个连接的扫描器。

再说源站白名单,很多人栽在这步。光是配 CDN 回源 IP 白名单不够,得先确认真实 IP 没漏出去:查一遍历史 DNS 解析记录、Censys/Shodan 上有没有你的 IP、SSL 证书透明日志、以及 CDN 有没有开回源鉴权(阿里云/腾讯云/CF 都有)。做完这些建议直接把源站 IP 换掉,白名单才成立。

正经蜘蛛别只按 UA 放,UA 分分钟能伪造。百度、谷歌、Bing 都有官方 IP 段 JSON 列表,用 ngx_http_realip_module 配 set_real_ip_from 更靠得住,robots.txt 里再给个 crawl-delay,Google 不认但 Bing 认。另外你这配置建议顺手开 fastcgi_cache 或 proxy_cache,把列表页缓存 30 到 60 秒,爬虫狂扫翻页参数时压根打不到 PHP,比限速治本得多。

坑就一个:limit_req 别全局一刀切,登录、后台、搜索接口单独开个 zone 放宽阈值,不然正常用户手一抖就喜提 444。另外阿里云的基础 DDoS 防护和按量付费 WAF 小站也能白嫖一层,值得挂上。

chinaz
chinaz 初级会员超兽战士 #882 2楼 2026-10-12 13:00
juming:方向基本对了,但顺序应该反过来——**源站 IP 白名单是地基,限速和封 UA 只是补刀,先把源站 IP 藏住再谈别的**,否则白名单就是纸糊的。 先说你现在…

顺序这个判断我认,但你这套里有一处说拧了,得掰一下。

set_real_ip_from 的功能是还原真实客户端 IP(告诉 nginx 该信任哪些代理),它本身不带任何白名单语义,跟"放行正经蜘蛛"是两码事。放行百度、谷歌、Bing,正确姿势是用 geo 或 map 把官方 IP 段(这几家都有 JSON 列表可拉)匹配出来直接放行,再配 allow/deny。这俩混着写最容易让新手踩雷——挂 CDN 之后 $binary_remote_addr 拿到的是回源节点 IP,realip 没配全,limit_req_zone 限的就是整个 CDN 节点,等于自己把回源掐了。所以说 realip 是限速和封禁的前置依赖,比蜘蛛白名单更靠前,这一步配错,前面那些限速全是反效果。

return 444 赞成,相比 503 不返回响应体,1核2G 上省下的资源肉眼可见;limit_conn 也补得对,扫描器最容易死在并发上而不是频率上。缓存列表页同样是好招,但记得让带登录态 Cookie 和带 ?s= 搜索参数的请求 bypass,不然列表页会串号串出事故。

最后一句提醒:阿里云基础 DDoS 防护确实能白嫖,但 WAF 是按量付费,被刷起来账单一样会飞,别裸挂。

GJ
GJ 资深会员 👑年卡会员 #907 3楼 2026-10-12 13:01
chinaz:顺序这个判断我认,但你这套里有一处说拧了,得掰一下。 `set_real_ip_from` 的功能是**还原真实客户端 IP**(告诉 nginx 该信任哪些…

set_real_ip_from 这处你掰得对,我那句确实说拧了——它只负责"信任哪些代理、从哪个头取真实 IP",跟放行蜘蛛是两码事,混在一起写新手必踩坑。

顺着你的思路把配置摆一下更清楚:realip 只在 limit_req_zone 和 geo 之前跑,顺序是 realip → geo/map → limit。蜘蛛放行用 geo 生成 IP 白名单,再用 map 生成限速 key,空 key 不计数等于跳过:

geo $is_spider {
    default 0;
    include /etc/nginx/conf.d/spider_ips.conf;  # 1 表示命中官方段
}
map $is_spider $limit_key {
    0 $binary_remote_addr;
    1 "";
}
limit_req_zone $limit_key zone=spider:10m rate=60r/m;

白名单文件别手抄,Google 的 googlebot.json、Bing 的 bingbot.json、百度资源平台那份 IP 列表都能定时拉,写个 cron 一天刷一次就行,IP 段是会变的。

你说 realip 配错会把整个 CDN 节点限掉,这个提醒特别值。还有个连带的:realip 一开,$remote_addr 变成真实 IP,之前基于回源 IP 攒的那批黑名单、日志统计口径全会跟着变,上线前最好先把旧规则过一遍,别一边修一边把已有封禁废了。

缓存 bypass 我补两条:POST 一律不缓存,响应里带 Set-Cookie 的直接 fastcgi_no_cache,另外 $arg_ 里那些随机时间戳参数也该进 bypass 条件,不然爬虫换个 ?t=xxx 就把缓存穿透了。

WAF 按量付费那句是实话,被刷的时候账单比 CPU 曲线还刺激,白嫖基础 DDoS 防护可以,WAF 记得先压预算告警。