你有没有在半夜接过这样的告警:云监控弹出一条“CPU使用率超过90%”,你的第一反应是业务高峰,可登录服务器后看到的是一个叫kthreadds的陌生进程,藏着/tmp/.X11/目录下,连着一串境外矿池地址。不用怀疑,服务器中挖矿木马了。
这篇文章是我处理一次真实挖矿入侵的完整复盘。从发现异常、定位木马、切断持久化,到把Docker重构成Rootless模式做权限隔离,再到日常加固方案,都会一步步展开。内容面向运维、后端开发,以及所有自己维护服务器的独立开发者。如果你正用默认配置的Docker跑业务,或者根本不清楚自己的Socket暴露范围,这篇文章至少能帮你少踩几个坑。
1. 事发当晚:挖矿木马是怎么进来的
1.1 现场第一次响应
我习惯每天睡前瞄一眼监控,那天看到八核CPU全部跑满,第一反应是定时任务或者日志处理脚本出了问题。登录服务器先执行top,排前面的进程里有个kthreadds,名字看起来很像系统内核线程,但CPU占用高达380%。经验告诉我,真内核线程的名字不会这么刻意,更不会单独占一个进程组。
接着我做了三件事:
bash复制ps -ef | grep kthreadds
ls -l /proc/$(pgrep kthreadds)/exe
cat /proc/$(pgrep kthreadds)/cmdline | tr '\0' ' '
输出很快暴露了问题。可执行文件路径在/tmp/.X11/config.sh,进程命令行里带着-a cryptonight这类参数,再配合外联IP段,基本可以确定是挖矿木马。这类木马通常还会释放免密公钥到authorized_keys,方便攻击者随时回来取货。
1.2 攻击者到底走了哪条路
清理前我强迫自己先回答一个问题:它是怎么进来的?
我检查了这几个常见入口:
- SSH暴力破解:看
/var/log/auth.log里有没有大量Failed password记录,确认是否弱口令账号被爆破。 - Docker API未授权:默认Docker Daemon只会监听
/var/run/docker.sock,但以前有同事为了远程管理,直接在daemon.json里加了"hosts": ["tcp://0.0.0.0:2375"],等于把Docker的控制权放到了公网。 - 暴露的Web服务漏洞:服务器上跑着某个旧版本管理后台,反代日志里有一些
/cgi-bin/路径探测记录。
排查后发现主要入口是SSH弱口令加Docker Socket权限过大。攻击者先登录服务器,发现当前用户在docker组里,直接利用Docker Socket容器挂载宿主目录,把挖矿程序带进了宿主机。这类攻击路径现在很常见:不需要内核漏洞,一个属于docker组的账号就能提权到宿主root,因为docker run -v /:/host本身就是一种最直接的提权方式。
所以这次事故真正让我紧张的,不只是CPU被打满,而是攻击者已经具备通过Docker Socket控制整台服务器的能力。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 主机排查实战:把入侵痕迹挖干净
2.1 识别伪装进程
挖矿木马很喜欢伪装成系统进程名。除了kthreadds,我还见过ksoftirqds、systemd-sudo、networkd这类命名。它们会利用系统管理员疲劳,匆匆扫一眼top就放过。
判断进程真伪需要看三条信息:
bash复制readlink /proc/PID/exe
cat /proc/PID/environ | tr '\0' '\n' | head -50
ls -l /proc/PID/fd | grep -E 'deleted|/tmp'
正常内核线程的exe链路指向/usr/bin/或者内核目录,不会从/tmp/下执行。很多木马为了防查杀,会把自己写成一个脚本,动态编译二进制,再立刻删除源文件。这样你看到进程虽然活着,文件已经没了。别慌,/proc/PID/exe在进程运行期间依然可以读,先复制出来:
bash复制cp /proc/PID/exe /root/malware-sample.bin
后续可以丢给杀毒引擎或在线沙箱做特征确认,也能判断挖矿变种家族。
2.2 持久化藏匿点
挖矿木马最核心的目标不是跑一次,而是每次重启后都能活过来。我梳理了服务器上所有可能的持久化位置,下面这张表可以作为排查模板:
| 位置 | 检查命令 | 备注 |
|---|---|---|
| 用户定时任务 | crontab -l |
注意每个账号都看 |
| 系统定时任务 | cat /etc/crontab、ls /etc/cron.d/ |
文件名往往是无规则字符串 |
| systemd服务 | systemctl list-unit-files |
检查异常Unit和动态生成的服务 |
| SSH公钥 | cat ~/.ssh/authorized_keys |
防止后门登录 |
| Shell启动 |
