去年有段时间,我的网站每隔几天就会莫名其妙地变慢。不是那种一直慢,是突然卡一下,然后恢复正常。有时候凌晨三点,有时候下午两点,没什么规律。
查了CPU、查了内存、查了数据库,都没问题。Wordfence安全插件也没报警。我一度以为是服务器商那边的问题,差点发工单去骂客服。
后来一个做运维的朋友跟我说了一句话:”你先去看日志。”
我说日志在哪?他说你不知道?
那天晚上我花了四个小时,才搞明白怎么看日志。而就在那堆看起来像乱码的东西里,我找到了一个IP地址,每隔6小时就会对我的wp-login.php发送大量POST请求——有人在暴力破解我的后台密码,已经持续了快两周了。
这篇文章就是从那晚的经历开始的。我想把”怎么看网站日志”这件事,用最不绕弯子的方式讲清楚。
网站日志是什么?先知道它在哪
网站日志就是服务器自动记录的一本”流水账”。每次有人访问你的网站、每次蜘蛛来抓取、每次有人提交表单——服务器都会记一笔。这笔记录包含:谁(IP)、什么时候(时间)、做了什么(请求类型)、访问了哪个页面(URL)、结果怎么样(状态码)。
日志文件一般在这几个位置:
| 服务器环境 | 日志路径 |
|---|---|
| Nginx(宝塔面板) | /www/wwwlogs/你的域名.log |
| Apache | /var/log/apache2/access.log |
| 宝塔面板(直接看) | 宝塔后台 → 网站 → 设置 → 日志 |
如果你用的是宝塔面板,最简单——直接进后台就能看。如果不是,需要SSH连上服务器,用命令看。
我第一次连SSH的时候,打开日志文件,看到的是这样的东西:
178.128.xxx.xxx - - [15/Mar/2025:03:12:45 +0800] "POST /wp-login.php HTTP/1.1" 200 5234 "-" "Mozilla/5.0"
178.128.xxx.xxx - - [15/Mar/2025:03:12:46 +0800] "POST /wp-login.php HTTP/1.1" 200 5234 "-" "Mozilla/5.0"
178.128.xxx.xxx - - [15/Mar/2025:03:12:47 +0800] "POST /wp-login.php HTTP/1.1" 200 5234 "-" "Mozilla/5.0"
当时我完全看不懂。但等我搞明白每部分是什么意思之后,才发现这三行日志已经在尖叫了——有人在一秒内对登录页面发了三次POST请求,这根本不是正常用户的行为。
一条日志拆开看,每个部分都可能是线索
拿上面那条日志举例,把它拆开:
178.128.xxx.xxx - - [15/Mar/2025:03:12:45 +0800] "POST /wp-login.php HTTP/1.1" 200 5234 "-" "Mozilla/5.0"
| 字段 | 含义 | 这条日志里是什么 |
|---|---|---|
| 第一段 | 访问者IP | 178.128.xxx.xxx(一个境外IP) |
| 时间 | 访问时间 | 凌晨3点12分(正常人谁凌晨三点登录后台?) |
| POST/GET | 请求类型 | POST(在提交数据,不是单纯浏览) |
| 路径 | 访问了哪个页面 | /wp-login.php(登录页面) |
| 状态码 | 请求结果 | 200(成功了) |
| UA | 浏览器标识 | Mozilla/5.0(伪装成普通浏览器) |
单看一条,没什么。但如果你看到同一个IP,在凌晨三点,连续对wp-login.php发POST请求,状态码还是200——这基本可以确定是暴力破解。
我当时翻日志翻到这一段的时候,手都在抖。这个IP已经连续两周,每天凌晨三点准时来,每次发几百个请求,尝试不同的用户名密码组合。而我完全不知道。
日志里最常见的几种攻击痕迹
我把后来翻日志时遇到的几种攻击模式,整理成了一张表。如果你在日志里看到这些特征,大概率是出事了。
| 攻击类型 | 日志特征 | 怎么判断 |
|---|---|---|
| 暴力破解 | 同一IP短时间内大量POST到wp-login.php或xmlrpc.php | 看频率——正常用户不会一秒钟发三次登录请求 |
| SQL注入 | URL里带union select、' OR '1'='1等字符串 | 直接搜这些关键词,有结果就是有人在尝试注入 |
| 扫描漏洞 | 短时间内大量404请求,访问各种不存在的路径 | 比如/wp-admin/setup-config.php、/.env、/phpmyadmin/ |
| Webshell访问 | 访问一些奇怪的PHP文件路径,比如/wp-content/uploads/shell.php | 这些路径不是正常WordPress会有的 |
| 爬虫/采集 | 同一IP短时间内大量GET请求,访问所有文章页面 | 看UA——如果是正常蜘蛛会标明自己是Googlebot或Baiduspider |
暴力破解是最常见的。 我之前那个站,日志里80%的异常请求都是暴力破解。攻击者会用一些常见的用户名密码组合(admin/123456、admin/admin、test/test)来试,试成功了就进来了。
这里有个很多人不知道的点:如果攻击者尝试登录,但密码不对,状态码也是200,不是401。 WordPress的登录页面,不管登录成功还是失败,返回的状态码都是200。所以你不能只看状态码,要结合频率和IP来判断。
其实就是一句话:正常人的访问行为是有节奏的,攻击者的行为是机器式的。 一旦你在日志里看到那种机械重复的模式,十有八九不正常。
怎么用命令快速翻日志(不用一条条看)
日志文件动不动就几百MB,一条条看是不可能看完的。我用几个命令就能快速定位问题。
看最近500条日志:
tail -n 500 /www/wwwlogs/你的域名.log
看某个IP的所有访问记录:
grep "178.128.xxx.xxx" /www/wwwlogs/你的域名.log
统计访问最多的IP(找出可疑IP):
awk '{print $1}' /www/wwwlogs/你的域名.log | sort | uniq -c | sort -rn | head -20
搜有没有人在尝试SQL注入:
grep -i "union select\|' or '1'='1\|drop table" /www/wwwlogs/你的域名.log
统计POST请求(找出谁在频繁提交表单):
grep "POST" /www/wwwlogs/你的域名.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
这几个命令,我平时至少每周跑一次。特别是最后一个统计POST请求的,跑一下就能看到最近谁在频繁往你的网站发数据。如果某个IP的POST请求数量远超其他IP,那就要重点关注了。
发现异常之后怎么办
找到了可疑IP和攻击行为,接下来就是处理。
第一步:封IP。 如果用的是宝塔,直接在”安全”里把IP加入黑名单。如果用Nginx,可以这样:
# 在Nginx配置里加
deny 178.128.xxx.xxx;
或者在服务器层面用iptables封:
iptables -A INPUT -s 178.128.xxx.xxx -j DROP
第二步:检查有没有被攻破。 封了IP之后,回头确认一下攻击者的尝试有没有成功。如果日志里发现了某个POST请求返回了302重定向(登录成功后会跳转),那说明密码已经被猜出来了。这种情况需要立刻改密码,并且排查网站有没有被植入后门。
第三步:加固防护。 封IP只是治标,攻击者换个IP又会来。可以做几件事:
- 把
wp-login.php的访问限制为只有你自己的IP能访问 - 安装登录限制插件,比如Limit Login Attempts Reloaded
- 开启双因素认证(WordPress后台安全加固里有详细步骤)
第四步:保留日志。 不要急着删日志。如果后续需要报警或者向服务器商投诉,日志文件就是证据。
日志不是出事了才看,应该定期看
我现在的习惯是:每周一早上花十分钟,跑一下上面那几个命令,看看过去一周有没有异常。大多数时候没什么问题,但偶尔会抓到一个新的扫描IP,及时封掉就没事了。
日志这东西,跟网站备份一样,平时不觉得重要,出了事才会后悔没早点看。我那个被暴力破解两周才发现的血泪教训,后来成了我写这篇文章的起点。如果你现在还没看过自己的网站日志,今天花十分钟去看一眼——可能什么都没有,也可能你会发现一个跟我一样的问题。
原创文章,首发于 wujianzhan.com。