谁是linux SIGKILL的凶手---linux审计日志排障的杀手锏

一、背景描述

在我们的技术生涯中,总会碰到那精彩的一瞬间,哪怕是一瞬间,曾经的熟悉php内核的同事和今天碰到的排障瞬间,都是我技术生涯中那精彩的一瞬间,写一篇日志记录一下。

今天碰到一个问题,就是采集器的agent 总是被另一个进程在5分钟之后杀掉

具体现象

# sudo strace -p 6574
strace: Process 6574 attached
restart_syscall(<... resuming interrupted read ...>

过了一会收到SIGKILL 信号

# sudo strace -p 6574
strace: Process 6574 attached
restart_syscall(<... resuming interrupted read ...>) = ?
+++ killed by SIGKILL +++

那么我们现在面临的问题是如何找到发送SIGKILL的真凶。我们知道linux 信号里和其他信号还不一样,比如说SIGTERM 是可捕获的,SIGKILL 是不可捕获的,当进程收到信号的时候进程会被操作系统强制杀掉,这也给我排障带来了很大的障碍。

二、谁是SIGKILL真凶的搜查之旅

1)初步使用strace 排障

当出现这个问题的时候我们使用strace 进行排障

具体命令如下

$ sudo strace -p 7000 -e trace=signal

具体排查效果

strace: Process 7000 attached
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=6672, si_uid=1000} ---
+++ killed by SIGTERM +++

 我们发现使用strace 可以很成功的捕获SIGTERM这一类的可捕获信号,但是当我们捕获SIGKILL的时候

$ sudo strace -p 7220 -e trace=signal
strace: Process 7220 attached
+++ killed by SIGKILL +++

发现SIGKILL被捕捉不了

总结:

使用strace 只可以捕获客捕捉的信号,当我们使用不可捕捉信号的时候strace 就已经回天乏术了

2)查看linux 内核相关日志查找SIGKILL信息

去 /var/log/messages 和 journalctl 也没查到相关日志

3)开启linux信号跟踪,找到发送信号的进程号

# 进入目录
cd /sys/kernel/debug/tracing/

# 过滤SIGKILL
echo 'sig==9' > events/signal/signal_generate/filter 

# 开启过滤
echo '1' > events/signal/signal_generate/enable

# 开启tracing_on
echo '1' > tracing_on


我们可以查看tracing 目录下面trace 查看是谁发起的SIGKILL的信号

# tracer: nop
#
# entries-in-buffer/entries-written: 1/1   #P:16
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
            bash-6558    [008] d..1.  2476.431621: signal_generate: sig=9 errno=0 code=0 comm=sleep pid=8784 grp=1 res=0

我们发现是linux的6558 发出的SIGKILL 信号杀掉了8784。

但是重点来了,我们知道是6558调用 kill 命令发出SIGKILL信号,但是6558 是一个子进程,他被父进程使用后立马被回收了,我们如何定位到调用6558 的父进程呢?、

我想过使用BCC EBPF 去HOOK linux 内核的exec clone 一类的函数去追查真凶,但是用户的linux主机中并没有bcc,无法使用ebpf,这时候我较劲脑汁也无法查找出最后的根因,真的没办法了吗?

三、精彩的一瞬-----linux审计日志排障

当我不知所措的时候一个搞了20多年的内核程序员说,你为什么不打开审计日志呢?这精彩的一瞬在这一刻让我找到了问题的真凶。就像一局棋,这一笔就是画龙点睛的最后一步,他找到了最后的真凶。

我们可是梳理思路能不能从系统调用的execve 这一侧找到问题的根因呢?我们使用审计日志审查SIGKILL的发出者以及execve的使用者,双管齐下找到了最后的真凶。具体步骤如下:

1)提前安装审计日志程序

sudo apt install auditd

2)添加审计日志规则

定位ls 用了哪个系统调用

# strace ls
execve("/usr/bin/ls", ["ls"], 0x7ffcd8de3d10 /* 49 vars */) = 0
brk(NULL)                               = 0x55d7dade2000

我们使用进程的时候会调用execve,于是我们添加审计日志

vi /etc/audit/rules.d/audit.rules

