更新于
服务器被入侵了吗?可疑登录与异常进程的只读排查
云厂商发来“异常登录”或“疑似挖矿”告警,CPU 莫名被跑满,或者登录记录里满屏陌生 IP——这时最想知道的是“机器是不是已经被人拿下了”。本文给自己部署应用的开发者和站长一组只读检查,帮助你区分“有人在尝试”和“可能已经有人进来了”,并决定要不要升级处理。
先把边界说在前面:
本文和 OpsMate 都不能给出“已入侵 / 未入侵”的结论,也不能证明一台机器是干净的。 OpsMate 不是安全产品,不做入侵检测。
如果机器真的被控制,攻击者可能改过
ps、ls等工具或删改过日志,这台机器上看到的任何输出都不能完全信任。在确认之前,不要删文件、不要杀进程、不要重启。这些动作会破坏证据,也可能让你误以为问题已经解决。
以下命令适用于常见 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
只要端口 22 对公网开放,大量
Failed password/Invalid user几乎是常态,失败尝试本身不等于被入侵。真正要紧的是
Accepted:出现你不认识的用户、不认识的来源 IP、不合常理的时间(比如你在睡觉的时段),就是需要升级处理的强信号。last/lastb读取 wtmp/btmp 记录。较新的发行版(如 Debian 13)已经移除了这两个命令,可以用lslogins --failed或上面的 journal 查询代替。
这些命令不能说明:日志会轮转,只覆盖有限的时间;日志可能被删改;没看到可疑的 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
看占 CPU 最高的进程:名字是否认识、属于哪个用户、什么时候启动的(
lstart)。随机字符串式的进程名、伪装成系统进程的名字、以陌生用户运行的高 CPU 进程,都值得记下来。ss -tnp state established看已建立的连接:有没有不认识的进程长期连着陌生的外部地址。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
定时任务里出现你不认识的
curl ... | sh、wget、base64 解码后执行之类的内容,是常见的持久化手法。find -newermt列出指定日期之后改动过的 systemd 单元文件,日期请改成你怀疑的起始时间之前。
再看账号和密钥:
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
UID 为 0 的账号正常情况下只有
root。列出普通用户,确认每个都有归属;再逐个查看
authorized_keys的修改时间和里面的公钥,是否有你没加过的。/etc/ld.so.preload在多数系统上不存在;如果存在且你不知道来由,需要重视。
这些检查不能说明:文件的修改时间可以被伪造;没找到痕迹不代表没有。
4. 判断之后怎么办
只看到失败尝试、没有可疑的成功登录和进程:这是公网服务器的常见状态。可以考虑加固,但每一项都是需要你决定的变更:只允许密钥登录、禁止 root 密码登录、在安全组里把 22 端口限制为你的 IP、安装 fail2ban 之类的工具。改 SSH 配置时,保持一个已登录的会话不要断开,先用 sudo sshd -t 检查配置语法,再用新窗口测试能否登录;出问题就用保留的会话把配置改回去。云控制台的 VNC/串口是最后的回退通道。之后可以把“登录失败次数突增”“出现新的监听端口”加进日常的只读检查,参见 小团队 VPS 监控清单。
出现以下任意一项,就按“可能已被入侵”处理:不认识的成功登录、不认识的 UID 0 账号或 authorized_keys 公钥、从临时目录运行或已被删除的可执行文件、云厂商已确认的恶意行为告警。这时:
先快照(如果第 0 步还没做),保留证据。
需要止损时,在云控制台用安全组限制入站和出站,而不是在机器上删文件、杀进程。这同样是变更:记录原有规则以便恢复,并确认自己仍能通过控制台访问。
联系云厂商的安全支持,或者专业的安全人员。
通常更稳妥的做法是用干净的镜像重建服务器,从入侵时间点之前的、确认可靠的备份恢复数据,而不是删掉挖矿程序后继续用这台机器——你很难确认所有后门都已清除。
从一台干净的设备上轮换这台机器涉及的所有凭证:SSH 密钥、数据库密码、应用里的 API 密钥等。如果你曾用密码登录过这台可疑机器,也应把该密码视为已泄露。
在 OpsMate 里做这些检查
OpsMate 的 SSH 终端和 AI 在同一个页面。上面的命令可以直接手敲;也可以用一句话请 AI 帮你排查:它会提出排查命令,除了读 auth 日志,也可以用 ps、ss、journalctl 这类命令做检查;命令跑完后,点击「需要分析」,AI 会汇总登录来源、用户和时间线。命令和输出留在终端里供你核对(用法见 终端里的「一句话 AI + 手敲命令」)。
先考虑脱敏:点击「需要分析」后,命令输出会发送给云端 AI 分析;桌面端默认保证的只是 SSH 凭证留在本机。如果日志里有客户 IP、真实用户名等你不想发出去的信息,不要直接点「需要分析」,先自己手敲命令,把摘录里的 IP 和用户名替换成
IP_A、USER_A之类的占位符,再把脱敏后的内容交给 AI 解释。不要把 AI 的总结当成结论:它能帮你整理时间线、指出值得看的行,但不能判断机器是否被入侵,更不能证明机器干净。
AI 以排查为主:危险命令会被拦截。快照、隔离、重建、轮换凭证都由你和负责安全的人决定。OpsMate 自己会做什么、不会做什么,以官网 常见问题 为准。
桌面端默认把 SSH 凭证保留在本机。即便如此,一旦怀疑机器被入侵,登录过它的密码和相关密钥仍应轮换。
说明性示例
说明性示例(不是真实客户案例):云厂商发来“疑似挖矿”告警。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 分析,请先去除敏感信息。
免费开始 本地凭证桌面端