一看吓一跳的网站响应日志

发布于 2025-11-07  91 次阅读


今天想到已经有好一段时间没去审计万事屋的网站响应日志了,就连上服务器,把日志拉取到本地,稍微翻一翻。

虽然早就做好在日志中看到一堆爬虫的心理准备,但是,为什么有那——么多啊……

除了爬虫,还有各种疑似脚本的访问记录一直在尝试爆破登录页面和XML-RPC页面。

是时候该处理一下了。那就一边吐槽,一边加固下网站的安全策略吧。

1.拦截爬虫

上次看的时候也不过就是各种搜索引擎爬虫偶尔爬一下,这次看爬虫的UA真的五花八门。而且相当一部分都在以爬虫之名,行DDoS之实。

对付爬虫,以及各种扫描器,可以考虑通过拒绝相关UA访问的方式,让它们没法抓取或者扫描网站数据。

一般来说,各种爬虫都会通过它的UA来标识其身份,例如爬虫UA包含GPTBot字符串,就表示这是来自OpenAI的爬虫,专门爬取网站数据训练GPT模型的。

GPTBot爬虫最近的完整UA信息如下:

Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.3; +https://openai.com/gptbot)

更早之前的日志中还看到1.0版本的,不过版本号意义不大。如果想要拦截这个爬虫,可以通过匹配UA关键字的方式拒绝掉其所有连接请求。

1.1.拒绝爬虫UA连接

虽然有robots.txt文件来告知爬虫抓取网站数据时的行为规范,但是它本质上只是个君子协定。如果爬虫不遵守,那就只能上拦截规则了。

对于Nginx来说,可以在配置文件里面添加以下规则匹配想拦截的爬虫UA关键字并将相关连接请求拒绝掉。多个UA关键字之间通过管道符分割。

if ($http_user_agent ~* "unwelcomeUA01|unwelcomeUA02"){
  return 444;
}

1.2.拒绝空UA连接

如果连接请求中的UA完全是空的,那么很有可能不是正常的访问。同样地拒绝掉就行。

Nginx的配置方式如下。

if ($http_user_agent ~ ^$ ) {
  return 444;
}

2.拦截网段

日志中有部分连接请求的UA信息看着像是正常浏览器,可是从同一个IP同时请求好多个页面来看,实在难以排除它是爬虫的可能性。这种就只能封IP了。

封禁单个IP意义确实不大,所以可以直接把整个段都封掉。对于一些IDC的网段,全部封禁也基本不会造成误伤。

2.1.通过ASN拦截

最近的日志中,很多的攻击脚本都来自DigitalOcean的IP,AS号是14061。

我觉得基本不会有访客通过这些IDC的IP来访问万事屋,所以直接把这个AS号内的所有网段全部拦截掉。

现成的ASN拦截策略可以在https://asn.ipinfo.app上直接获取。对于Nginx来说,可以通过路飞工具箱里面的脚本(https://blog.lufei.de/p/350/)快速维护。

因为路飞大佬的博客中写的很全,所以建议直接看大佬的介绍。基于Nginx规则的脚本2用的是宝塔面板环境下的Nginx路径,如果是用源装的Nginx,需要改一下脚本里的路径。

2.2.通过所属地区拦截

还是翻日志看到的,最近某个国家的IP没几个是正常访问的。所以就想根据所属国家或地区来拦截掉那一部分的IP段。

各个国家或地区的IP段可以在https://www.ipdeny.com/ipblocks/上获取。为了方便维护,也依葫芦画瓢摸了个脚本。

如果是宝塔面板环境,可以将脚本里的nconf变量值改为/www/server/nginx/confnbin变量值改为/usr/bin/nginx

#!/bin/bash
origfold=$PWD
baseurl="https://www.ipdeny.com/ipblocks/data/aggregated/"

nconf="/etc/nginx/conf.d"
nbin="/usr/sbin/nginx"

regionlist="sg
ro"

if [ "$1" == "--delall" ]; then
    for i in $regionlist;
    do
        echo "" >$nconf/regionblock_$i.conf
        echo "$(date +%Y-%m-%d\ %H:%M:%S) Region $1 has been unbanned!"
    done
elif [ "$1" == "-d" ]; then
    echo "" >$nconf/regionblock_$2.conf
    $nbin -s reload
    echo "$(date +%Y-%m-%d\ %H:%M:%S) Region $2 has been unbanned!"
elif [ "$1" == "-a" ]; then
    curl -s $baseurl$2-aggregated.zone | \
    awk '{print "deny " $1 ";"}' > $nconf/regionblock_$2.conf
        echo "$(date +%Y-%m-%d\ %H:%M:%S) $nconf/regionblock_$2.conf downloaded."
        echo "$(date +%Y-%m-%d\ %H:%M:%S) Region $2 has been banned!"
    $nbin -s reload
else
    rm -rf $nconf/regionblock*.conf
    echo "$(date +%Y-%m-%d\ %H:%M:%S) All legacy configuration files have been cleared!"
    for i in $regionlist;
    do
        curl -s $baseurl$i-aggregated.zone | \
        awk '{print "deny " $1 ";"}' > $nconf/regionblock_$i.conf
        echo "$(date +%Y-%m-%d\ %H:%M:%S) $nconf/regionblock_$i.conf downloaded."
        echo "$(date +%Y-%m-%d\ %H:%M:%S) Region $i has been banned!"
    done
fi

$nbin -s reload
cd $origfold
exit 0

3.隐藏WordPress登录页面

稍微处理了下爬虫后,接下来尝试解决一下登录页面爆破的问题。

一开始想到的办法是用WPS Hide Login插件把登录地址改掉,后面突发奇想用了其他的方式,决定先看看效果,再考虑通过插件来实现。

4.个人吐槽

一番调整后,看着被444掉的爬虫和脚本,还是稍微有点成就感的(笑)。

网站被爬取、爆破这种事情,不上称没四两重,上称了怕是要把称给压垮。

因为键盘敲困了,今天就先简单处理一下,回头再研究点效果更好的方法应用上。