Ubuntu服务器在长期运行后,系统管理员最容易陷入的误区是“没报警就等于没问题”。实际上,很多高危漏洞和性能瓶颈在爆发前都有征兆,只是常规的监控脚本没有覆盖到那些死角。真正的常态化巡检,不是跑一遍“apt update”那么简单,而是需要建立一套针对用户权限、网络异常、内核状态和合规基线的多维排查体系。下面直接拆解具体的执行技巧和排查命令。
排查异常账户与隐形提权风险攻击者一旦突破边界,第一件事往往是创建隐藏账户或篡改现有账户权限。常规的“cat /etc/passwd”只能看到表面,重点在于检查是否有UID为0的非root账户。执行命令:
awk -F: '($3 == 0) {print}' /etc/passwd
正常输出应该只有root一行。如果出现其他账户名,说明系统已被植入超级用户后门。另一个高危点是空密码账户,用以下命令快速扫描:
awk -F: '($2 == "" ) {print $1}' /etc/shadow
此外,/etc/sudoers文件的检查不能只靠肉眼。重点关注NOPASSWD配置,它允许特定命令无需密码执行,常被用于持久化控制。使用visudo -c检查语法后,用grep过滤无密码条目:
grep -v '^#' /etc/sudoers | grep NOPASSWD
同时检查/etc/sudoers.d/目录下的分片文件,很多安全基线会忽略这里。对于用户登录行为,lastlog命令能显示所有账户的最后登录时间,重点关注从未登录过的账户,它们可能是测试账户或遗留后门,应及时禁用。
网络监听与异常外联的深度检测netstat -tunlp是常用命令,但它在容器化和高并发场景下输出量巨大,容易漏掉关键信息。更高效的做法是直接排查监听在0.0.0.0上的非业务端口,特别是高位端口。用ss命令替代netstat,性能更好:
ss -tlnp | grep '0.0.0.0:'
重点核对每个监听端口的PID和进程名。如果发现某个进程伪装成系统进程却监听在奇怪端口,用lsof -p PID进一步查看它打开的所有文件和连接。对于外联连接,攻击者常使用反向Shell或DNS隧道。用ss -anp列出所有ESTABLISHED状态连接,结合地理位置信息判断是否异常。一个实用技巧是检查crontab中是否隐藏了反弹Shell的定时任务:
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null; done
这条命令会遍历所有用户的定时任务。同时检查/etc/cron.d/、/etc/cron.hourly/等系统级目录,攻击者常在这些地方放置恶意脚本。对于DNS异常,检查/etc/resolv.conf是否被篡改,以及/etc/hosts文件中是否有可疑的域名映射。
内核模块与系统调用层的威胁狩猎Rootkit是常态化巡检中最难对付的对手,因为它能劫持系统调用,让ls、ps等基础命令失效。单纯靠rkhunter或chkrootkit这类工具已经不够,因为它们依赖的特征库更新滞后。更底层的做法是直接对比内核符号表与/proc/kallsyms中的地址。如果发现不一致,说明有模块篡改了系统调用表。检查已加载的内核模块:
lsmod | sort
重点关注第三列“Used by”为0的模块,以及来自非标准路径的模块。用modinfo查看模块详细信息:
modinfo 模块名
如果模块没有签名(signature)信息,且路径可疑,需要立即深入排查。另一个硬核技巧是检查/proc/modules与sysfs中模块列表的差异,部分高级Rootkit能隐藏自身在proc中的条目,但在sysfs中会留下痕迹。同时,定期检查内核日志中是否有“tainted”标记:
cat /proc/sys/kernel/tainted
非0值表示内核被污染,可能是加载了非开源模块或发生了严重错误,需要结合dmesg输出分析具体原因。
包完整性校验与供应链安全巡检很多管理员只做“apt upgrade”,却从不验证已安装包的完整性。Debian系提供了强大的debsums工具来校验包文件的MD5值:
apt install debsums -y debsums -c 2>&1 | grep -v "OK$"
输出中任何FAILED或REPLACED的文件都值得高度警惕,说明二进制文件可能被替换。特别是/bin、/sbin、/usr/bin下的核心工具,如果被篡改,所有操作都不可信。对于未使用debsums的包,可以用dpkg -V命令验证:
dpkg -V 包名
输出中,每个字段代表不同的校验项,比如“5”表示MD5校验和不匹配,“M”表示权限或文件类型改变。如果发现/lib/libc.so.6这类核心库被修改,系统可能已被深度控制。此外,要建立软件源白名单机制,检查/etc/apt/sources.list和/etc/apt/sources.list.d/目录,确保没有第三方未签名源混入,供应链攻击常通过篡改软件源植入恶意包。
日志审计的自动化与关键事件提取手动翻看/var/log/auth.log效率太低。应该建立关键事件正则表达式库,用journalctl或awk批量提取。例如,快速统计暴力破解尝试的IP地址:
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -20
对于使用systemd-journald的系统,用journalctl更高效:
journalctl -u sshd --since "2 days ago" | grep "Failed"
除了SSH,还要关注sudo失败记录,这可能是内部提权尝试:
grep "sudo.*COMMAND" /var/log/auth.log | grep -v "root"
这条命令能找出非root用户执行sudo的记录,重点排查在非工作时间出现的sudo操作。对于日志被清除的风险,检查/var/log目录下各文件的最后修改时间,如果auth.log的修改时间与系统最后启动时间不符,说明可能被轮转或清除过。同时,配置auditd守护进程监控关键文件访问,比如对/etc/shadow的读取行为:
auditctl -w /etc/shadow -p r -k shadow_read
然后用ausearch -k shadow_read查看审计记录,能捕捉到试图读取密码文件的进程。
资源基线偏离与隐蔽挖矿进程发现挖矿木马现在越来越智能,会主动检测系统负载,只在空闲时启动,避开top命令的排查。因此,巡检不能只看瞬时CPU,要对比历史基线。安装sysstat后,用sar命令回溯过去几天的CPU使用模式:
sar -u -f /var/log/sysstat/sa日期
如果发现每天固定时段CPU有规律性尖峰,但当时并无计划任务,就需要深入排查。更隐蔽的检测方法是查看进程的运行时间和累计CPU时间。用ps查看进程的etime(运行时长)和time(累计CPU时间):
ps -eo pid,user,comm,etime,time --sort=-time | head -20
如果一个进程运行时间很短,但累计CPU时间异常高,说明它在短时间内消耗了大量计算资源,高度疑似挖矿。同时检查/proc/PID/exe指向的可执行文件路径,如果指向/tmp或/dev/shm等可写目录,基本可以判定为恶意进程。对于GPU服务器,还要用nvidia-smi检查GPU利用率,部分挖矿程序专门针对GPU。
文件系统权限与隐藏目录的周期扫描攻击者喜欢在文件系统深处创建以“.”或“..”开头的隐藏目录,或者利用空格和特殊字符混淆文件名。find命令是排查利器,但需要精细构造参数。扫描所有隐藏目录:
find / -type d -name ".*" -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null
更危险的是全局可写的目录,它们可能被用于植入恶意脚本:
find / -type d -perm -0002 -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null
对于SUID和SGID文件,它们是提权的常见跳板。用以下命令找出系统中所有SUID文件,并与已知基线对比:
find / -perm -4000 -type f 2>/dev/null
如果出现/bin/bash或/bin/dash具有SUID权限,说明系统已被严重入侵。同样,检查无属主文件,它们可能是攻击者删除账户后留下的文件:
find / -nouser -o -nogroup 2>/dev/null
这些文件应该被隔离审查或删除。
系统服务与启动项的完整性校验Systemd是Ubuntu的标准启动系统,攻击者会创建伪装成系统服务的恶意单元。检查所有已启用的服务:
systemctl list-unit-files --state=enabled
重点关注Type=simple且ExecStart指向/tmp或/home目录的服务。用systemctl cat服务名查看单元文件内容,确认执行路径和用户权限是否合理。同时,检查/etc/systemd/system/目录下是否有软链接指向可疑位置。对于传统的init.d脚本,检查/etc/init.d/和/etc/rc*.d/目录,用chkconfig或直接查看脚本内容,确保没有调用外部未知脚本。此外,/etc/profile、/etc/bash.bashrc以及各用户的.bashrc文件也是常被植入恶意环境变量的位置,需要定期用diff工具与备份版本对比差异。
自动化巡检脚本的工程化思路将上述检查点整合成脚本时,不要写成大而全的单文件,应该模块化设计。每个检查函数输出统一格式的JSON或CSV,便于后续集中分析。脚本开头必须加入环境锁定检查,确保脚本以只读权限运行,避免误操作。一个实用的框架是:先收集系统基础信息(主机名、内核版本、运行时间),然后依次执行账户检查、网络检查、文件系统检查、包完整性检查,最后生成报告并对比上次巡检结果,仅输出差异部分。这样能大幅降低运维人员的阅读负担。脚本中所有外部命令调用都应使用绝对路径,防止PATH环境变量被篡改导致执行了伪造的命令。
常态化巡检的本质不是依赖某一次深度扫描,而是通过高频次、低开销的自动化检查,建立起系统状态的连续视图。当异常发生时,你看到的不是孤立事件,而是与基线的偏离曲线,这才是从被动救火转向主动防御的关键一步。
