嵌入式Linux支持Audit審計

背景: 開發過程中發現自己的某個進程被莫名其妙的殺死了,概率性的,不好查。想知道是被哪個進程給誤殺了


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
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章