




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、Linux 安全體系分析與編程2.2 審計(jì)系統(tǒng)2.2 審計(jì)系統(tǒng)Linux提供了用來記錄系統(tǒng)安全信息的審計(jì)系統(tǒng),審計(jì)系統(tǒng)分為用戶空間和內(nèi)核空間審計(jì)系統(tǒng),用戶空間審計(jì)系統(tǒng)用來設(shè)置規(guī)則和審計(jì)系統(tǒng)狀態(tài)、將內(nèi)核審計(jì)系統(tǒng)傳來的審計(jì)消息寫入log文件。內(nèi)核審計(jì)系統(tǒng)用于產(chǎn)生和過濾內(nèi)核的各種審計(jì)消息。本節(jié)重點(diǎn)分析內(nèi)核審計(jì)系統(tǒng)產(chǎn)生和過濾審計(jì)消息的機(jī)制。 審計(jì)系統(tǒng)構(gòu)架審計(jì)系統(tǒng)提供了一種記錄系統(tǒng)安全信息的方法,為系統(tǒng)管理員在用戶違反系統(tǒng)安全法則時提供及時的警告信息。審計(jì)系統(tǒng)的審計(jì)信息包括:可被審計(jì)的事件名稱、事件狀態(tài)(成功或失敗)和安全信息等。審計(jì)系統(tǒng)可以將記錄系統(tǒng)內(nèi)部發(fā)生的事件的信息根據(jù)用戶的需求,提供不同的報(bào)表功
2、能,從而實(shí)現(xiàn)對系統(tǒng)信息的追蹤、審查、統(tǒng)計(jì)和報(bào)告等功能。Linux審計(jì)系統(tǒng)子系統(tǒng)之間通信如圖2-3所示。應(yīng)用程序auditctl用來設(shè)置審計(jì)消息過濾規(guī)則、查詢內(nèi)核審計(jì)系統(tǒng)狀態(tài)等,它通過netlink機(jī)制與內(nèi)核審計(jì)系統(tǒng)的socket線程進(jìn)行雙向通信。內(nèi)核其他線程的審計(jì)信息通過內(nèi)核審計(jì)API寫入套接字緩沖區(qū)隊(duì)列audit_skb_queue中,內(nèi)核線程kauditd通過netlink機(jī)制將審計(jì)消息定向發(fā)送給用戶空間的審計(jì)后臺auditd的主線程,auditd主線程再通過事件隊(duì)列將審計(jì)消息傳給審計(jì)后臺的寫log文件線程,由寫log文件線程將審計(jì)消息寫入log文件。另一方面,審計(jì)后臺還通過一個與套接字綁
3、定的管道將審計(jì)消息發(fā)送給dispatcher應(yīng)用程序。 用戶空間審計(jì)系統(tǒng)應(yīng)用程序在用戶空間,審計(jì)系統(tǒng)由auditd、audispd、auditctl、autrace、ausearch和aureport等應(yīng)用程序組成。審計(jì)后臺auditd應(yīng)用程序通過netlink機(jī)制從內(nèi)核中接收審計(jì)消息,然后,通過一個工作線程將審計(jì)消息寫入到審計(jì)日志文件中,其中,還有一部分消息通過消息分發(fā)后臺進(jìn)程dispatcher調(diào)用syslog寫入日志系統(tǒng)。下面分別說明這些應(yīng)用程序的功能。1審計(jì)后臺auditd在用戶空間,審計(jì)系統(tǒng)通過auditd后臺進(jìn)程接收內(nèi)核審計(jì)系統(tǒng)傳送來的審計(jì)信息,將信息寫入到/var/log/aud
4、it/audit.log 中,audit.log的路徑可在/etc/auditd.conf 中指定。圖2-3 Linux審計(jì)系統(tǒng)子系統(tǒng)之間通信當(dāng)auditd沒有運(yùn)行時,內(nèi)核將審計(jì)信息傳送給 syslog,這些消息通常保存在/var/log/messages文件中,可以用dmesg命令查看。如果要啟用內(nèi)核中的審計(jì)功能,必須在系統(tǒng)啟動時將audit=1傳遞給內(nèi)核。也可以在運(yùn)行時,使用下列命令來啟用內(nèi)核審計(jì)功能:auditctl -e 1審計(jì)系統(tǒng)后臺應(yīng)用程序auditd是Linux審計(jì)系統(tǒng)的用戶空間部件,它負(fù)責(zé)將審計(jì)記錄寫入到硬盤中。ausearch或aureport工具用來查看寫在文件中的審計(jì)記錄
5、,auditctl工具用來設(shè)置審計(jì)規(guī)則。系統(tǒng)啟動時,auditctl讀取/etc/audit.rules中的規(guī)則,審計(jì)后臺可以通過auditd.conf文件定制配置。運(yùn)行auditd后臺的命令如下:auditd -f 其中,選項(xiàng)-f表示讓auditctl在前臺運(yùn)行,以方便調(diào)試,消息可以直接輸出到stderr,而不是輸出到log系統(tǒng)。用于配置auditd后臺的文件說明如下:/etc/auditd.conf用于auditd后臺的配置文件。/etc/audit.rules啟動時裝載的審計(jì)規(guī)則。2auditctl工具auditctl控制行為、得到狀態(tài)、從內(nèi)核審計(jì)系統(tǒng)增加或刪除規(guī)則。命令格式如下:aud
6、itctl options工具auditctl的命令行選項(xiàng)(options)很多,例如:-e 0|1表示停止或啟動內(nèi)核審計(jì)功能;-a表示將規(guī)則追加到鏈表;-S表示系統(tǒng)調(diào)用號或名字;-F表示規(guī)則域。工具auditctl設(shè)置規(guī)則的樣例如下:/查看程序所有的系統(tǒng)調(diào)用auditctl -a entry,always -S all -F pid=1005/查看指定用戶打開的文件auditctl -a exit,always -S open -F auid=510/查看不成功的open系統(tǒng)調(diào)用auditctl -a exit,always -S open -F success!=0設(shè)置規(guī)則和顯示規(guī)則的命令
7、樣例列出如下:-$ auditctl -a entry,always -S all -F pid=1005-$ auditctl -lLIST_RULES: entry,always pid=1005 (0 x3ed) syscall=all工具auditctl的選項(xiàng)說明如表2-1所示。表2-1 工具auditctl的選項(xiàng)說明選 項(xiàng) 名選項(xiàng)的值說 明-b 設(shè)置內(nèi)核允許的緩沖區(qū)數(shù),默認(rèn)值為64-e 0|1關(guān)閉或啟動內(nèi)核審計(jì)系統(tǒng)-f 0.2設(shè)置失敗標(biāo)識0=silent 1=printk 2=panic,默認(rèn)值為1。設(shè)置內(nèi)核如何處理臨界錯誤,如:backlog限制超出、內(nèi)存錯誤等-h 幫助信息-i當(dāng)
8、從文件中讀取規(guī)則時忽略錯誤-l列出所有的規(guī)則,每行一條規(guī)則-k 設(shè)置審計(jì)規(guī)則上的過濾關(guān)鍵詞key,key是不超過32字節(jié)長的任意字符串,它能唯一鑒別由watch產(chǎn)生的審計(jì)記錄-m text僅由root用戶發(fā)送用戶空間消息到審計(jì)系統(tǒng)。為文件系統(tǒng)watch設(shè)置許可過濾器。r=read,w=write,x=execute,a=attribute change。這些許可不是文件的標(biāo)準(zhǔn)許可,而是系統(tǒng)調(diào)用使用的,read和write系統(tǒng)調(diào)用將忽略這種設(shè)置,否則它們將淹沒log-r 設(shè)置每秒傳輸?shù)南?shù)限制,默認(rèn)值為0,表示無限制-R 從file文件中讀取規(guī)則-s報(bào)告狀態(tài)-a 追加規(guī)則到l鏈表,a表示規(guī)則的
9、動作有效鏈表名ltask追加規(guī)則到每個任務(wù)鏈表AUDIT_FILTER_TASK 。域應(yīng)用任務(wù)創(chuàng)建時的uid、gid等entry追加規(guī)則到系統(tǒng)調(diào)用進(jìn)入鏈表AUDIT_FILTER_ENTRY,用于決定進(jìn)入到系統(tǒng)調(diào)用時是否創(chuàng)建審計(jì)事件exit追加規(guī)則到系統(tǒng)調(diào)用退出鏈表AUDIT_FILTER_EXIT 。用于決定退出系統(tǒng)調(diào)用時是否創(chuàng)建審計(jì)事件user追加規(guī)則到用戶消息過濾鏈表AUDIT_FILTER_USER ,內(nèi)核在轉(zhuǎn)播用戶空間產(chǎn)生的事件到審計(jì)后臺之前,用這個鏈表過濾這些事件。僅域?yàn)閡id、auid、gid和pid時有效exclude用于過濾不想看到的事件,對應(yīng)內(nèi)核消息過濾鏈表AUDIT_FI
10、LTER_TYPE 規(guī)則的有效動作anever不產(chǎn)生審計(jì)記錄always分配一個審計(jì)上下文,在系統(tǒng)調(diào)用退出時填充-A 添加規(guī)則到l鏈表頭,動作為a-d 從帶有a動作的l鏈表刪除規(guī)則-D刪除所有的規(guī)則和watch-S 系統(tǒng)調(diào)用名或號|all如果程序使用指定的系統(tǒng)調(diào)用,則它啟動一項(xiàng)審計(jì)記錄。如果給出域規(guī)則而沒有指定系統(tǒng)調(diào)用,它將默認(rèn)為所有系統(tǒng)調(diào)用續(xù)表 選 項(xiàng) 名選項(xiàng)的值說 明-F n=v | n!=v | nv | n=v創(chuàng)建一個規(guī)則域:名字、操作、值??梢詥蝹€命令行傳遞最多64個域。每個域必須啟動一個審計(jì)記錄??芍С?種操作:等于、不等于、小于、大于、小于或等于和大于或等于有效的規(guī)則域na0,
11、a1, a2, a3對應(yīng)系統(tǒng)調(diào)用的前4個參數(shù)。不支持字符串參數(shù)。常用于復(fù)合的套接字或IPC操作arch系統(tǒng)調(diào)用的CPU構(gòu)架auidaudit uid,是用戶注冊的最初的IDb32用于32位系統(tǒng)調(diào)用表的archb64用于64位系統(tǒng)調(diào)用表的archdevmajor主設(shè)備號(Device Major Number)devminor次設(shè)備號(Device Minor Number)egid有效組IDeuid有效用戶IDexit從一個系統(tǒng)調(diào)用退出時的值fsgid文件系統(tǒng)組IDgid組IDinode節(jié)點(diǎn)號key設(shè)置過濾關(guān)鍵字,與-k選項(xiàng)一樣msgtype用于匹配消息類型編號,僅用于排除(exclude)過
12、濾鏈表obj_user資源的SELinux用戶obj_role資源的SELinux角色obj_type資源的SELinux類型obj_lev_low資源的SELinux低級別obj_lev_high資源的SELinux高級別path監(jiān)視的文件的全路徑,僅用于exit鏈表pers操作系統(tǒng)(OS)個人特征序列號pid進(jìn)程IDppid父進(jìn)程IDsubj_user程序的SELinux用戶subj_role程序的SELinux角色subj_type程序的SELinux類型subj_sen程序的SELinux敏感度(Sensitivity)subj_clr程序的SELinux的間隔(Clearance)s
13、gid設(shè)置組IDsuccess如果退出值大于或等于0,這個值為true/yes,否則為false/no。當(dāng)寫規(guī)則時,用1表示true/yes,用0表示false/nosuid設(shè)置用戶ID(Set User ID)uid用戶ID(User ID)-w 為文件系統(tǒng)對象插入一個watch(監(jiān)視)。不支持匹配符-W 移去文件系統(tǒng)對象path上的watch3autraceautrace是一個程序,它將添加審計(jì)規(guī)則、類似于strace跟蹤一個進(jìn)程,審計(jì)信息的結(jié)果將記錄在審計(jì)log文件中。在目標(biāo)程序執(zhí)行的前后,它都將刪除審計(jì)規(guī)則。autrace用于模擬strace工具。語法列出如下:autrace prog
14、ram 一個使用sutrace程序的典型樣例列出如下:-$ auditd -$ autrace /bin/ls /tmpWaiting to execute: /bin/lsgconfd-rootvirtual-root.SReCx6Cleaning up.No rulesTrace complete. You can locate the records with ausearch -i -p 5722-$ vi /var/log/audit/audit.logtype=DAEMON_START msg=audit(1174214581.293:1962) auditd start, ver
15、=, format=raw, auid=4294967295 pid=5477 res=success, auditd pid=54type=CONFIG_CHANGE msg=audit(1174214581.514:38): audit_enabled=1 old=1 by auid=4294967295 subj=user_u:system_r:unconfined_t:s04ausearch工具ausearch用于查詢審計(jì)后臺的日志,它能基于不同搜索規(guī)則的事件查詢審計(jì)后臺日志。每個系統(tǒng)調(diào)用進(jìn)入內(nèi)核空間運(yùn)行時有個唯一的事件ID,系統(tǒng)調(diào)用在進(jìn)入內(nèi)核后的運(yùn)行過程的審計(jì)事件共享這個ID。內(nèi)核可
16、以添加各種審計(jì)記錄,例如:系統(tǒng)調(diào)用“open”的審計(jì)事件將引起內(nèi)核發(fā)送一個帶有文件名的PATH記錄。ausearch的語法列出如下:ausearch options 其中,options表示選項(xiàng)值,如:-a 、-f 等?;谟脩鬒D的搜索樣例列出如下:-$ ausearch -ui 4294967295time-Sun Mar 18 18:43:01 2007type=DAEMON_START msg=audit(1174214581.293:1962) auditd start, ver=, format=raw, auid=4294967295 pid=5477 res=success,
17、auditd pid=54time-Sun Mar 18 18:43:01 2007type=CONFIG_CHANGE msg=audit(1174214581.514:38): audit_enabled=1 old=1 by auid=4294967295 subj=user_u: system_r:unconfined_t:s05aureport工具aureport用于產(chǎn)生審計(jì)后臺日志的總結(jié)報(bào)告,語法列出如下:aureport options 其中,options表示選項(xiàng),如:-a報(bào)告所有的AVC(Access Vector Cache)消息;-c報(bào)告配置改變的消息;-e報(bào)告事件消息。
18、工具aureport運(yùn)行后結(jié)果列出如下:-$ aureportSummary Report=Range of time: 03/18/2007 18:43:01.293 - 03/18/2007 18:43:01.514Number of changes in configuration: 1Number of changes to accounts or groups: 0Number of logins: 0Number of failed logins: 0Number of users: 0Number of terminals: 0Number of host names: 0Num
19、ber of executables: 0Number of files: 0Number of avc denials: 0Number of failed syscalls: 0Number of anomaly events: 0Number of responses to anomaly events: 0Number of process IDs: 1Number of events: 26audispdaudispd是消息分發(fā)的后臺進(jìn)程,用于將auditd后臺發(fā)過來的一些消息通過syslog寫入日志系統(tǒng)。 內(nèi)核審計(jì)緩沖區(qū)管理機(jī)制內(nèi)核審計(jì)系統(tǒng)將審計(jì)消息寫入審計(jì)用的緩沖區(qū)(稱為審計(jì)緩沖
20、區(qū))。由于審計(jì)信息是通過netlink機(jī)制發(fā)往用戶空間后臺進(jìn)程的,因此,審計(jì)緩沖區(qū)包括了結(jié)構(gòu)sk_buff描述的套接字緩沖區(qū),套接字緩沖區(qū)用來存儲用于發(fā)送的審計(jì)消息記錄。審計(jì)緩沖區(qū)的結(jié)構(gòu)定義如下(在linux26/kernle/audit.c中):struct audit_buffer struct list_head list; struct sk_buff *skb; /*格式化的套接字緩沖區(qū),準(zhǔn)備用于發(fā)送審計(jì)消息 */ /*每個進(jìn)程的審計(jì)上下文,包括進(jìn)程的狀態(tài)、時間和uid等,與進(jìn)程上下文相關(guān),可以為空 */ struct audit_context *ctx; gfp_t gfp_ma
21、sk;/緩存區(qū)的標(biāo)識,如:_GFP_WAIT;審計(jì)套接字緩沖區(qū)組成鏈表,用于存入填充了審計(jì)消息的審計(jì)套接字緩沖區(qū)指針,鏈表定義如下(在linux26/kernle/audit.c中):static struct sk_buff_head audit_skb_queue;審計(jì)套接字緩沖區(qū)鏈表用于存入審計(jì)消息,當(dāng)鏈表中的緩沖區(qū)個數(shù)超過上限時,當(dāng)前進(jìn)程需要等待用戶空間的后臺進(jìn)程將審計(jì)消息寫入log文件,直到緩沖區(qū)個數(shù)小于上限值為止。內(nèi)核審計(jì)系統(tǒng)還使用空閑審計(jì)緩沖區(qū)鏈表audit_freelist 存放空閑的審計(jì)緩沖區(qū),存放的個數(shù)上限為AUDIT_MAXFREE。這樣,維持一定數(shù)據(jù)的空閑緩沖區(qū)數(shù),對于
22、頻繁操作的審計(jì)系統(tǒng)來說,可以減少緩沖區(qū)的分配與釋放次數(shù),提高系統(tǒng)性能。當(dāng)申請審計(jì)緩沖區(qū)時,系統(tǒng)先查看鏈表audit_freelist是否存在空閑的審計(jì)緩沖區(qū);如果存在,就從鏈表中取下一個返回給申請者。如果鏈表中沒有空閑審計(jì)緩沖區(qū),就分配一個審計(jì)緩沖區(qū)。當(dāng)調(diào)用函數(shù)audit_buffer_free釋放審計(jì)緩沖區(qū)時,先檢查空閑審計(jì)緩沖區(qū)鏈表audit_freelist的空閑審計(jì)緩沖區(qū)是否超過上限;如果沒有超過上限,就將審計(jì)緩沖區(qū)放入鏈表audit_freelist,留給以后使用。否則,釋放緩沖區(qū)。函數(shù)audit_buffer_free釋放審計(jì)緩沖區(qū)時,每次都釋放它包含的套接字緩沖區(qū)??臻e審計(jì)緩沖區(qū)
23、鏈表的定義列出如下:#define AUDIT_MAXFREE (2*NR_CPUS)static LIST_HEAD(audit_freelist); 審計(jì)事件分類審計(jì)系統(tǒng)的消息事件分為以下幾個部分:10001099用于審計(jì)系統(tǒng)的命令。11001199 用戶空間可信的應(yīng)用程序消息。12001299 審計(jì)后臺的內(nèi)部消息。13001399 審計(jì)事件消息。14001499 SELinux使用的消息。15001599 內(nèi)核LSPP事件。16001699 內(nèi)核加密(crypto)事件。17001799 內(nèi)核正常記錄。18001999 將來內(nèi)核使用(可能是整數(shù)標(biāo)簽和相關(guān)的事件)。2000 用于其他沒有分
24、類的內(nèi)核審計(jì)消息(假想)。20012099 未使用(內(nèi)核)。21002199 用戶空間正常記錄。22002299 用戶空間對正常記錄相應(yīng)的動作。23002399 用戶空間產(chǎn)生的LSPP事件。24002499 用戶空間加密事件。25002999 用戶空間將來使用(可能是整數(shù)標(biāo)簽和相應(yīng)的事件)。10001199是內(nèi)核和用戶空間雙向使用的,12001299和21002999是用戶空間專有的,13002099是內(nèi)核-用戶空間通信用的。審計(jì)事件的詳細(xì)定義在linux26/include/linux/audit.h中實(shí)現(xiàn),事件的定義在內(nèi)核和用戶空間的審計(jì)系統(tǒng)都是一致的。內(nèi)核審計(jì)系統(tǒng)根據(jù)審計(jì)事件執(zhí)行相應(yīng)的操
25、作或者完成相應(yīng)的審計(jì)消息過濾。 內(nèi)核審計(jì)系統(tǒng)的接口函數(shù)在Linux內(nèi)核需要輸出審計(jì)信息時,它先調(diào)用函數(shù)audit_log_start創(chuàng)建緩沖區(qū)。接著,調(diào)用函數(shù)audit_log或audit_log_format寫緩沖區(qū)寫入審計(jì)信息,最后調(diào)用函數(shù)audit_log_end發(fā)送審計(jì)信息,并釋放緩沖區(qū)。這三個函數(shù)分別說明如下:1函數(shù)audit_log_start 函數(shù)audit_log_start申請審計(jì)緩沖區(qū),如果任務(wù)當(dāng)前在系統(tǒng)調(diào)用中,系統(tǒng)調(diào)用被標(biāo)識為可審計(jì)的,并在系統(tǒng)調(diào)用退出時,產(chǎn)生一條審計(jì)記錄。函數(shù)audit_log_start的參數(shù)ctx為審計(jì)上下文結(jié)構(gòu)實(shí)例;參數(shù)gfp_mask為分配內(nèi)存的
26、類型,如:_GFP_WAIT表示可以等待和重調(diào)度;參數(shù)type為審計(jì)消息類型。如果緩存區(qū)申請成功,它返回審計(jì)緩沖區(qū)的指針,否則返回NULL表示錯誤。函數(shù)audit_log_start申請審計(jì)緩沖區(qū),當(dāng)審計(jì)緩沖區(qū)鏈表的緩沖區(qū)個數(shù)超過上限時,當(dāng)前進(jìn)程需要等待用戶空間的后臺進(jìn)程將審計(jì)消息寫入log文件,直到緩沖區(qū)個數(shù)小于上限值為止。函數(shù)audit_log_start在申請并初始化審計(jì)緩沖區(qū)后,給緩沖區(qū)加時間戳和審計(jì)記錄序列號。函數(shù)audit_log_start列出如下(在linux26/kernel/audit.c中):/聲明等待隊(duì)列頭,用于等待審計(jì)消息被后臺進(jìn)程寫入log文件static DECL
27、ARE_WAIT_QUEUE_HEAD(audit_backlog_wait);struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) struct audit_buffer *ab = NULL; struct timespec t; unsigned int serial; int reserve; unsigned long timeout_start = jiffies; /開始的時間 if (!audit_initialized)/如果已初始化,就直接退出 re
28、turn NULL; if (unlikely(audit_filter_type(type) return NULL; if (gfp_mask & _GFP_WAIT) reserve = 0; else reserve = 5; /*允許調(diào)用者多出5個條目*/ /當(dāng)鏈表中審計(jì)緩沖區(qū)數(shù)超出上限時,進(jìn)程等待auditd處理鏈表中緩沖區(qū) while (audit_backlog_limit & skb_queue_len(&audit_skb_queue) audit_backlog_limit + reserve) if (gfp_mask & _GFP_WAIT & audit_backl
29、og_wait_time & time_before(jiffies, timeout_start + audit_backlog_wait_time) /* 等待后臺進(jìn)程auditd從隊(duì)列中處理部分緩沖區(qū) */ DECLARE_WAITQUEUE(wait, current); set_current_state(TASK_INTERRUPTIBLE); /設(shè)置當(dāng)前進(jìn)程的狀態(tài)為可中斷等待狀態(tài) add_wait_queue(&audit_backlog_wait, &wait); /將當(dāng)前進(jìn)程加入等待隊(duì)列 if (audit_backlog_limit & skb_queue_len(&aud
30、it_skb_queue) audit_backlog_limit) schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies);/調(diào)度 _set_current_state(TASK_RUNNING);/設(shè)置當(dāng)前進(jìn)程為運(yùn)行狀態(tài) remove_wait_queue(&audit_backlog_wait, &wait); continue; /檢查每秒發(fā)送的記錄數(shù)不能超過上限,以防止受非法攻擊 if (audit_rate_check() printk(KERN_WARNING audit: audit_backlog
31、=%d audit_backlog_limit=%dn, skb_queue_len(&audit_skb_queue), audit_backlog_limit); audit_log_lost(backlog limit exceeded); audit_backlog_wait_time = audit_backlog_wait_overflow; wake_up(&audit_backlog_wait); return NULL; ab = audit_buffer_alloc(ctx, gfp_mask, type);/申請審計(jì)緩沖區(qū) if (!ab) audit_log_lost(
32、out of memory in audit_log_start); return NULL; /得到當(dāng)前時間存入t,計(jì)算審計(jì)記錄的序列號,存入serial audit_get_stamp(ab-ctx, &t, &serial); /將時間戳和序列號寫入審計(jì)記錄 audit_log_format(ab, audit(%lu.%03lu:%u): , t.tv_sec, t.tv_nsec/1000000, serial); return ab;函數(shù)audit_buffer_alloc申請審計(jì)緩沖區(qū),先嘗試從空閑鏈表上取下一個緩沖區(qū),如果空閑鏈表中沒有,就分配一個緩沖區(qū)。然后,填充netlin
33、k消息頭。該函數(shù)列出如下:static DEFINE_SPINLOCK(audit_freelist_lock);/定義自旋鎖,用于鎖住鏈表audit_freeliststatic struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, gfp_t gfp_mask, int type) unsigned long flags; struct audit_buffer *ab = NULL; struct nlmsghdr *nlh; /從空閑鏈表中得到一個緩沖區(qū) spin_lock_irqsave(&audit_
34、freelist_lock, flags);/加鎖 if (!list_empty(&audit_freelist) ab = list_entry(audit_freelist.next, struct audit_buffer, list); list_del(&ab-list); -audit_freelist_count; spin_unlock_irqrestore(&audit_freelist_lock, flags);/釋放鎖 /如果空閑鏈表中沒有空閑緩沖區(qū)成員,就分配一個緩沖區(qū) if (!ab) ab = kmalloc(sizeof(*ab), gfp_mask); if
35、(!ab) goto err; ab-skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);/分配套接字緩沖區(qū) if (!ab-skb) goto err; ab-ctx = ctx; ab-gfp_mask = gfp_mask; /擴(kuò)展套接字緩沖區(qū)skb的已使用數(shù)據(jù)區(qū),將netlink消息頭數(shù)據(jù)nlmsghdr加到skb nlh = (struct nlmsghdr *)skb_put(ab-skb, NLMSG_SPACE(0); nlh-nlmsg_type = type; nlh-nlmsg_flags = 0; nlh-nlmsg_pid = 0; nlh
36、-nlmsg_seq = 0; return ab;err: audit_buffer_free(ab); return NULL;2函數(shù)audit_log_format函數(shù)audit_log_format將一個審計(jì)消息按格式寫入審計(jì)緩沖區(qū),參數(shù)ab為審計(jì)緩沖區(qū),參數(shù)fmt為格式化的字符串。其列出如下:void audit_log_format(struct audit_buffer *ab, const char *fmt, .) va_list args; if (!ab) return; va_start(args, fmt); audit_log_vformat(ab, fmt, ar
37、gs); va_end(args);函數(shù)audit_log_vformat將一個審計(jì)消息按格式寫入套接字緩沖區(qū)中,如果審計(jì)緩沖區(qū)沒有足夠的空間,就擴(kuò)展套接字緩沖區(qū)的數(shù)據(jù)域。由于printk緩沖區(qū)為1024,擴(kuò)展的套接字緩沖區(qū)最小應(yīng)為1024。函數(shù)audit_log_vformat列出如下:static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args) int len, avail; struct sk_buff *skb; va_list args2; if (!ab) return;
38、BUG_ON(!ab-skb); skb = ab-skb; avail = skb_tailroom(skb);/計(jì)算套接字緩沖區(qū)的空閑數(shù)據(jù)空間 if (avail = 0) /如果套接字緩沖區(qū)沒有空閑數(shù)據(jù)空間,擴(kuò)展空間 avail = audit_expand(ab, AUDIT_BUFSIZ);/ AUDIT_BUFSIZ為1024, if (!avail) goto out; va_copy(args2, args); len = vsnprintf(skb-tail, avail, fmt, args);/將信息寫入到緩沖區(qū) if (len = avail) /如果實(shí)際信息長度比可用
39、的緩沖區(qū)大,擴(kuò)展空間 /* 由于printk緩沖區(qū)是1024,因此,擴(kuò)展空間最少為1024 */ avail = audit_expand(ab, max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail); if (!avail) goto out; len = vsnprintf(skb-tail, avail, fmt, args2);/將審計(jì)信息寫入到緩沖區(qū) if (len 0) skb_put(skb, len); /將寫入信息的數(shù)據(jù)緩沖區(qū)附加到skb上out: return;函數(shù)audit_expand擴(kuò)展在審計(jì)緩沖區(qū)中的套接字緩沖區(qū),擴(kuò)展成功,返回可用的
40、空間大小,擴(kuò)展失敗返回0,表示沒有空間。參數(shù)ab表示審計(jì)緩沖區(qū)的指針,參數(shù)extra表示加到套接字緩沖區(qū)skb尾部的緩沖區(qū)空間大小。函數(shù)audit_expand列出如下:static inline int audit_expand(struct audit_buffer *ab, int extra) struct sk_buff *skb = ab-skb; int ret = pskb_expand_head(skb, skb_headroom(skb), extra, ab-gfp_mask); if (ret skb-data; nlh-nlmsg_len = ab-skb-len -
41、 NLMSG_SPACE(0); skb_queue_tail(&audit_skb_queue, ab-skb); ab-skb = NULL; wake_up_interruptible(&kauditd_wait);/發(fā)送了數(shù)據(jù),喚醒等待隊(duì)列 else /使用printk記錄數(shù)據(jù) printk(KERN_NOTICE %sn, ab-skb-data + NLMSG_SPACE(0); audit_buffer_free(ab); 內(nèi)核審計(jì)系統(tǒng)初始化函數(shù)audit_init在系統(tǒng)啟動時初始化內(nèi)核審計(jì)系統(tǒng),它創(chuàng)建nelink機(jī)制套接字,注冊接收函數(shù),給SELinux注冊審計(jì)回調(diào)函數(shù),注冊文
42、件系統(tǒng)變化監(jiān)控機(jī)制的操作函數(shù)集。該函數(shù)列出如下:/* 基于節(jié)點(diǎn)規(guī)則的Hash表 */struct list_head audit_inode_hashAUDIT_INODE_BUCKETS;static int _init audit_init(void) int i; printk(KERN_INFO audit: initializing netlink socket (%s)n, audit_default ? enabled : disabled); /創(chuàng)建nelink機(jī)制套接字audit_sock,將函數(shù)audit_receive注冊作為netlink機(jī)制接收函數(shù) audit_soc
43、k = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive, THIS_MODULE); if (!audit_sock) audit_panic(cannot initialize netlink socket); else audit_sock-sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;/定義發(fā)送超時時間 skb_queue_head_init(&audit_skb_queue); /初始化 audit_initialized = 1; audit_enabled = audit_default; /*給S
44、ELinux注冊回調(diào)函數(shù),當(dāng)新的策略發(fā)生變化時,將觸發(fā)這個回調(diào)函數(shù)*/ selinux_audit_set_callback(&selinux_audit_rule_update); audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, initialized);#ifdef CONFIG_AUDITSYSCALL audit_ih = inotify_init(&audit_inotify_ops);/注冊文件系統(tǒng)變化監(jiān)控機(jī)制的操作函數(shù)集 if (IS_ERR(audit_ih) audit_panic(cannot initialize inotify han
45、dle);#endif for (i = 0; i sk_receive_queue); qlen; qlen-) skb = skb_dequeue(&sk-sk_receive_queue); audit_receive_skb(skb); kfree_skb(skb); mutex_unlock(&audit_cmd_mutex);函數(shù)audit_receive_skb從接收套接字緩沖skb取出消息,這些消息來自應(yīng)用程序auditctl。它調(diào)用函數(shù)audit_receive_msg處理每一條消息,并應(yīng)答確認(rèn)信號。該函數(shù)列出如下:static void audit_receive_skb(
46、struct sk_buff *skb) int err; struct nlmsghdr *nlh; u32 rlen; while (skb-len = NLMSG_SPACE(0) nlh = (struct nlmsghdr *)skb-data; if (nlh-nlmsg_len len nlmsg_len) return; rlen = NLMSG_ALIGN(nlh-nlmsg_len); /32位對齊的長度 if (rlen skb-len) rlen = skb-len; if (err = audit_receive_msg(skb, nlh) netlink_ack(s
47、kb, nlh, err);/應(yīng)答錯誤信號 else if (nlh-nlmsg_flags & NLM_F_ACK) netlink_ack(skb, nlh, 0);/應(yīng)答無錯誤的確認(rèn)信號 skb_pull(skb, rlen);/從skb開始刪除數(shù)據(jù) 函數(shù)audit_receive_msg處理每條接收的消息,當(dāng)?shù)谝淮谓邮盏接脩艨臻gauditctl的消息時,它創(chuàng)建專門用來發(fā)送審計(jì)消息的線程kauditd,用來發(fā)送內(nèi)核的審計(jì)消息。該函數(shù)列出如下:static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) u3
48、2 uid, pid, seq, sid; void *data; struct audit_status *status_get, status_set; int err; struct audit_buffer *ab; u16 msg_type = nlh-nlmsg_type; /得到消息類型 uid_t loginuid; /* 發(fā)送者注冊uid */ struct audit_sig_info *sig_data; char *ctx; u32 len; /檢查接收的消息類型是否正確 err = audit_netlink_ok(skb, msg_type); if (err) r
49、eturn err; /* 創(chuàng)建名為kauditd的內(nèi)核線程,用來將審計(jì)消息發(fā)送給審計(jì)后臺auditd*/ if (!kauditd_task) /創(chuàng)建線程并喚醒線程 kauditd_task = kthread_run(kauditd_thread, NULL, kauditd); if (IS_ERR(kauditd_task) err = PTR_ERR(kauditd_task); kauditd_task = NULL; return err; pid = NETLINK_CREDS(skb)-pid; uid = NETLINK_CREDS(skb)-uid; loginuid =
50、 NETLINK_CB(skb).loginuid; sid = NETLINK_CB(skb).sid; seq = nlh-nlmsg_seq; /消息序列號 data = NLMSG_DATA(nlh); switch (msg_type) /根據(jù)用戶空間的應(yīng)用程序auditctl發(fā)來的消息類型進(jìn)行處理 case AUDIT_GET:/得到內(nèi)核審計(jì)系統(tǒng)狀態(tài) status_set.enabled = audit_enabled; status_set.failure = audit_failure; status_set.pid = audit_pid; status_set.rate_l
51、imit = audit_rate_limit; status_set.backlog_limit = audit_backlog_limit; status_set.lost = atomic_read(&audit_lost); status_set.backlog = skb_queue_len(&audit_skb_queue); /分配并填充套接字緩沖區(qū),然后調(diào)用netlink機(jī)制函數(shù)netlink_unicast將應(yīng)答發(fā)給auditctl audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0, &status_set,
52、 sizeof(status_set); break; case AUDIT_SET:/開/關(guān)審計(jì)系統(tǒng)、設(shè)置狀態(tài) break; case AUDIT_USER: case AUDIT_FIRST_USER_MSG.AUDIT_LAST_USER_MSG:/過濾auditctl轉(zhuǎn)發(fā)的消息 case AUDIT_FIRST_USER_MSG2.AUDIT_LAST_USER_MSG2: if (!audit_enabled & msg_type != AUDIT_USER_AVC) return 0; err = audit_filter_user(&NETLINK_CB(skb), msg_ty
53、pe); if (err = 1) /如果auditctl轉(zhuǎn)發(fā)的消息滿足user規(guī)則鏈表上的規(guī)則,則返回轉(zhuǎn)發(fā)的消息 err = 0; ab = audit_log_start(NULL, GFP_KERNEL, msg_type); if (ab) audit_log_format(ab, user pid=%d uid=%u auid=%u, pid, uid, loginuid);/填充pid等 if (sid) if (selinux_sid_to_string(sid, &ctx, &len) audit_log_format(ab, ssid=%u, sid); /填充安全I(xiàn)D el
54、se audit_log_format(ab, subj=%s, ctx); /填充安全上下文 kfree(ctx); audit_log_format(ab, msg=%.1024s, (char *)data); /data是auditctl送來的消息 audit_set_pid(ab, pid); audit_log_end(ab); break; case AUDIT_ADD: case AUDIT_DEL: if (nlmsg_len(nlh) nlmsg_type, NETLINK_CB(skb).pid, uid, seq, data, nlmsg_len(nlh), login
55、uid, sid); break; case AUDIT_ADD_RULE:/增加系統(tǒng)調(diào)用過濾規(guī)則 case AUDIT_DEL_RULE: if (nlmsg_len(nlh) nlmsg_type, NETLINK_CB(skb).pid, uid, seq, data, nlmsg_len(nlh), loginuid, sid); break; case AUDIT_SIGNAL_INFO: /得到發(fā)送者的信號信息 break; default: err = -EINVAL; break; return err 0 ? err : 0;線程函數(shù)kauditd_thread是一個獨(dú)立線程
56、的運(yùn)行函數(shù)。它是內(nèi)核后臺線程,是一直在運(yùn)行的工作線程。它從審計(jì)套接字緩沖區(qū)鏈表上取下緩沖區(qū),通過netlink機(jī)制函數(shù)netlink_unicast將緩沖區(qū)發(fā)送給用戶空間的審計(jì)后臺。如果鏈表中沒有數(shù)據(jù),這個工作線程就進(jìn)入睡眠等待狀態(tài)。函數(shù)kauditd_thread列出如下:static int kauditd_thread(void *dummy) struct sk_buff *skb; while (!kthread_should_stop() skb = skb_dequeue(&audit_skb_queue);/從審計(jì)套接字緩沖區(qū)鏈表上取下緩沖區(qū)skb wake_up(&audit
57、_backlog_wait); /喚醒等待的進(jìn)程 if (skb) if (audit_pid) /如果用戶空間審計(jì)后臺存在,發(fā)送消息 int err = netlink_unicast(audit_sock, skb, audit_pid, 0); if (err data + NLMSG_SPACE(0); kfree_skb(skb);/釋放skb else /如果沒有需要發(fā)送的套接字緩沖區(qū),則將當(dāng)前進(jìn)程放入等待隊(duì)列進(jìn)行等待 DECLARE_WAITQUEUE(wait, current);/初始化等待隊(duì)列成員wait set_current_state(TASK_INTERRUPTIB
58、LE);/將當(dāng)前進(jìn)程設(shè)置為可中斷等待狀態(tài) add_wait_queue(&kauditd_wait, &wait);/加入等待隊(duì)列kauditd_wait if (!skb_queue_len(&audit_skb_queue) /如果隊(duì)列長度為0,即沒有成員,則進(jìn)入等待狀態(tài) try_to_freeze(); schedule();/調(diào)度 _set_current_state(TASK_RUNNING);/將當(dāng)前進(jìn)程設(shè)置為正在運(yùn)行狀態(tài) remove_wait_queue(&kauditd_wait, &wait);/從等待隊(duì)列kauditd_wait刪除成員wait return 0; 利用規(guī)
59、則鏈表進(jìn)行審計(jì)事件過濾1規(guī)則條目應(yīng)用程序auditctl用來設(shè)置審計(jì)規(guī)則,并將審計(jì)規(guī)則發(fā)送到內(nèi)核審計(jì)系統(tǒng),存放在內(nèi)核的規(guī)則鏈表上。一個規(guī)則設(shè)置的樣例列出如下:auditctl -a exit,always -S open -F auid=510規(guī)則條目audit_entry是規(guī)則鏈表的組成元素,它存儲規(guī)則的各種信息,其結(jié)構(gòu)列出如下(在linux26/kernel/auidt.h中):struct audit_entry struct list_head list; struct rcu_head rcu; struct audit_krule rule;/規(guī)則;結(jié)構(gòu)audit_krule表示一
60、條審計(jì)規(guī)則,其列出如下:struct audit_krule int vers_ops; u32 flags; /*加規(guī)則到鏈頭或鏈尾,如:AUDIT_FILTER_PREPEND*/ u32 listnr; /*規(guī)則鏈表標(biāo)識,如:AUDIT_FILTER_EXIT */ u32 action; /*操作域,為never或always,如:AUDIT_ALWAYS u32 maskAUDIT_BITMASK_SIZE; /*系統(tǒng)調(diào)用號計(jì)算成掩碼位,如:open系統(tǒng)調(diào)用*/ u32 buflen; /*鏈表規(guī)則上分配的緩沖區(qū)長度*/ u32 field_count; /*規(guī)則域數(shù)組的成員個數(shù)*/
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 回收包裝合同范本
- 二手電梯房出售合同范本
- 入城證申請合同范例
- 品牌西服采購合同范本
- 合租倉庫協(xié)議合同范本
- 二十四節(jié)氣文化內(nèi)涵與漢字文創(chuàng)衍生品的融合創(chuàng)新設(shè)計(jì)
- 2025至2030年中國純銅浴缸扶手?jǐn)?shù)據(jù)監(jiān)測研究報(bào)告
- 公司總監(jiān)合同范例
- 合同標(biāo)題寫著合同范本
- 買賣合同范本房子
- 2022年高考(全國甲卷)語文仿真模擬卷【含答案】
- 腸瘺治療PPT醫(yī)學(xué)課件(PPT 25頁)
- 員工轉(zhuǎn)正評價(jià)表
- 道路交通事故責(zé)任認(rèn)定行政復(fù)議申請書范例
- 鄭州大學(xué)圖書館平立剖面效果圖
- 高效液相含量測定計(jì)算公式
- 公安機(jī)關(guān)通用告知書模板
- 《小學(xué)數(shù)學(xué)課程與教學(xué)》教學(xué)大綱
- 《手機(jī)攝影》全套課件(完整版)
- 礦井無計(jì)劃停電停風(fēng)安全技術(shù)措施
- 標(biāo)前合作合同協(xié)議書范本
評論
0/150
提交評論