VPS被入侵了怎么办?服务器被黑后的紧急处理方案
VPS被入侵后不要尝试清理,因为Rootkit会伪造系统状态。本文提供标准应急流程:在云服务商控制台进行网络隔离、对磁盘快照留证、轮换所有凭据并从干净镜像重建系统,避免因后门残留导致二次泄露。
不要清理被入侵的 VPS
如果您的 VPS 被入侵,最重要的决定是在执行任何命令之前做出的。不要尝试清理机器。应在服务商控制台将其隔离,对磁盘进行快照以留作证据,轮换该服务器持有的所有凭据,然后使用您信任的源在全新的服务器上重建。
您无法证明 rootkit 已被清除,因为用于证明的工具本身就处于攻击者的控制之下。
这就是全部论点。其背后的机制如下:获得 root 权限的攻击者可以替换 ps,使某个进程 ID 永远不会出现在其输出中。/etc/ld.so.preload 中的一行代码可以将攻击者代码加载到系统中的每个动态链接程序中,因此 ls、ss 和 find 都会以同样一致的方式撒谎。可加载内核模块可以在系统调用层面隐藏文件,即使是刚下载的二进制文件看到的也是干净的磁盘。您删除了挖矿程序,CPU 图表下降,服务器恢复平静。但平静也是一个正常工作的后门所呈现的状态。
重建的成本比感觉上要低。典型的 VPS 只包含少数几个软件包、一个配置目录和一个数据集,因此重建是一项有明确终点的工作。而搜寻攻击者所做的每一处改动则是无底洞,且永远无法得到确凿的证明。
确认服务器确实已被入侵
许多被报告为“被黑”的服务器实际上并未被入侵。每天数以千计的 SSH 登录失败属于互联网背景噪声,因为每个公网 IPv4 地址都在被持续扫描。lastb 的输出中充斥着 root 和 admin 的尝试,这仅说明扫描器发现了你的端口,并不代表有人已经进入系统。
以下信号才意味着真正的问题:
- 无法解释的成功登录记录,例如
Accepted password for root from 203.0.113.7。 authorized_keys中出现了你未添加的密钥。- 收到主机商关于服务器发出异常流量的滥用通知。
- 某个进程占用 100% CPU,且名称模仿内核线程。通过暴露的 Redis 和 Docker 套接字植入的挖矿程序,常以
kdevtmpfsi和kinsing等名称出现。 - 向你的服务从未使用过的地址发起出站连接。
针对内核线程伪装有一个快速测试方法。真正的内核线程显示在方括号内,且没有对应的可执行文件,因此 sudo ls -l /proc/<pid>/exe 对它们会因 No such file or directory 而失败。如果一个显示为 [kworker/0:2] 的进程,其 exe 链接指向 /tmp 下的某个位置,那么它就是一个冒充内核名称的普通用户程序。
执行这些检查时,请意识到系统可能在欺骗你。这些检查足以判断系统存在异常,但不足以证明系统完全安全。
在服务商层面切断网络,而非在服务器内部操作
隔离是首要任务。只要攻击者仍持有 shell,后续的任何操作都是徒劳。在攻击者实时监控的情况下,查看日志、轮换密钥和恢复数据毫无意义。
请在服务商的控制面板中进行操作,使用操作系统之外的网络防火墙。拒绝所有入站和出站流量,仅保留 Web 控制台作为访问入口。在此处执行的规则不受磁盘上任何异常情况的影响。
不建议在服务器内部执行此操作有两个原因。在被入侵的内核中配置防火墙,其执行权仍归该内核所有,root 用户可以像你编写规则一样轻松地清除 nftables。此外,通过 SSH 执行 sudo ip link set enp1s0 down 会先切断你自己的会话,导致你被锁定在正在检查的机器之外。
同时封禁出站和入站流量。反向 shell 会从你的服务器向攻击者发起外连,因此仅封禁入站流量无法切断已建立的连接。如果服务商仅提供入站规则,剩下的选择是断开网络接口或关闭实例。
不要立即重启。首先检查 /var/log/journal 是否存在。如果该目录不存在,说明 journald 正在将日志写入 /run/log/journal,该路径位于内存中,重启会删除入侵记录。运行中的进程也会在重启后消失,而它们的命令行参数往往是你所能获取的最直接的证据。
在进行任何操作前对磁盘进行快照
在此场景下,快照与备份的作用不同。你现在创建的快照是受损磁盘的副本:它是你的证据,也是你在误操作覆盖数据后唯一能回退的手段。你之前的备份才是恢复路径。如果你的服务商控制面板混用了这两个词,请先阅读 VPS 快照与常规备份的区别,因为它们的保留规则和恢复行为并不相同。
在再次登录服务器前,请从服务商控制面板执行快照。实时快照具有崩溃一致性:它捕获的是那一瞬间的磁盘状态,等同于直接断电。这对留存证据已足够。请为快照命名,以免他人误操作恢复。使用 COMPROMISED-do-not-restore-2026-08-12 这样直白的名称最为合适。请保留该快照,直到调查结束且你与主机商之间的所有滥用工单均已关闭。
当 SSH 无法连接时的访问方法
有两种途径,均可在服务商控制面板中找到。Web 控制台(VNC 或串口)的作用等同于直接连接物理键盘。当 sshd 服务停止、防火墙配置错误或攻击者修改了 SSH 端口时,该方式依然有效。它使用本地密码进行身份验证,因此对于仅使用密钥登录的服务器,可能需要先重置 root 密码才能通过控制台登录。
救援模式是更好的选择。它会引导一个精简的 Live 系统,并将你的磁盘挂载为非运行状态,因此你执行的命令是可信的:此时被入侵的内核和二进制文件并未运行。请以只读方式挂载磁盘。
lsblk -f
sudo mkdir -p /mnt/victim
sudo mount -o ro /dev/vda1 /mnt/victim如果 lsblk 显示的是 LVM(逻辑卷管理器)卷而非普通分区,请先使用 sudo vgchange -ay 激活它们,然后挂载 /dev/mapper/ 下出现的设备。
不要使用 chroot 进入已挂载的磁盘进行查看。chroot 会以你的权限执行攻击者的二进制文件,这将导致你进入救援模式的目的完全失效。
收集仍然可信的证据
在救援模式下运行这些命令,并将磁盘以只读方式挂载到 /mnt/victim。首先检查登录记录,因为它们能确定入侵时间,一旦有了时间窗口,其他工作都会变得容易。
sudo grep -aE 'Accepted (password|publickey)' /mnt/victim/var/log/auth.log
sudo last -f /mnt/victim/var/log/wtmp
sudo lastb -f /mnt/victim/var/log/btmp
sudo journalctl -D /mnt/victim/var/log/journal -u ssh --since "2026-07-01"缺少 /var/log/auth.log 本身并不一定可疑。一些当前的 Ubuntu 镜像默认不安装 rsyslog,因此 sshd 的日志仅记录在 journal 中,这正是 journalctl -D 行所读取的内容。真正值得注意的是日志在连续记录中出现的断层,或者被截断为 0 字节的日志文件。清除日志的行为很常见,且通常手法拙劣。
接下来检查账户和密钥。
sudo find /mnt/victim/root /mnt/victim/home -name 'authorized_keys*' -exec ls -l {} +
sudo awk -F: '$3 == 0 {print $1}' /mnt/victim/etc/passwd
sudo lsattr /mnt/victim/root/.ssh/authorized_keysawk 行会打印出所有用户 ID 为 0 的账户。如果输出中出现 root 以外的内容,则说明存在第二个 root 账户。find 模式特意匹配了 authorized_keys2,因为 OpenSSH 默认会读取这两个文件名,而后者很容易被忽略。如果 lsattr 在属性列表中打印出 i,说明该文件是不可变的:攻击者设置此标志是为了让你的删除操作因 Operation not permitted 错误而失败,而疲惫的管理员可能会误以为修改已生效。
持久化机制通常隐藏在少数几个位置,请务必全部检查。
sudo ls -lt /mnt/victim/etc/systemd/system
sudo ls -l /mnt/victim/etc/cron.d /mnt/victim/var/spool/cron/crontabs
sudo cat /mnt/victim/etc/ld.so.preload
sudo grep -rnE 'curl|wget|base64|/dev/tcp' /mnt/victim/etc/update-motd.d /mnt/victim/etc/rc.local /mnt/victim/root/.bashrc /mnt/victim/root/.profile/etc/ld.so.preload 在正常的 Ubuntu 或 Debian 系统中并不存在,因此 No such file or directory 是健康的结果,任何内容都值得你关注。如果登录文件将 base64 -d 的输出通过管道传递给 shell,情况也是一样:合法的配置不需要隐藏其自身文本。
根据更改时间(ctime)而非修改时间(mtime)构建时间线。
sudo find /mnt/victim -xdev -newerct '2026-08-01' -type f -printf '%TF %TT %p\n' | sorttouch 可以将修改时间设置为攻击者想要的任何值,因此 mtime 不可信。更改时间(ctime)会在 inode 发生任何更改时更新,且 touch 无法将其回溯,因此 -newerct 提供了更真实的近期写入记录。但这仍不能作为确凿证据,因为 root 用户可以修改系统时钟或直接向块设备写入数据。
软件包完整性检查只需一个命令,但有一个注意事项。在运行中的系统上,sudo dpkg --verify 会为每个校验和不匹配的打包文件打印一行记录,并在校验和列显示 5;如果安装了 debsums 软件包,sudo debsums -ac 也可以完成同样的工作,且包含配置文件。请仅从一个方向解读结果:已更改的 /usr/sbin/sshd 是确凿证据。而报告显示“干净”并不能证明什么,因为替换二进制文件的同一个 root 账户同样可以重写 /var/lib/dpkg/info/ 下的校验和列表。诸如 rkhunter 和 chkrootkit 之类的 Rootkit 扫描器遵循同样的规则:发现异常是有价值的信息,而扫描结果“干净”并不代表系统已清除威胁。
在进行任何破坏性操作之前,请将收集到的数据从机器上复制出来。
sudo tar --ignore-failed-read -C /mnt/victim -czf /root/evidence-2026-08-12.tgz \
var/log etc root/.ssh root/.bash_history home
sha256sum /root/evidence-2026-08-12.tgz将该哈希值记录在服务器之外的地方。如果将来涉及保险索赔或警方调查,能够证明归档文件自收集以来未被更改,是区分“证据”与“普通文件文件夹”的关键。在调查过程中误删文件是常有的事,快照加上这份归档文件是确保调查能够继续的前提。事后撤销错误的 rm 操作比人们预想的要困难得多,正如 恢复被 rm -rf 删除的文件 中所解释的那样。
查找入侵入口
如果重建系统后未能关闭入侵路径,服务器通常会在几天内再次被攻破,因为扫描程序从未停止。绝大多数单机服务器的入侵都源于以下四种入口。
SSH 密码登录。 如果在 Accepted password for root 中发现来自陌生地址的记录,这就是答案。请检查 PasswordAuthentication 在 /etc/ssh/sshd_config 以及 /etc/ssh/sshd_config.d/ 下所有文件中的设置。sshd 会优先使用读取到的第一个关键字值,而 Ubuntu 主配置文件顶部的 Include 行会覆盖后续的配置,因此直接放入的配置文件可能会悄无声息地覆盖你在文件末尾修改的设置。
未配置身份验证的公开服务。 例如 6379 端口上的 Redis、2375 端口上的 Docker API,或绑定到 0.0.0.0 而非 127.0.0.1 的数据库。Docker 是最常见的隐患。发布容器端口会插入 DNAT(目标网络地址转换)规则,这些规则的优先级高于 ufw 链,因此 ufw status 可能会显示端口已拦截,但容器实际上已向全网开放。在重建系统前务必理解这一点:为什么 Docker 发布端口会绕过 ufw 详细说明了规则顺序及修复方法。
未打补丁的 Web 应用。 在发现异常的最早时间戳附近,搜索 Web 服务器访问日志中指向上传路径或管理路径的 POST 请求,然后查找 Web 根目录下修改时间相符的文件。上传目录中多出的 PHP 文件是典型的入侵结果。
凭据泄露。 提交到代码仓库的密钥、粘贴在聊天记录中的令牌,或是被配置错误的 Web 服务器当作静态文件提供的 .env 文件。自动化操作很容易导致此类失误,这也是 为何应将密钥排除在 AI 代理及其配置文件之外 的原因。
如果排查后仍无法确定入口,请假设凭据已泄露,并将该机器上存储的所有密钥视为已公开。
轮换该机器可能已泄露的所有凭据
请务必在切断网络连接后再进行轮换,切勿提前操作。若在攻击者仍保持连接时进行轮换,只会直接将新密钥拱手相让。
- 服务器上存储的所有 SSH 私钥,以及其他任何信任对应公钥的账户。
- 通过
ssh -A转发到该机器的任何密钥。代理转发会在/tmp下留下一个套接字,只要您的会话保持开启,该机器上的 root 用户即可利用此套接字在任何接受您密钥的地方进行身份验证。 - 位于
.env文件、systemdEnvironment=行、CI 配置以及服务商凭据中的 API 令牌。 - 数据库密码及其所关联的应用账户。
- 服务器持有的 TLS (传输层安全) 私钥。请重新签发证书并吊销旧证书。
- 您的托管账户密码,并开启双重身份验证。该控制面板可以重建、快照并进入您拥有的每台服务器的控制台,因此它是真正的安全边界。
- 在该主机被入侵期间,在 shell 会话中输入的任何密码,因为 root 用户可以实时记录终端会话。
如果该机器上的密码在其他任何地方也被使用,请一并修改。密码复用是导致一台 VPS 被入侵演变为电子邮件账户被入侵的主要原因。
重建检查清单
- 使用全新的发行版镜像创建新服务器。不要使用被入侵系统的快照,也不要进行整个根文件系统的恢复。
- 从发行版仓库安装软件包。严禁从旧磁盘复制任何二进制文件。
- 仅恢复数据,且备份日期必须早于时间线中最早的入侵证据。包括数据库导出文件、上传内容和应用状态。放弃
/etc、/usr以及旧的单元文件。 - 手动输入轮换后的密钥。不要复制旧的
.env。 - 在重新提供服务前,检查恢复的 Web 内容,剔除入侵期间添加的文件。
- 在暴露服务前加固系统:仅限密钥登录 SSH、使用非 root 工作账户、默认拒绝入站防火墙,且严禁将服务发布到不必要的范围。请依次完成 新 VPS 的前十分钟配置,然后 正确加固 SSH,最后添加 Ubuntu 24.04 上的 fail2ban 以减少登录日志干扰。为每个服务分配 独立的最小权限账户,确保下次入侵无法直接获取 root 权限。
- 关闭旧服务器电源,并保留其快照,直到调查结束且所有滥用投诉处理完毕。
- 修复备份策略。如果第 3 步只能靠猜测,说明备份历史太短,无法追溯到入侵发生之前。具有长保留期的异地版本化备份才能在下次提供干净的还原点:VPS 上的 restic 备份 可以同时满足这两点。
如果你无法确定入侵时间,就无法选择安全的备份。在这种情况下,仅恢复可以通过肉眼检查的数据:例如可阅读的 SQL 导出文件或可列出的图片目录。将所有可执行文件视为可疑,并从仓库重新安装。
主机商发送滥用通知的含义
大多数人并非通过自身监控,而是从服务提供商处得知服务器被入侵。主机商会监测到出站流量:针对其他网络的 SSH 暴力破解、25 端口上的垃圾邮件,或是参与反射攻击。工单通常包含时间戳、端口和流量样本,并附带以小时为单位的截止期限。
即使你唯一的回复是服务器已被隔离并正在重建,也必须回复工单。如果工单未得到回复,提供商会执行黑洞路由或暂停服务器,这会将你的安全事件演变为服务中断。随后,要求提供报告背后的原始日志行。这些时间戳是在你的机器之外记录的,因此它们是攻击者无法篡改的时间线部分,相比磁盘上的任何内容,它们往往能更准确地确定入侵时间。
客户服务器被入侵对主机商而言是常规工作,妥善处理不会对你产生负面影响。关于 VPS 托管是否安全 的更广泛问题,主要取决于客户的配置,而这正是你现在需要从零开始重新完成的部分。
何时寻求专业协助
- 服务器存储了他人个人数据。根据 GDPR(通用数据保护条例),发生个人数据泄露时,必须在获悉后立即向监管机构报告;若可行,应在 72 小时内完成。判断报告时限是否已触发属于法律范畴,而非系统管理员的工作。
- 涉及支付卡数据。卡组织要求由经认可的取证调查员介入,自行排查可能会破坏取证现场。
- 收到勒索要求,或数据已被加密。
- 该机器可访问其他设备:如内部网络、虚拟机管理程序或持有生产环境凭据的 CI runner。在证明清白之前,集群中一台主机被入侵即视为全网安全事件。
- 若需保留证据以供保险理赔或执法部门使用,请在快照后停止操作,制作完整磁盘镜像,并记录所有操作人员及时间。
对于仅运行个人服务且不含他人数据的单台 VPS,上述操作手册即为全部工作内容:在云服务商层面进行隔离,拍摄快照留存证据,收集仍可信的数据,轮换所有凭据,最后进行全新重装。
FAQ
我可以直接清理被入侵的 VPS 而不是重装系统吗?
不能,因为你无法确信清理结果。你是在要求一个已被入侵的系统报告其自身的状态。被替换的 ps 可以隐藏进程,/etc/ld.so.preload 中的一行代码可以向你运行的每个动态链接工具注入恶意代码,而内核模块可以同时对所有程序隐藏文件。你可以发现已知的恶意行为,因此发现问题是有意义的。但你无法证明系统不存在其他问题,因此“清理干净”的结果不可信。只有当服务器上没有任何重要数据,且你接受它可能再次被入侵的前提下,清理才具有可行性。
我应该关闭被入侵的服务器还是让它保持运行?
首先在服务商控制台切断其网络,然后保持运行足够长的时间,以便拍摄快照并查看正在运行的进程。关机会销毁进程列表;如果 /var/log/journal 不存在,关机还会彻底删除日志,因为此时 journald 会将日志写入 /run 下的内存中。如果服务器正在主动攻击其他网络,且你无法拦截其出站流量,则必须立即关机。停止危害比保留证据更重要。
我该如何确定攻击者是什么时候进入系统的?
在 /var/log/auth.log 或系统日志中找到最早且无法解释的 Accepted password 或 Accepted publickey 条目。使用 find / -xdev -newerct 'YYYY-MM-DD' -type f 列出文件的变更时间进行交叉验证,因为 ctime 比 mtime 更难伪造。然后将两者与服务商滥用通知中的时间戳进行对比,这些时间戳记录在机器外部,无法被篡改。选择一个早于这三个日期中最早时间的备份。如果无法对齐时间,请假设入侵时间早于你的备份历史,并仅恢复你可以检查的数据。
入侵后我的备份还能安全恢复吗?
经过检查后,数据通常是安全的,但系统文件不是。在入侵后进行的备份包含后门,因此恢复整个根文件系统也会恢复攻击者。同时也要检查备份仓库本身:如果备份凭据存储在被入侵的服务器上,备份历史可能已被删除或篡改,这就是使用仅追加(append-only)或拉取式(pull-based)备份目标的原因。请仅恢复应用数据,然后从发行版仓库重新安装软件。
我的 VPS 被入侵后,我必须通知任何人吗?
必须回复服务商的滥用通知。除此之外,这取决于机器上存储了谁的数据。如果涉及他人的个人数据,可能会触发法律报告义务,例如 GDPR 规定的 72 小时内向监管机构报告。如果服务器上存储了用户凭据,请告知这些用户,以便他们在其他地方修改密码。如果机器上的密钥授权了对第三方系统(如代码托管平台或云账户)的访问权限,请告知这些服务商,以便他们检查是否存在滥用行为。如果服务器仅供个人使用且不包含任何他人的数据,则除了回复滥用通知外,没有其他义务。