蜘蛛IP段识别访问策略:为什么你的日志里全是“假蜘蛛”?

你打开服务器日志,看到一堆百度、谷歌的爬虫IP,心里踏实了——流量不错,收录应该没问题。结果一查索引量,掉了。再一看,这些“蜘蛛”访问的页面全是后台登录、API接口、甚至wp-admin。真正的搜索引擎蜘蛛,不会干这种事。你被“假蜘蛛”耍了。更麻烦的是,这些伪装成蜘蛛的爬虫,要么在采集你的内容,要么在试探你的漏洞。今天,我直接告诉你:怎么从IP段层面,把真蜘蛛和假蜘蛛一刀切开。

为什么光靠User-Agent拦不住假蜘蛛?

很多站长觉得,只要在Nginx或Apache里限制User-Agent为“Baiduspider”或“Googlebot”就行。我当初也这么干过,结果一个月后,服务器CPU飙到100%。查日志才发现,一个IP段疯狂请求,User-Agent写得一模一样:“Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)”。你看着像真家伙,但那个IP段根本不是百度官方的。

真蜘蛛的User-Agent可以伪造,但IP段不行。百度、谷歌、必应,这些搜索引擎都会公开自己的爬虫IP段。比如百度在官网有完整列表,谷歌也提供了DNS反查机制。假蜘蛛不会用这些IP段,因为它们拿不到。所以,你的第一道防线不是检查User-Agent,而是验证源IP。

举个真实例子:我一个朋友的博客,每天被“谷歌蜘蛛”访问几百次。他查了IP,发现来自某个欧洲机房。用谷歌的官方工具反查,那个IP根本没有PTR记录。他直接封了那个段,服务器负载立刻降了70%。从那以后,他所有蜘蛛验证都先走IP段白名单。

如何拿到官方蜘蛛IP段?3个最快来源

别自己去网上搜“百度蜘蛛IP段大全”,那些列表八成是过期的。官方有持续更新的来源,我给你三个最靠谱的。

第一,百度蜘蛛IP段。百度在“百度站长平台”里有一个“爬虫IP列表”页面,定期更新。你登录后就能看到所有段的CIDR。比如现在的百度蜘蛛主要来自220.181.0.0/1661.135.0.0/16这些段。注意,百度偶尔会调整,所以你得每个月拉一次最新数据。

第二,谷歌蜘蛛IP段。谷歌更简单,它提供的是DNS反查机制。你拿到一个IP,直接用host命令反查,如果结果里包含“googlebot”或“google.com”,就是真蜘蛛。比如,你看到IP是66.249.66.1,跑一下host 66.249.66.1,返回是crawl-66-249-66-1.googlebot.com,那就对了。如果反查失败或返回别的域名,直接丢进黑名单。

第三,必应和Yandex。必应蜘蛛的IP段主要在40.77.0.0/1652.167.0.0/16这些段,Yandex则是77.88.0.0/16。这些数据在各自官方帮助中心有PDF文档,下载下来存好。

你把这些段整理成一个白名单文件,比如spider_ips.txt,每行一个CIDR。然后在服务器层面,只允许这些IP段访问你的robots.txt和sitemap。其他IP想假装蜘蛛?门都没有。

配置服务器:用IP段白名单卡死假蜘蛛

拿到官方IP段后,你要在服务器层面做两件事:一是白名单放行真蜘蛛,二是黑名单封掉所有伪造IP。

在Nginx里,你可以在server块或location块里写条件判断。比如,你想让真蜘蛛正常访问,但假蜘蛛直接返回403:

location / {
    # 先定义白名单变量
    set $spider_ip 0;
    if ($remote_addr ~* "^(220\.181\.|61\.135\.|66\.249\.|40\.77\.)") {
        set $spider_ip 1;
    }
    # 如果User-Agent像蜘蛛但IP不在白名单,拒绝
    if ($http_user_agent ~* "baiduspider|googlebot|bingbot") {
        set $spider_ip "${spider_ip}2";
    }
    if ($spider_ip = "02") {
        return 403;
    }
    # 正常处理请求
}

注意:这个例子只是演示逻辑,真实生产环境你要用geo模块或者map指令来优化性能。if在Nginx里有很多坑,别滥用。

Apache的话,用mod_rewrite<If>指令。更简单的方法是,用防火墙工具如iptablesufw,直接拉一个白名单规则:

