前两天服务器经历了一次比较典型的入侵事件。整个过程其实挺有代表性的,从最开始的网络异常,到逐步定位问题,再到最后确认系统被入侵并彻底重装系统。这里把整个过程写下来,既是给自己做个记录,也希望给以后遇到类似问题的人一点参考。
事情的起因其实不是来自服务器报警,而是来自网络异常。当时整个机柜的网络突然变得非常奇怪,看起来像是“断网”,但又不完全是。微信还能发消息,但是速度非常慢,延迟高得离谱,基本上和断网差不多。同时在 Ubiquiti 的网关管理界面上可以看到非常明显的异常:丢包率飙升,延迟非常高。
一开始其实还以为是运营商线路的问题,但进一步查看网关的流量统计之后,很快发现事情不太对。设备列表里有一台服务器的流量异常高,这台机器是一台 Dell R730xd,它的上下行流量几乎同时跑满,大约在 50MB/s 左右。换句话说,这台服务器基本上把整个出口带宽占满了。机柜里其他设备的网络之所以几乎不可用,其实就是被这台机器拖垮的。
为了先恢复整个网络环境,第一步采取的措施是在网关上给这台服务器做带宽限速。限速之后效果立刻出现了,整个机柜的网络马上恢复正常,其他设备也可以正常访问外网。这一步基本可以确认问题来源确实就是这台服务器。
接下来就登录服务器开始排查。当时第一反应是看系统资源情况,比如 CPU 和内存占用。但结果非常奇怪,CPU 使用率正常,内存占用也很正常,没有任何明显的异常负载。但与此同时,服务器的网络流量却在持续对外通信。这种情况其实是很多恶意程序的典型特征:CPU 不高,但网络非常活跃。
因为这台服务器之前接入了 Cloudflare Tunnel,所以最开始还怀疑是不是 Tunnel 被滥用,于是先把 Tunnel 直接关掉。但关闭之后观察流量,发现服务器的异常流量依然持续存在,这一步基本可以排除 Cloudflare Tunnel 的影响。
接下来又尝试关闭 Web 服务。直接停止 nginx,如果流量来自网站访问,那么关闭 Web 服务之后流量应该会明显下降。但结果依然没有变化,服务器仍然在持续产生流量。到这一步基本可以确定,问题已经不是网站访问层面的事情,而是系统内部有进程在产生网络通信。
于是开始检查系统进程。在查看进程列表的时候,很快发现了一批非常可疑的进程。其中一个比较典型的是一个名叫 dbus-daemon 的进程,但它的运行路径是在 /dev/shm 目录下。这个细节其实非常关键,因为 /dev/shm 是 Linux 的内存文件系统,正常的系统服务不会从这里运行。真正的 dbus-daemon 应该在 /usr/bin 这样的系统目录,而不是在 /dev/shm 里面。也就是说,这个进程明显是在伪装成系统进程。
接下来把这些可疑进程全部终止。进程被杀掉之后,服务器的异常流量立刻下降,网络恢复正常,看起来问题好像解决了。
但过了几分钟之后,异常流量又出现了。再去看进程列表,又出现了一批类似的进程。这说明这个恶意程序并不是简单的单个进程,而是有自动启动机制。你把它杀掉之后,它会过一会儿重新启动。这种情况一般说明系统里存在某种持久化启动机制,比如定时任务、systemd 服务或者隐藏脚本,但这些东西往往藏得很深。
既然已经确认服务器存在系统级异常进程,那么接下来就要找攻击入口。服务器上跑着几个网站,于是开始逐个检查网站目录。很快就在一个 WordPress 站点里发现了一些异常的 PHP 文件。这些文件的文件名不像 WordPress 原本的文件,而且内容明显经过混淆。打开之后可以看到大量 Base64 编码以及 eval 之类的结构。这种代码基本可以确定就是典型的 PHP WebShell。
根据这些痕迹,大致可以推测攻击路径。攻击者应该是先通过 WordPress 的某个漏洞或者弱密码获得网站写入权限,然后上传 WebShell 文件。有了 WebShell 之后,攻击者就可以在服务器上执行系统命令,比如下载恶意程序。随后恶意程序被下载到系统里,并在 /dev/shm 这样的目录中运行,同时伪装成系统进程名,例如 dbus-daemon。这个程序随后持续进行网络通信,从而占满服务器带宽。
为了进一步确认攻击情况,又查看了这个 WordPress 站点的访问日志。日志里可以看到大量来自不同国家的陌生 IP,对 WordPress 的常见入口进行扫描,比如登录接口和后台路径。这类访问基本都是自动化扫描工具,用来寻找漏洞或者弱密码。
由于这个恶意程序已经具备自动重启机制,而且启动位置隐藏得很深,即使把当前进程清理掉,也很难保证系统已经完全干净。在这种情况下继续排查其实意义不大,所以最终做出的决定是直接放弃当前系统。只备份必要的数据文件,然后对服务器进行整机重装。系统重装之后重新部署服务,问题也彻底消失了。
这次事件其实有几个比较重要的经验。第一,当网络出现类似“假断网”的情况时,不一定是线路问题,很可能是某台机器把出口带宽跑满了。第二,服务器被入侵时,CPU 和内存不一定会有异常,很多恶意程序只是进行网络通信,因此最明显的信号往往是异常流量。第三,一旦确认系统级入侵,并且存在持久化机制,最安全的处理方式通常就是直接重装系统,而不是试图逐个清理。
另外,这次之后也给那个 WordPress 站点加上了 Cloudflare 的安全防护,比如 WAF 和访问频率限制,用来减少自动化扫描带来的风险。WordPress 这种公开服务的站点,如果长期暴露在公网,其实几乎每天都会被扫描,防护措施还是有必要的。
整个过程虽然折腾了一圈,但也算是一次比较完整的实战排查。如果你的服务器也突然出现网络异常、带宽被打满,而 CPU 却很正常,那就要警惕了,很可能并不是网络问题,而是服务器已经被别人拿去干活了。