十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Linux进程溯源实战:从ps到/proc,揪出陌生进程的来龙去脉

Linux进程溯源实战:从ps到/proc,揪出陌生进程的来龙去脉 排查线上服务器问题时最让人头疼的场景之一就是明明没有部署过相关服务ps 里却多了一个陌生进程或者 CPU 被打满top 一看是个名字非常可疑的进程但根本不知道它是被谁拉起来的、启动参数是什么、有没有做过坏事。这类问题如果靠肉眼一条条对 ps 输出效率很低而且容易漏掉关键线索。本文要聊的就是一套面向“进程溯源”的系统化排查方法同时引入 witr 这个辅助定位工具的思路帮助大家从进程的启动时间、父进程、工作目录、文件描述符、启动命令等维度像福尔摩斯破案一样把进程的来龙去脉一点点还原出来。文章会先从进程和守护进程的基础概念讲起再逐步展开常用的进程排查命令然后通过一个完整的实战案例演示“如何定位一个来源不明的进程”最后补充高频问题排查清单和工程实践建议。无论你是刚接触 Linux 的运维新人还是已经有几年经验的后端开发都能从里面找到可以直接落地的操作思路。1. 背景与核心概念1.1 什么是进程为什么需要管理它进程是程序运行时的最小执行单元。一个写好的二进制文件存放在磁盘上时它只是一堆静态的指令和数据当操作系统把它加载到内存中并分配 CPU、内存、文件描述符等资源后它才成为一个“进程”。同样一个程序可以被启动多次形成多个进程每个进程拥有独立的 PID进程标识符、独立的内存空间和独立的执行上下文。那为什么我们需要管理进程直接原因有三个。第一进程会消耗系统资源。CPU、内存、磁盘 IO、网络带宽都由进程占用一个失控的进程足以拖垮整台机器。常见的“服务器卡死”“内存溢出”“CPU 飙高”绝大多数情况都需要先定位到具体进程才能进一步分析。第二进程之间存在依赖和通信关系。一个后端服务可能依赖 Nginx、Redis、MySQL 等多个进程如果某个进程异常退出上下游都会受到影响。理解进程关系才能快速判断故障影响范围。第三进程是排查安全问题和异常活动的关键入口。服务器被植入挖矿程序、被反弹 Shell、被挂马最终都会体现为“多了一个陌生进程”。能不能从进程出发顺藤摸瓜找到启动源、可执行文件位置、网络连接目标直接决定了应急响应的效率。1.2 进程、线程、守护进程先分清概念很多初学者会把进程和线程混为一谈这里用一句话区分进程是操作系统分配资源的基本单位。线程是进程内部执行任务的基本单位。同一个进程下的多个线程共享该进程的内存空间和文件描述符。守护进程Daemon是长时间在后台运行、没有控制终端的进程常见的有 Nginx、sshd、mysqld 等。在排查问题时我们通常先定位“进程”再通过/proc/PID/task目录查看该进程下的线程信息。top命令默认显示进程级别的 CPU 和内存占用按H键可以切换到线程视图这是定位“进程总 CPU 不高但某个线程异常”的关键操作。1.3 witr 是什么一个进程溯源辅助思路witr 并不是 Linux 发行版自带的通用命令而是一个可以理解为“进程溯源排查工具集”的代号。在实际工程中它可以是团队内部封装的一组脚本集合也可以是一套排查流程的统称核心目标只有一个把“这个进程是从哪来的、为什么运行、它打算干什么”这三个问题变成一组可执行的排查步骤。本文后续会用witr作为辅助工具名来组织排查流程但不会依赖任何虚构的独家命令。所有核心操作都基于 Linux 系统自带的命令完成witr 的价值在于把零散命令编排成标准化的排查路径让新手也能按部就班地执行。1.4 进程排查的思维模型在动手执行命令之前建议先建立一套思维模型。进程溯源本质上是一次“从现象到根因”的推理我们可以把排查过程拆成六步发现异常进程通过 top、ps、pidstat 等命令找到嫌疑对象。确认进程身份查看 PID、PPID、用户、启动时间、启动命令。回溯启动来源通过父进程、systemd unit、启动脚本定位是谁拉起了它。收集行为证据查看打开的文件、网络连接、工作目录、环境变量。定位可执行文件通过 exe 软链接找到磁盘上的程序本体检查是否被篡改。处置与预防根据判断杀掉可疑进程、清理持久化配置、加固系统。这套模型同样适用于正常的服务进程排障。区别在于正常服务我们其实早就知道它是谁排查重点是“为什么表现异常”而对来源不明的进程前两步往往就能直接确定要不要继续深挖。2. 环境准备与版本说明进程排查是一门“命令实践型”技能操作系统环境越接近生产环境命令的输出越有参考价值。下面给出本文示例所使用的环境参考请根据实际情况调整。环境项说明操作系统CentOS 7.9 / Ubuntu 20.04 均可命令略有差异内核版本3.10 以上即可建议 4.x / 5.xShellBash 5.x 或 Zsh必要工具ps、top、lsof、ss、pidstat、strace、auditctl、systemctl权限要求普通用户可查看自身进程查看其他用户进程、安装工具需要 root 或 sudo安装缺失工具的方法Debian/Ubuntusudo apt update sudo apt install -y procps lsof strace sysstat auditdCentOS/RHEL 系统对应为sudo yum install -y procps-ng lsof strace sysstat audit如果生产环境不方便安装新工具优先使用系统自带命令。ps、top、ls -l /proc/PID这组组合拳在绝大多数 Linux 发行版上都可用本文的排查流程也尽量以系统自带能力为主。3. 核心排查命令与原理拆解排查进程来源本质上就是围绕 PID 展开信息收集。Linux 的/proc虚拟文件系统是核心信息源它以目录形式暴露了每个进程的运行时状态。下面拆解几个最常用的排查维度。3.1 ps基础信息入口ps是最基础的进程查看命令但如果只执行ps -ef信息量其实不够。建议使用带完整格式的选项ps -eo pid,ppid,user,start,etime,cmd参数说明pid进程 ID。ppid父进程 ID这是回溯启动来源的关键字段。user运行进程的用户很多可疑进程会以普通用户身份运行。start进程启动时间。etime进程已经运行了多长时间。cmd完整启动命令。如果怀疑某个进程被隐藏可以对比ps输出与/proc目录下的进程列表。正常情况下ps -eo pid显示的 PID 集合应该与/proc下的数字目录基本一致。3.2 pstree一眼看清父子关系pstree能直观展示进程之间的父子关系这在排查“谁启动了谁”时非常有用pstree -ap | grep -A 5 -B 5 PID比如输出结果中出现了systemd───bash───python3───sh───curl这样的链路说明该进程是被某个交互式 Shell 拉起的大概率与定时任务、手工执行或反弹 Shell 有关如果是systemd───nginx───nginx则说明是标准服务进程。3.3 /proc/ 每个进程都有一本“档案”/proc是 Linux 暴露内核和进程信息的虚拟文件系统。以 PID 为 1234 的进程为例以下文件值得重点关注文件或目录作用/proc/1234/cmdline完整的启动命令参数之间以\0分隔/proc/1234/cwd进程当前工作目录可执行文件所在位置的重要参考/proc/1234/exe指向进程实际可执行文件的软链接/proc/1234/environ进程启动时的环境变量/proc/1234/fd进程打开的所有文件描述符/proc/1234/net/tcp进程相关的 TCP 连接信息需要结合 inode 判断/proc/1234/status进程状态、PPID、内存、线程数等摘要查看 exe 软链接的方法ls -l /proc/1234/exe如果输出结果是(deleted)说明可执行文件已经被删除但进程仍在运行这是挖矿木马和临时脚本常用的“毁尸灭迹”手段也常出现在正常的软件升级场景中需要结合上下文判断。cmdline 的查看方法cat /proc/1234/cmdline | tr \0 echo使用tr把分隔参数的\0替换成空格可读性会好很多。3.4 lsof进程打开了什么当进程来源不明时查看它打开了哪些文件、哪些网络端口往往能获得决定性证据lsof -p 1234这条命令会列出进程 1234 的所有文件描述符包括普通文件、目录、socket、管道、字符设备等。重点关注.sh、.py、.pl结尾的脚本文件可能是进程正在执行的脚本内容。指向/tmp目录的路径很多恶意程序喜欢在/tmp下留痕。TCP类型的 socket结合网络连接 IP 判断通信对象。只查看网络连接lsof -i -P -n | grep 1234-i表示列出网络文件-P不解析端口名为服务名-n不解析 IP 为主机名输出速度更快且不会被 DNS 干扰。3.5 ss从网络连接反查进程如果可疑进程正在与外网通信ss可以直接看到连接与进程的对应关系ss -tnp | grep 1234或者只看 ESTABLISHED 状态的连接ss -tnp state established | grep 1234输出中的users:((python3,pid1234,fd3))直接告诉你进程号、进程名和文件描述符编号。如果看到大量连接到未知 IP 的 ESTABLISHED 连接且进程名明显与业务无关那基本可以判定为可疑活动。3.6 systemctl检查是否被注册为系统服务很多持久化后门会把自己注册成 systemd service这样即使进程被杀也会在重启后被重新拉起。排查时不能只看当前运行的进程还要检查服务配置systemctl list-units --typeservice --staterunning如果怀疑某个服务可疑查看它的 unit 文件systemctl cat service-name搜索新近创建或修改的 service 文件find /etc/systemd/system /usr/lib/systemd/system -name *.service -mtime -7 -type f 2/dev/null3.7 strace观察进程到底在做什么strace能跟踪进程的系统调用适合分析“一个行为可疑的进程在运行时到底做了什么”。示例strace -p 1234 -f -e tracefile,network,process -o /tmp/strace_1234.log-p指定要跟踪的 PID。-f同时跟踪子进程。-e tracefile,network,process只跟踪文件、网络、进程相关系统调用减少干扰。-o输出到日志文件。注意strace会对目标进程产生性能影响生产环境建议在流量低峰期使用或先采样几秒就退出。3.8 auditd记录谁执行了什么auditd 是 Linux 内核级审计组件可以用来监控命令执行、文件访问和系统调用。它不能追溯过去的操作但可以预防下一次“神不知鬼不觉”的进程启动。规则示例sudo auditctl -a always,exit -F archb64 -S execve -k EXEC_LOG这条规则会记录所有 64 位程序的execve调用即每次程序启动都会留下审计日志。查看日志sudo ausearch -k EXEC_LOG -ts recent在应急排查中auditd 的价值在于“事件发生后的取证”建议提前部署。4. 完整实战案例找出神秘进程的来龙去脉下面通过一个接近真实场景的案例把前面提到的命令串起来。场景设定如下。某台测试服务器突然出现 CPU 使用率飙升top显示有一个名为kworker_scan的进程占用了大量 CPU但运维同学确认没有部署过相关任务。按照本文的排查模型我们一步步来。4.1 第一步锁定嫌疑进程执行top查看 CPU 占用最高的进程top -b -n 1 | head -20预期输出关键行PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 2856 root 20 0 632372 55896 4892 S 185.3 1.2 15:23.33 kworker_scan记下 PID 为 2856。注意这里特意选择了一个伪装成内核线程名字的进程因为在真实故障中很多可疑进程会通过改名方式隐藏自己但在/proc目录下很难做到完全伪装。4.2 第二步查看进程身份使用增强版 ps 获取详细信息ps -eo pid,ppid,user,start,etime,cmd | grep -E PID|^ *2856输出示例PID PPID USER START ETIME CMD 2856 1 root 09:23 01:23:33 /tmp/.X11-unix/./scan --poolhttp://203.0.113.10:8080 --interval30看到几个关键信息PPID 是 1说明它的父进程已经退出进程被 systemd 或其他 init 进程收养。用户是 root说明可执行文件以最高权限运行。启动命令中有/tmp/.X11-unix/路径这个路径非常可疑。正常的 X11 目录不会存放可执行程序。连接了一个陌生的 HTTP 地址。此时基本可以判定为可疑进程。继续深入前先把当前 CPU 占用情况记录下来作为后续处置的对比基准。4.3 第三步回溯启动来源由于 PPID 是 1直接查父进程没有意义。此时需要另辟蹊径检查是否有定时任务、systemd 服务或启动脚本在背后做持久化。crontab -l -u root ls -l /etc/cron.d/ cat /var/spool/cron/root同时检查 rc.localcat /etc/rc.local再检查 systemd 服务中是否有可疑单元systemctl list-units --typeservice --staterunning | grep -i scan如果这些地方都没有可疑记录接下来就要通过可执行文件和运行行为入手。4.4 第四步查看可执行文件与环境查看进程的 exe 软链接和 cwd 目录ls -l /proc/2856/exe ls -l /proc/2856/cwd预期输出/proc/2856/exe - /tmp/.X11-unix/./scan (deleted) /proc/2856/cwd - /tmp看到(deleted)标记说明启动进程的二进制文件已经被删除。这个特征非常符合“临时落地、运行后自删”的恶意程序行为但也存在另一种可能某团队用脚本临时部署了任务脚本结束后自动清除了安装包。无论哪种情况都需要继续收集证据。再查看环境变量中是否有特殊内容cat /proc/2856/environ | tr \0 \n4.5 第五步检查打开的端口和网络连接查看进程监听的端口和已建立的连接lsof -p 2856 -i -P -n ss -tnp | grep 2856如果进程在向外发送数据ss会显示对应的远端 IP 和端口这一步对判断数据外传非常关键。同时查看它打开的其他文件ls -l /proc/2856/fd注意观察是否有写日志、写配置文件、读取密钥等文件操作线索。4.6 第六步导出完整证据链为了后续分析把关键信息汇总到文件中{ echo ps info ps -eo pid,ppid,user,start,etime,cmd | grep -E ^ *2856 echo exe and cwd ls -l /proc/2856/exe /proc/2856/cwd echo environ cat /proc/2856/environ | tr \0 \n echo network ss -tnp | grep 2856 echo lsof lsof -p 2856 } /tmp/process_evidence_2856.txt4.7 第七步动态跟踪进程行为在确认进程短期内不会退出后用 strace 跟踪几秒钟观察系统调用序列timeout 5 strace -p 2856 -f -e tracefile,network,process -o /tmp/strace_2856.log查看日志中的文件访问和网络连接行为grep -E connect|sendto|openat|execve /tmp/strace_2856.log常见的可疑行为包括反复连接固定 IP、读取/etc/passwd、执行curl或wget下载新文件等。4.8 第八步处置与清理处置前务必做好证据备份。如果这是在非生产环境测试服务器上完成的排查处置相对简单如果是在生产环境必须优先考虑业务连续性先隔离再处理。基本处置步骤备份证据文件。在防火墙或安全组中封禁可疑 IP。杀掉进程并确认没有子进程残留。清理持久化配置。修改可能被利用的账号密码。复查全盘是否存在同源文件。杀进程的命令kill 2856 sleep 2 ps -p 2856如果进程无法正常结束使用kill -9 2856但要注意强制杀进程可能导致它持有的资源无法正常释放。4.9 案例总结这个案例完整走了一遍“发现进程 → 确认身份 → 回溯来源 → 收集证据 → 动态分析 → 处置清理”的流程。核心收获在于不要被进程名字欺骗真正有价值的信息藏在/proc目录、网络连接和启动参数里。5. 常见问题与排查思路5.1 进程突然消失找不到 PID 怎么办有时候还没收集完信息可疑进程就自动退出了。这种情况说明进程可能是“一次性执行”类型或者有检测机制。处理思路立即查看审计日志或 bash history。用lsof L1查找被删除但仍打开的文件。检查是否有父进程等待重启子进程稍作等待再执行ps。提前部署 auditd记录 execve 事件。5.2 /proc 下可以看到目录但 ps 里没有进程这是一种常见的进程隐藏方式。ps默认只显示同用户或有权限的进程而且如果进程修改了 comm 字段看起来也会不一样。可执行文件被删除后ps会显示完整路径但标记为 deleted不要因此放弃排查。如果ps完全看不到但/proc有对应数字目录可以直接访问/proc/PID/cmdline和/proc/PID/exe获取线索。5.3 父进程是 1是不是就查不到了不是。PPID 为 1 只是说明父进程已经退出进程被 init 收养。此时要检查是谁通过 nohup、setsid 或 启动的。启动脚本是否已经被删除。是否注册了 systemd service。是否通过 at、cron、anacron 提交了任务。5.4 进程名字正常但行为异常很多业务进程也会出现 CPU 高、连接多的情况不能一律当成恶意进程。判断标准应该综合以下几点启动时间是否与业务发布窗口吻合。启动命令是否包含预期参数。工作目录和可执行文件路径是否规范。网络连接的目标 IP 是否属于已知供应商或业务对端。建议先比对发布系统和监控平台的记录再决定是否大动干戈。5.5 高频问题速查表问题现象常见原因排查命令解决思路CPU 占用高但进程名陌生可疑程序或异常脚本top、ps查看 /proc/PID/exe 和网络连接exe 显示 deleted程序启动后自删或更新替换ls -l /proc/PID/exe结合启动时间和业务发布记录判断进程杀掉后自动重启存在守护进程或定时任务systemctl list-units、crontab -l清理 service、cron、rc.local 等持久化手段端口被占用找不到进程权限不足或进程隐藏sudo lsof -i:port用 root 重试检查 /proc/net/tcp网络连接指向陌生 IP病毒回连或正常业务ss -tnp、lsof -i对比 IP 情报执行封禁和应急处置多个同名进程出现程序多实例启动ps -eo pid,ppid,cmd检查启动脚本中的死循环或调度入口6. 最佳实践与工程建议6.1 建立进程基线比“出了问题再排查”更有效的做法是在系统初始化完成后记录一份进程基线。ps -eo pid,ppid,user,start,etime,cmd /var/log/process_baseline_$(date %F).txt lsof -i -P -n /var/log/network_baseline_$(date %F).txt当后续出现可疑进程时直接与基线对比能快速筛选出新增项。这一步也可以配合监控系统定期快照并保存到集中日志平台。6.2 提前部署审计能力auditd 是投入成本低、排查收益高的组件。推荐至少开启以下审计规则sudo auditctl -a always,exit -F archb64 -S execve -k EXEC_LOG sudo auditctl -a always,exit -F archb32 -S execve -k EXEC_LOG sudo auditctl -w /etc/crontab -p wa -k CRON_LOG sudo auditctl -w /etc/systemd/system -p wa -k SYSTEMD_LOG这样每次命令执行、定时任务变更、systemd 配置变更都会留下记录。生产环境建议把 auditd 日志转发到远程日志服务器防止攻击者清除本地日志。6.3 统一服务部署规范很多“来源不明”的进程其实是同事手动部署的临时任务。规范化部署可以大幅降低排查成本所有正式服务必须通过 systemd 或容器编排管理禁止裸跑 nohup。临时任务必须登记负责人和过期时间。进程启动参数中尽可能携带可识别的标识例如-Dapp.namexxx。统一使用专用用户运行服务不要直接使用 root。脚本统一存放目录例如/opt/scripts禁止随意散落到/tmp。6.4 异常响应流程在应急预案中固定一套进程异常响应流程可以避免现场慌乱。推荐按以下顺序执行冻结现场不要立刻 kill先收集信息。收集证据ps、lsof、ss、/proc 信息、日志。隔离网络通过防火墙或安全组断网封禁可疑 IP。分析定性确认是业务进程还是恶意进程。清理处置杀进程、删文件、清配置。复盘加固检查账号、SSH 密钥、权限、补丁。6.5 权限与敏感操作提示涉及生产环境处置时必须强调几条原则排查操作优先选择只读命令避免对运行中的进程造成影响。杀进程前务必备份证据并与业务负责人确认影响。使用kill -9要谨慎它会让进程无法执行清理逻辑可能导致文件损坏或数据不一致。对可疑进程的二进制文件不要随便执行应该复制到隔离环境分析。涉及删除文件、封禁 IP、修改账号密码等操作必须在变更评审和授权范围内进行。7. 总结与学习路线本文围绕“找出进程从哪来的、为什么运行”这一核心目标介绍了从 ps、pstree 到 /proc 目录、lsof、ss、strace、auditd 的完整命令体系并通过一个模拟可疑进程的实战案例演示了标准排查流程的每一步。不管是排查 CPU 飙高、端口占用还是面对来源不明的新进程这套方法都适用。如果你刚开始接触进程管理建议按照下面的顺序继续学习第一步熟练掌握ps、top、pstree的输出字段含义能够看懂进程树。第二步熟悉/proc/PID目录下的关键文件理解内核如何暴露进程状态。第三步练习用lsof和ss建立“进程 ↔ 文件 ↔ 网络”的关联能力。第四步学习strace和auditd的常用参数掌握动态分析和事后取证能力。第五步把本文的案例在虚拟机或测试环境完整复现形成自己的排查模板。记住一个关键原则排查进程问题不要只看进程名真正的证据永远藏在启动命令、可执行文件路径、父进程关系、网络连接和行为轨迹里。把这些维度组合起来你就是进程管理的福尔摩斯。
返回列表