auditd不直接记录孤儿/僵尸进程,因其属内核正常状态转换,非需审计的安全事件;它仅捕获fork、exit、waitpid等显式系统调用,需通过监控异常kill、execve、exit_group及缺失waitpid等行为间接识别根源。

auditd 本身不直接记录“孤儿进程”或“僵尸进程”的产生事件,因为这两类进程是内核调度与进程生命周期管理的自然结果,不属于需审计的安全行为。但你可以通过监控触发它们产生的关键系统调用和权限变更,间接识别异常模式,从而定位潜在问题根源。
为什么 auditd 不直接记录孤儿/僵尸进程
孤儿进程(父进程先退出)和僵尸进程(子进程退出后父进程未回收)是 Linux 进程模型的正常状态,内核不会为此生成审计事件。auditd 只捕获显式系统调用(如 fork、exit、waitpid、kill)及其参数,而非内核内部状态转换。
监控关键系统调用以发现异常线索
真正值得关注的是导致异常孤儿/僵尸泛滥的上游行为,例如:父进程意外崩溃、服务未正确处理 SIGCHLD、恶意进程暴力终止其他进程等。以下规则可帮你捕获这些信号:
-
监控非预期的进程终止行为:
auditctl -a always,exit -F arch=b64 -S kill -F a1=9 -k sigkill_suspicious
记录所有发送SIGKILL (9)的调用,排查是否有人/脚本/守护进程在无故强杀进程(可能造成子进程变孤儿) -
跟踪高危 fork/exec 行为:
auditctl -a always,exit -F arch=b64 -S execve -F uid!=0 -F a0=*sh* -k shell_spawn_unpriv
捕获非 root 用户启动 shell 的行为,防止隐蔽子进程链绕过管控 -
检测异常 exit 调用(尤其来自服务进程):
auditctl -a always,exit -F arch=b64 -S exit_group -F pid=12345 -k app_exit_abnormal
若已知某关键服务 PID,可临时监控其退出,确认是否因崩溃导致子进程失管
结合日志分析识别僵尸/孤儿相关异常模式
audit.log 中不会出现 “zombie” 或 “orphan” 字样,但可通过以下方式关联线索:
- 用
ausearch -m SYSCALL -sc fork -ts today | grep -E "(pid=[0-9]+.*ppid=[0-9]+)"查看近期 fork 行为,再人工比对 ps 输出中是否存在大量 PPID=1 的进程(孤儿)或状态为Z的进程 - 过滤高频失败的 wait 系统调用:
ausearch -m SYSCALL -sc waitpid -sv no -i | awk '{print $1,$13}' | sort | uniq -c | sort -nr
若某用户反复调用waitpid但失败(success=no),说明其程序可能未正确处理子进程退出,易积累僵尸 - 关联
SIGCHLD处理缺失:虽然 auditd 不审计信号接收,但若发现某进程频繁exit_group却无对应waitpid成功记录,可推断其父进程未响应子进程终止通知
辅助验证:用标准工具确认真实状态
auditd 提供线索,最终仍需靠系统命令确认:
- 查僵尸进程:
ps aux | awk '$8 ~ /Z/ {print}' - 查孤儿进程:
ps -eo pid,ppid,state,comm | awk '$3=="S" && $2==1 {print}'(仅适用于被 init 收养的典型孤儿) - 查某进程的子进程树及状态:
ps --forest -o pid,ppid,stat,comm $(pgrep -f "your_service")
真正的问题往往不在“有没有孤儿/僵尸”,而在于“为什么父进程不回收”或“为什么父进程提前挂了”。auditd 的价值,在于帮你锁定那个没调用 waitpid 的服务、那个被莫名 kill -9 的守护进程,或那个偷偷 fork 出百个子进程又不管理的脚本。