-a exit,always -F arch=b64 -F a1=9 -S kill -k sigkill
-a exit,always -F arch=b32 -F a1=9 -S kill -k sigkill
-a exit,always -F arch=b64 -F a1=15 -S kill -k sigterm
-a exit,always -F arch=b32 -F a1=15 -S kill -k sigterm
-a exit,always -F arch=b64 -F a1=19 -S kill -k sigstop
-a exit,always -F arch=b32 -F a1=19 -S kill -k sigstop
-a always,exit -F arch=b64 -S execve -k exec
-a always,exit -F arch=b32 -S execve -k exec

-a exit,always:表示无论系统调用是否成功,都会记录事件。

-F arch=b32:指定CPU架构为32位系统。

-F a1=15:表示系统调用的第一个参数为15,即SIGTERM信号。

-S kill:表示监视kill系统调用。

-k sigterm:使用"sigterm"作为事件的键值。

修改完成规则后我们重启审计日志服务:

service auditd restart

3)查看审计日志

/var/log/audit/audit.log

我们用sleep 为例:

type=SYSCALL msg=audit(1704732268.057:196): arch=c000003e syscall=59 success=yes exit=0 a0=55e92bc5bc30 a1=55e92bc5f7c0 a2=55e92bc57110 a3=8 items=2 ppid=7356 pid=11663 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts2 ses=2 comm="sleep" exe="/usr/bin/sleep" subj=unconfined key="exec"ARCH=x86_64 SYSCALL=execve AUID="zhanglei" UID="root" GID="root" EUID="root" SUID="root" FSUID="root" EGID="root" SGID="root" FSGID="root"

最后通过审计日志我们一步步找到了kill 调用的父进程,最终找到了使用Kill 发送 SIGKILL的真凶

四、总结