iptables -A INPUT -s 220.181.0.0/16 -j ACCEPT
iptables -A INPUT -s 61.135.0.0/16 -j ACCEPT
# 其他蜘蛛段...
iptables -A INPUT -p tcp --dport 80 -m string --string "Baiduspider" --algo bm -j DROP

最后一行是:如果User-Agent包含“Baiduspider”但来源IP不在白名单,直接丢弃包。这个策略对假蜘蛛来说,就是降维打击。

日志分析:怎么揪出那些“伪装成蜘蛛”的坏蛋?

光配置了防火墙还不够,你还要定期翻日志。假蜘蛛不会只伪装一次,它们会换IP、换User-Agent继续攻击。

打开你的访问日志,比如Nginx的access.log,用grepawk筛出所有User-Agent包含“Baiduspider”或“Googlebot”的行。然后提取IP,去重,再和你手里的白名单比对。

举个例子,你看到IP是192.168.1.1,User-Agent写着“Googlebot”,但这个IP是内网地址。显然,这是假的。或者IP来自某个云服务商,比如阿里云、AWS,这些云IP段根本不在搜索引擎的官方列表里。你直接封掉这个IP段。

更狠一点,你可以写个脚本,每天跑一次。脚本逻辑:从日志里提取所有自称蜘蛛的IP,然后对每个IP做DNS反查。如果反查结果不包含“googlebot.com”或“baidu.com”,就自动加到防火墙黑名单。我见过一个团队用这个方案,一周内封掉了300多个假蜘蛛IP,服务器带宽节省了40%。

动态IP段更新:别让你的白名单变成废纸

搜索引擎的IP段不是一成不变的。百度偶尔会扩充段,谷歌也会调整。如果你三个月不更新白名单,就可能把真蜘蛛挡在门外,或者让新冒出来的假蜘蛛漏进来。

怎么更新?手动去官方页面拉数据太累。你可以写一个cron任务,每周一凌晨从百度站长平台(需要登录,但可以模拟请求)和谷歌官方列表(公开URL)下载最新的IP段。然后自动合并到你的防火墙规则中。

比如,谷歌的IP段公开在https://developers.google.com/search/docs/crawling/verifying-googlebot,你直接curl下来,解析成CIDR格式。百度那边,如果你有站长平台登录态,可以爬取。如果没有,至少每个月手动更新一次。

我认识一个做SEO的朋友,他写了个脚本,每天凌晨3点跑一次。脚本先curl官方列表,比对本地文件,如果有变化,就重启Nginx重新加载规则。他用了两年,从来没被假蜘蛛搞崩过。

常见陷阱:别被“反向代理”和CDN的IP骗了

你可能会遇到一种情况:你的网站用了Cloudflare或阿里云CDN,所有访问者的真实IP都被隐藏了,日志里只显示CDN节点的IP。这时候,你的IP段白名单就失效了,因为真蜘蛛的IP变成了CDN的IP。

怎么办?两个方法。第一,在服务器配置里,从X-Forwarded-For头中提取真实IP。Nginx里,你可以用set_real_ip_from指令告诉Nginx,信任CDN节点,然后从X-Forwarded-For里取最后一跳的IP。比如:

set_real_ip_from 103.21.244.0/22; # Cloudflare节点段
real_ip_header X-Forwarded-For;

然后,你在if条件里用$realip_remote_addr代替$remote_addr,就能拿到真实IP了。

第二,对于CDN场景,你还可以利用CDN本身的安全规则。比如Cloudflare的“Bot Fight Mode”,它会自动识别并拦截假蜘蛛。但别完全依赖它,因为它也有误判。你最好在CDN层面也加上IP段白名单。

一个真实教训:我之前一个客户,用了阿里云CDN,日志里所有蜘蛛IP都是阿里云节点。他按节点IP做了白名单,结果真蜘蛛被放行,假蜘蛛也混进来了。后来他加上X-Forwarded-For解析,把真蜘蛛IP段重新过滤,才解决问题。

结尾:今天就能做的1个操作

别等日志爆炸了再行动。现在,打开你的服务器,做三件事:

  1. 去百度站长平台和谷歌官方列表,下载最新蜘蛛IP段。
  2. 在你的Nginx或防火墙里,写一条规则:只允许这些IP段访问robots.txtsitemap.xml,其他IP访问这两个文件直接返回403。
  3. 跑一条命令,检查过去24小时日志里,自称蜘蛛但IP不在白名单的IP有多少。如果超过10个,立刻封掉它们对应的段。

这个操作,只需要10分钟,但能让你下周的服务器负载和日志量明显下降。别拖了,现在就去。