更新于

服务器被入侵了吗?可疑登录与异常进程的只读排查

云厂商发来“异常登录”或“疑似挖矿”告警,CPU 莫名被跑满,或者登录记录里满屏陌生 IP——这时最想知道的是“机器是不是已经被人拿下了”。本文给自己部署应用的开发者和站长一组只读检查,帮助你区分“有人在尝试”和“可能已经有人进来了”,并决定要不要升级处理。

先把边界说在前面:

以下命令适用于常见 Linux 发行版;日志路径和服务名因发行版而异,请按实际替换。

0. 开始之前:先保留现场

1. 有人在尝试,还是有人进来了?

先看成功登录。Ubuntu/Debian 通常在 /var/log/auth.log,RHEL/CentOS/Rocky 等在 /var/log/secure;没有这些文件时(例如只用 journald 的系统),用 journal:

sudo grep -E 'Accepted (password|publickey)' /var/log/auth.log | tail -n 50
sudo journalctl -u ssh -u sshd --since "7 days ago" --no-pager | grep -E 'Accepted|Failed password|Invalid user' | tail -n 50

按“认证方式 + 用户 + 来源 IP”汇总成功登录(把文件名换成你系统上的实际路径):

sudo grep -hoE 'Accepted [a-z-]+ for [^ ]+ from [^ ]+' /var/log/auth.log | sort | uniq -c | sort -rn

再看失败尝试和当前在线的会话:

sudo grep -hoE 'Failed password for (invalid user )?[^ ]+ from [^ ]+' /var/log/auth.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head -n 20
who
last -a -n 30
sudo lastb -a -n 30

这些命令不能说明:日志会轮转,只覆盖有限的时间;日志可能被删改;没看到可疑的 Accepted 也不代表没人进来,入侵不一定经过 SSH,也可能来自 Web 应用漏洞或泄露的密钥。

顺手看一下 SSH 当前实际生效的认证设置,为后面的加固决策做准备(只读,需要 root):

sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication) '

passwordauthentication yes 表示允许密码登录,这会让暴力破解有机会成功;permitrootlogin 显示 without-password(即 prohibit-password)表示 root 只能用密钥登录。

2. 有没有异常进程和外连

ps -eo pid,ppid,user,lstart,cmd --sort=-%cpu | head -n 15
sudo ss -tnp state established
sudo ss -ltnup

对可疑的 PID,查看它的可执行文件和工作目录(把 PID 换成实际数字):

sudo ls -l /proc/PID/exe /proc/PID/cwd

可执行文件位于 /tmp、/var/tmp、/dev/shm,或者显示为 (deleted)(程序启动后文件被删),都是需要重视的迹象。

这些命令不能说明:高 CPU 也可能是正常业务;隐藏得好的恶意程序可能不会出现在 ps 和 ss 的输出里。

3. 有没有留下“下次还能进来”的痕迹

sudo crontab -l
crontab -l
sudo ls -la /var/spool/cron/ /var/spool/cron/crontabs/ 2>/dev/null
sudo ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/
cat /etc/crontab
systemctl list-timers --all --no-pager
sudo find /etc/systemd/system -type f -newermt '2026-09-01' -ls

再看账号和密钥:

awk -F: '$3 == 0 {print $1}' /etc/passwd
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $6, $7}' /etc/passwd
sudo find /root /home -name authorized_keys -exec ls -l --time-style=long-iso {} \;
sudo ls -la /etc/sudoers.d/
ls -l /etc/ld.so.preload

这些检查不能说明:文件的修改时间可以被伪造;没找到痕迹不代表没有。

4. 判断之后怎么办

只看到失败尝试、没有可疑的成功登录和进程:这是公网服务器的常见状态。可以考虑加固,但每一项都是需要你决定的变更:只允许密钥登录、禁止 root 密码登录、在安全组里把 22 端口限制为你的 IP、安装 fail2ban 之类的工具。改 SSH 配置时,保持一个已登录的会话不要断开,先用 sudo sshd -t 检查配置语法,再用新窗口测试能否登录;出问题就用保留的会话把配置改回去。云控制台的 VNC/串口是最后的回退通道。之后可以把“登录失败次数突增”“出现新的监听端口”加进日常的只读检查,参见 小团队 VPS 监控清单。

出现以下任意一项,就按“可能已被入侵”处理:不认识的成功登录、不认识的 UID 0 账号或 authorized_keys 公钥、从临时目录运行或已被删除的可执行文件、云厂商已确认的恶意行为告警。这时:

  1. 先快照(如果第 0 步还没做),保留证据。

  2. 需要止损时,在云控制台用安全组限制入站和出站,而不是在机器上删文件、杀进程。这同样是变更:记录原有规则以便恢复,并确认自己仍能通过控制台访问。

  3. 联系云厂商的安全支持,或者专业的安全人员。

  4. 通常更稳妥的做法是用干净的镜像重建服务器,从入侵时间点之前的、确认可靠的备份恢复数据,而不是删掉挖矿程序后继续用这台机器——你很难确认所有后门都已清除。

  5. 从一台干净的设备上轮换这台机器涉及的所有凭证:SSH 密钥、数据库密码、应用里的 API 密钥等。如果你曾用密码登录过这台可疑机器,也应把该密码视为已泄露。

在 OpsMate 里做这些检查

OpsMate 的 SSH 终端和 AI 在同一个页面。上面的命令可以直接手敲;也可以用一句话请 AI 帮你排查:它会提出排查命令,除了读 auth 日志,也可以用 ps、ss、journalctl 这类命令做检查;命令跑完后,点击「需要分析」,AI 会汇总登录来源、用户和时间线。命令和输出留在终端里供你核对(用法见 终端里的「一句话 AI + 手敲命令」)。

说明性示例

说明性示例(不是真实客户案例):云厂商发来“疑似挖矿”告警。ps 显示一个名字像随机字符串的进程占满 CPU,/proc/PID/exe 指向 /tmp 下一个已标记为 (deleted) 的文件;ss 显示它长期连着一个陌生的外部地址。auth 日志里有一条凌晨 3 点从 203.0.113.45 以密码方式成功登录用户 deploy 的记录,而 sshd -T 显示密码登录是开启的;该用户的 crontab 里有一行每 10 分钟下载并执行脚本的任务。这些证据合在一起强烈提示机器已被控制,但仍然不是“结论”。合理的做法是:快照、在安全组层面隔离、联系云厂商安全支持、用干净镜像重建并轮换所有凭证。只杀掉进程、删掉 crontab 然后继续使用,很可能留下没发现的后门。(示例 IP 使用文档保留网段。)

AI 排查提示词

我担心这台服务器有可疑登录。请先只做检查、不做任何改动,看看:最近 7 天 SSH 成功和失败登录的来源、用户和时间分布,当前占 CPU 最高的进程及其可执行文件路径,已建立的外部连接,定时任务和 systemd timer,UID 为 0 的账号,以及 authorized_keys 的修改时间。请只列出观察到的事实和值得关注的点,不要给出“已入侵”或“安全”的结论,并说明还缺少哪些信息。不要删除文件、结束进程、修改配置或重启;如果建议任何变更,先说明风险和回退方案,等我确认。

试用

每月免费 500 次 AI 调用;服务器数量不限。桌面端默认把 SSH 凭证保留在本机。

需要帮助理解排查结果?

OpsMate 帮助开发者和运维人员用 AI 辅助排查,由你核对证据。点击「需要分析」后,命令输出会发送给云端 AI 分析,请先去除敏感信息。

免费开始 本地凭证桌面端

排障指南