在没有ebpf 的情况下,我们可以使用strace 找到相关系统调用,然后进一步使用审计日志,找到问题出现的根源,从而解决问题。

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、 实验目的 1、通过实验了解和熟悉Linux系统管理; 2、掌握用户和组管理命令; 3、掌握软件包安装命令和步骤; 4、掌握网络通信管理命令; 5、掌握进程管理命令; 6、掌握系统的服务管理命令; 7、掌握磁盘操作管理命令。 二、 开发工具和运行环境 1、虚拟机VMware 2、Linux操作系统 三、 实验内容 1、了解和熟悉Linux系统管理 2、用户和组管理命令 (1)帐户管理命令: useradd、 usermod、 passwd、userdel (2)组帐户管理命令: groupadd、 groupdel. gpasswd 3、软件包安装命令和步骤 (1) RPM 包的安装 安装RPM包的基本命令格式是: rpm -ivh (2) RPM 包的删除 删除RPM包的基本命令格式是: rpm -e (3) RPM 包的查询 rpm - qa (4) RPM 包的升级 升级RPM包的基本命令格式是: rpm -Uvh (5) RPM包的验证 验证RPM包的基本命令格式是: rpm -V [参数] (6)建立TAR包 有两种方式: -种是建立普通的TAR包,只打包,不压缩 tar cvf 另一种是打包并压缩,选项是“zcvf”,其中“z”代表使用“gzip” 程序 进行文件的压缩 tar zcvf (7)查询TAR包 在释放TAR包之前,查看TAR包中的文件内容。其格式如下: tar ztf (8)释放TAR包 它也分为解非压缩和压缩包两种方式,命令格式如下: tar zxvf 4、网络通信管理命令 (1)hostname命令:显示及设置主机名。 (2)ifconfig命令:显示当前活动的(或指定的)网卡设置。 其格式为: ifconfig [网卡设备名] 重新设置网卡的IP地址,-般由root用户进行设置。其格式为: Ifconfig 网卡设备名 IP 地址 (3) ping命令:网络测试命令 ping [-c报文数] 目的主机地址 (4)write命令:实时给其他用户发送消息 write username [tty] (5)wall命令:以广播方式向系统中的所有用户发送消息 wall message (6)mail 命令:双方用户不同时在线时,使用mai发送和接收消息 mail username mail -s topic username<filename 查看邮件使用mail命令,输入邮件编号以查看邮件 5、进程管理命令 (1)at命令:定时任务命令 (2)ps命令:进程查看命令 ps -ef ps -axu (3)free命令:显示系统内存的使用情况,包括内存总量、已经使用内存数量,空闲内存数量等信息。 (4) top命令:实时监控系统进程。 (5)sleep 命令:用于使进程延迟一段时间再执行。 其格式为: sleep time; command (6)kill命令:来杀死程序产生的进程来结束程序的运行。 格式1 : kill PID 格式2 : kill -9 PID “-9”为SIGKILL信号,属于强制结束 (7)前台与后台运行相关命令 command、command & 6、系统的服务管理命令 (1) runlevel 命令:显示系统当前和上一次的运行级别 (2) init 命令:转换服务的运行级别 init n (3)systemctl 命令:系统服务管理 查看系统服务启动状态。其格式: systemctl list-unit-files --type service 列出所有处于激活状态的服务。其格式为: systemctl list-units --type service --all 服务状态控制。其格式: systemctl [status/start/stop/ restart/reload] name.service 服务开机自启控制。其格式: systemctl [enable/di sable] name.service 7、磁盘操作管理命令 (1)查看系统磁盘分区情况命令: Fdisk -l (2)使用命令手工挂载 mount命令:查看所有挂载设备 mount [-t fs-type] [-o option] device mountpoint 例: mount /dev/cdrom /mnt/cdrom (注意,先要建立挂载目录,并保证设备存在) (3)卸载 umount [device] [dir]
SimIt-ARM-3.0 给予命令行ARM指令模拟器,短小精悍,是研究ARM处理器的好工具,该模拟器既可以运行用户级别的ELF程序,又可以模拟运行Linux操作系统;提供了简单易用的调试命令,可以逐条跟踪指令的执行。 SimIt-ARM-3.0-gk-20150902.tar.bz2 HowTo 0.what is SimIt-ARM-3.0 SimIt-ARM 3.0 is an instruction-set simulator that runs both system-level and user-level ARM programs, for more about it please read user's guide file. 1.how to build tar jxvf SimIt-ARM-3.0-gk-20150902.tar.bz2 cd SimIt-ARM-3.0-gk ./configure make make install After these steps, the ./build/bindirectory contains the following programs: ema An ARM interpreter. To test the installation was successful type ./build/bin/ema test/wc configure modifiy PATH environment variable: PATH=$PATH:$HOME/SimIt-ARM-3.0-gk/build/bin ; export PATH 2. how to use 2.1 run user-level ARM programs [root@ORA9 SimIt-ARM-3.0-gk]# cd gcc-asm [root@ORA9 gcc-asm]# more hello.c /* * hello.c * Tue Sep 8 10:13:40 CST 2015 */ int main() { printf("hello world\n"); __asm("mov r0,#2\n\t" "swi 0x1\n\t"); // syscall: exit(2); } [root@ORA9 gcc-asm]# arm-linux-gcc -v Reading specs from /usr/local/arm/3.4.1/bin/../lib/gcc/arm-linux/3.4.1/specs Configured with: /opt/crosstool/crosstool-0.28/build/arm-linux/gcc-3.4.1-glibc-2.3.2/gcc-3.4.1/configure --target=arm-linux --host=i686-host_pc-linux-gnu --prefix=/opt/crosstool/arm-linux/gcc-3.4.1-glibc-2.3.2 --with-float=soft --with-headers=/opt/crosstool/arm-linux/gcc-3.4.1-glibc-2.3.2/arm-linux/include --with-local-prefix=/opt/crosstool/arm-linux/gcc-3.4.1-glibc-2.3.2/arm-linux --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long Thread model: posix gcc version 3.4.1 [root@ORA9 gcc-asm]# arm-linux-gcc hello.c -o hello -static [root@ORA9 gcc-asm]# ls -l hello* -rwxr-xr-x 1 root root 520775 Sep 8 10:18 hello -rw-r--r-- 1 root root 160 Sep 8 10:15 hello.c [root@ORA9 gcc-asm]# file hello hello: ELF 32-bit LSB executable, ARM, vers

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值