今日站点异常流量的分析
人家说,三天不打上房揭瓦,今天倒好,三天不更,就开始有什么东西来揭瓦了。
真希望他们能明白,『短暂停更一段时间』的意思是笔者暂时不更新,去打游戏了,不代表我不看站点的运行情况,也不代表我不会分析流量,以及写报告。
我们在大量的异常访问中发现了少量正常读者1. 前言
上一次写类似内容,应该是去年的11月份。那一次是HTTP GET Flood,带有比较明显的攻击倾向,甚至站点也停止运行了,因此很容易就被看出来,并实施针对性修复。今天站点碰到的问题,情况更为隐秘,也很难定性。我不好说这是否是某种攻击,或是某个镜像站在低速采集,所以也基本上暂时没办法进行进一步的反制措施。因此把他记录下来,供各位大牛观赏,分析。
从早上七点开始,站点就进来一批显著不正常的访问请求,推高了Umami统计的PV(浏览页面数)和UV(浏览用户数),一直持续到下午六点钟(不确定是否已停止,可能仍在继续)。其特点是:
- PV/UV比极低,几乎每个访客只看一个页面
- Referer为空
- 访问目标大多是平时没人看的冷门页面,比如深层作者分页、深层列表页
- 路径比较奇怪
- IP来源集中在中国大陆、香港、新加坡、美国
这些请求当然没有影响到站点正常运行(因为其请求速度还是比较低的),然而最直接的影响就是导致统计数据失真(今天的统计数据就比昨天翻了两三倍),另外还可能引入其他问题(下文会提),因此有必要取证分析下。
以下内容部分为 DeepSeek-V4-Flash数据分析,并使用ChatGPT免费版做简单表述修正。部分内容懒得手打,直接从复盘报告里面复制出来的,所以今天的博文有不少的AI辅助创作的成分。不过笔者都有核对数据,因此请放心阅读。
2. 数据获取与分析
数据获取方面,Nginx access日志有现成的分析器,直接对近段时间的记录做一次增量转换即可。另外,还需要准备Umami的记录,由于自托管版本Umami不支持数据导出,这里选择直接从容器内的PgSQL导出一份sql文件,供Agent参考。
分析方面,基本上就和普通的流程差不多,先写一份spec.md,然后让OpenCode里的dsv4f去读取,并按提示操作。
spec.md节选整个分析过程持续了几个对话,主要是换其他LLM(主要是ChatGPT)重新构建详细的分析维度,并补充站点的一些信息(比如,笔者有几个IP是作为固定的出口IP的,这部分应该bypass掉),让分析更为准确。最后分析完,让他一方面输出为md格式供其他LLM去做核查,另一方面转为HTML,供笔者来分析。
2.1 攻击类型
说白了,就是有程序在不停地请求站点上的冷门页面,而且似乎还有重复请求的情况。具体来说可以细分为两种:一个可能是分布式的worker pool + 代理IP池 + 共享(伪造)UA池,且访问程序可以执行js(因为正确触发了Umami统计,以及笔者自己写的API统计接口),不排除无头浏览器的可能性;另一个可能是纯URL枚举型,是否存在js执行能力还不好说,更像是搜索页面上能找到的所有URL,然后发送访问请求。
总体来看,异常流量更像是自动化流量,按照报告的说法,非真人、非平台互访、但至于是不是真的『非攻击』,就有待商榷,主要是因为怎么定义『攻击』。v4f不认为这是攻击,因为并没有对站点有明显的破坏行为(和上次的GET Flood很明显不同),但笔者对攻击的定义会广一些,如果说对面是某种采集站,用全站爬虫爬走文章然后去盗版发布,我会把它归类为攻击。因此这里更准确的说法是,未影响站点本体运行。
2.2 异常IP
从中分析出来的异常IP大约有906个,来源相对来说比较整齐,主要是云服务IP以及运营商IP
- 腾讯云 43.x/81.70/113.44/82.156/170.106
- 华为云 116.204/121.37
- 移动 36.x/171.x
- 电信 180.153/1.92
- 剩下的是海外,SG/US/HK,这部分没有详细报告
云服务部分,考虑到早年间有不少教程讲到过『如何搭建代理IP给手游工作室使用』,就是让你去国内云厂商那里买机器,然后再买几个弹性IP,实现单机器多出口,再搭建CCProxy之类的服务,所以不排除还有人搭建这种代理IP的可能性。当然还有可能就是,这些机器也是被黑的,成了人家的扫描器而不自知,这就不得而知了。
运营商部分,无法确定是在运营商机房跑的请求,还是说是家宽代理(内地的家宽代理市场其实也不相上下,也有不少是黑代理),不过报告里面有一个很有意思的现象,IP严格单页,比如说,62个移动(36.x)IP 全部只访问1个页面,298个腾讯云(43.x)中有96.3%只访问1页。如果光这么看的话,其实确实有些符合之前分析代理IP时,对其中一种用途,爬虫代理,的状况,他们有时候甚至会用上轮换代理IP,让每次请求都使用不同的IP,自然会产生单页访问的情况。
2.3 User-Agent
疑点最大的其实就在于UA。懂得HTTP原理的朋友都知道,虽然UA可以判断用户类型,但也不是不能伪造的,伪造之后可以规避一些访问限制,比如原来的UA的curl,这种一下子就能拦下来,伪造为Chrome的就不容易拦了。然而问题在于,伪造得不好,反而会露马脚。
流量里面出现次数最多的是iOS的UA,共350个,然而这其中有213个(60.9%)有显著的伪造痕迹,主要是出现了iPhone OS 10_3_1 + Safari 26.5这种离谱的搭配。虽然自Safari 26起,UA不再报告当前系统版本,而是冻结为旧版本,但显然,iOS 10.3.1 并不是启用了冻结的版本,因此上面几乎不可能有真实设备发出这种流量,极大概率就是在伪造UA。
另外,有59种(不同的字符串视为不同种)UA 被大于等于2个IP共享,涉及794个IP(87.6%),典型如50个IP共享『iPhone OS 11_0 + Safari 26.5』这种明显有问题的组合。结合这个特征来看,基本上更确定了是自动化浏览器在做UA Spoofing。
2.4 访问深度
正常情况下,站内的流量有很明显的三种趋势:比如说我今天更了,就有从博客聚合站来的朋友阅读最新文章,此外就是有从搜索引擎来的朋友在访问热门文章(比如站内讲对讲机频率的,还有一种就是前几天说的『深潜流量』,表现为在站内连续跳转阅读,有一定深度。
也就是说,正常访问流量一般都不会具有太大的深度,即使偶然有,也是少量的,有稳定阅读轨迹的。然而这次的异常流量,却出现了不正常的高深度流量。这里的深度指的是老页面,或需要一定跳转的,比如十几页开外的分页,十几页开外的作者页。而且并非偶然,类似这样的深层页面(评论页+分页+作者页+分类页)请求合计 410 次,占总流量的45.3%,因此可以怀疑是在全站结构遍历。
定量来看,比如说首页分页,看第二页的有22个,第三第四页的有7个,大概就是正常访客的水平,翻几页就走了。然而,看第十页及以后的有36个,甚至还有看作者页的第15页的(我自己都快忘了Typecho是多用户博客程序,可以看作者页),这很显然不对劲。
2.5 冷门URL
如引言中的图片说是,很多访问都似乎是在访问冷门URL,例如文章后带comment的(直接跳转评论区),带respon的(回复),甚至还排查出来带?replyTo=的。最后一个是最狠的,因为replyTo只出现在一个地方:
<a
href="..comment-page-1?replyTo=<comment_id>#respond-post-<id>"
rel="nofollow"
onclick="return TypechoComment.reply(...);">
回复
</a>懂得HTML和js的朋友都知道,只要TypechoComment.reply返回false,就不会触发浏览器跳转到href指向的链接。现在出现了这样的请求,要么就是对方没有好好执行js,要么就是单纯地扫描链接,有什么访问什么。
2.6 请求频次
从时间上来看,对方倒也文明,保持恒定低速率请求,相邻异常请求间隔中位数45s、P25=12s、P75=97s、P90=162s(n=905)。突发请求方面,0–3 秒间隔的,出现 129 次(14.3%);同一秒内大于等于3 IP请求的有9个时刻,最大同秒17个IP,总体来看还能接受。
然而另一方面,报告里也指出,存在『不同IP在几秒内分别访问不同冷门URL』和『同一URL由多个IP在 0–9 秒内连续访问,随后长时间静默』的情况,怀疑是批量任务分发(每个 worker 领取一个 URL)的模式。
3. 对方的目的?
不是明显的攻击,那这是在这干啥呢?
根据报告的说法,这玩意有概率是自动化采集程序,以约 1–2 IP/分钟的速率持续遍历,一直到下午六点,符合全站遍历内容采集/镜像的行为。至于是不是真的这样,那就只有天知道了。
4. 写在最后
先排查到这里吧。因为目前没有更多的证据了,而且攻击也已经停止,只能说明天再看,是否还会继续出现这样的情况。
主要是数据看着很闹心,而且也怕真的就是内容采集站,一声不吭拿去用的,而且最后还影响自己的SEO。就,转载可以,署个名呗大哥,直接照抄当自己的就有些不厚道了。
(完)