背景: 開發過程中發現自己的某個進程被莫名其妙的殺死了,概率性的,不好查。想知道是被哪個進程給誤殺了
Linux kernel 版本: linux-3.18.20
audit 版本: audit-1.7.18
首先 Kernel 要支持 audit,要看 linux-3.18.20/kernel 目錄下有沒有 audit 相關的 .c 文件
audit.c
audit_tree.c
audit_watch.c
auditfilter.c
auditsc.c
有了這些文件就需要修改配置文件,讓它們被編譯進內核
參考 https://patchwork.kernel.org/patch/7800051/ 拉到網頁最後的補丁
發現這個補丁文件還是存在問題,因爲它沒有打開 HAVE_ARCH_AUDITSYSCALL 這一項,所以最後 AUDITSYSCALL 也沒被打開
直接用我如下這個補丁文件: enable_audit.patch
--- a/init/Kconfig 2019-09-20 09:13:06.856735962 +0800
+++ b/init/Kconfig 2019-09-23 17:38:40.490129265 +0800
@@ -317,16 +317,11 @@
auditing without CONFIG_AUDITSYSCALL.
config HAVE_ARCH_AUDITSYSCALL
- bool
+ bool "HAVE_ARCH_AUDITSYSCALL"
config AUDITSYSCALL
bool "Enable system-call auditing support"
depends on AUDIT && HAVE_ARCH_AUDITSYSCALL
- default y if SECURITY_SELINUX
- help
- Enable low-overhead system-call auditing infrastructure that
- can be used independently or with another kernel subsystem,
- such as SELinux.
config AUDIT_WATCH
def_bool y
cd linux-3.18.20
patch -p1 < ../enable_audit.patch
make menuconfig 裏面選中這3項
[*] Auditing support
[*] HAVE_ARCH_AUDITSYSCALL
[*] Enable system-call auditing support
檢查看看 .config 這幾個都是 y 就可以了
CONFIG_AUDIT=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_WATCH=y
CONFIG_AUDIT_TREE=y
編譯 kernel,燒寫 uImage 鏡像文件到開發板上
下載源碼包和補丁文件: audit-1.7.18.tar.gz + audit-1.7.18-cross.patch + audit-1.7.18-sys_stat_h.patch
http://repository.timesys.com/buildsources/a/audit/audit-1.7.18/
注意: audit-1.7.18-cross.patch 是交叉編譯所需的補丁文件,audit-1.7.18-sys_stat_h.patch 是解決編譯錯誤的補丁
解壓源碼包
tar -zxf audit-1.7.18.tar.gz
打補丁
cd audit-1.7.18
patch -p1 < ../audit-1.7.18-cross.patch
patch -p1 < ../audit-1.7.18-sys_stat_h.patch
配置
./configure CC=arm-hisiv600-linux-gcc --host=arm-hisiv600-linux --prefix=/home/admin/audit_out/
我的開發板是32位系統,所以這個地方需要設置一下(注意要加上大括號括起來)
audit-1.7.18/lib/libaudit.c audit_detect_machine() 函數裏面添加這句: strcpy(uts.machine, "i386");
int audit_detect_machine(void)
{
struct utsname uts;
if (uname(&uts) == 0) {
strcpy(uts.machine, "i386");
return audit_name_to_machine(uts.machine);
}
return -1;
}
編譯
make
生成可執行文件、庫文件、配置文件
make install
拷貝可執行文件到開發板的 /bin 和 /sbin 目錄
拷貝庫文件到開發板的 /lib 目錄
拷貝配置文件到開發板的 /etc 目錄
cp -rfp /home/admin/audit_out/sbin/* /sbin
cp -rfp /home/admin/audit_out/bin/* /bin
cp -rfp /home/admin/audit_out/lib/libaudit.so* /lib
cp -rfp /home/admin/audit_out/lib/libauparse.so* /lib
cp -rfp /home/admin/audit_out/etc/audit/ /etc
mkdir -p /var/log/audit
chown root /etc/audit/auditd.conf
chown root /sbin/audispd
chmod 0750 /sbin/audispd
reboot 開發板
-f 表示前臺運行,會有log打出,方便debug(等你解決bug之後可以把要把 -f 去掉,即變爲後臺運行 auditd)
auditd -f
注意: auditd 是後臺守護進程,負責監控記錄
可以看看 auditd 有沒有跑起來
ps | grep audit
400 root 0:00 auditd
403 root 0:00 [kauditd]
409 root 0:00 grep audit
這一句可以看到當前 auditd 的狀態,如果看到 enabled=1 則說明 auditd 已經跑起來了
auditctl -s
注意: auditctl 是配置規則的工具
加上這個規則後,再用 kill 殺死一個進程就可以看到是誰幹的了(我發現這裏必須得加 -k 給規則起個名字,才能成功添加規則)
auditctl -a exit,always -S kill -k my_monitor_kill
這一句可以查看當前存在的規則有哪些
auditctl -l
試驗
pkill -9 xxxx.bin
看看 /var/log/audit/audit.log 有沒有相應的 log 信息
type=SYSCALL msg=audit(231.260:3): arch=40000028 syscall=37 per=800000 success=yes exit=0 a0=10c a1=9 a2=9 a3=0 items=0 ppid=341 pid=547 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=ttyAMA0 ses=4294967295 comm="pkill" exe="/bin/busybox" key="my_monitor_kill"
type=OBJ_PID msg=audit(231.260:3): opid=268 oauid=-1 ouid=0 oses=-1 ocomm="xxxx.bin"
type=UNKNOWN[1327] msg=audit(231.260:3): proctitle=706B696C6C002D39006170705F68646D69
ppid=341 pid=547,表示是哪個 pid 發出的 pkill 命令
opid=268,表示是哪個 pid 被殺掉了
ps | grep 341
341 root 0:00 -sh
651 root 0:00 grep 341
可以看出 341 這個 pid 是 shell 進程,即命令行發出的 pkill 信號殺掉了 xxxx.bin