⑴ linux的audit.log日誌審計怎麼斷定被黑客入侵了
這里首先介紹來auditctl的自應用,具體使用指南查看man auditctl。auditctl的man 描述說明這個工具主要是用來控制audit系統行為,獲取audit系統狀態,添加或者刪除audit系統的規則。控制audit系統行為和獲取audit系統狀態參數:
-s 或者auditd 狀態 auditctl -s 顯示:AUDIT_STATUS: enabled=1 flag=1 pid=2792 rate_limit=0 backlog_limit=320 lost=0 backlog=0
⑵ 如何查看linux系統下的各種日誌文件 linux 系統日誌的分析大全
一般兩種類型日誌: 永久日誌rsyslog 臨時日誌system.journald
臨時日誌 查看journalctl -f 參數可追蹤實時日誌
永久日誌保存在/etc/log 目錄下,通過修改/etc/rsyslog.conf參數可定義不同日誌的輸出路徑
配置路徑格式: 設備名 . 優先順序 ; 例外 路徑
例如 *.info;mail.none;authpriv.none;cron.none /var/log/messages
表示的是 :所有日誌 優先順序在info以上包含info 除去mail authpriv cron的日誌保存在/var/log/messages中
常用日誌
message 系統信息日誌
sercue 安全審計日誌
Boot.log 系統啟動日誌
dmesg 硬體檢測日誌 (此日誌只能用dmesg命令查看)
yum.log 所有通過yum安裝的軟體的安裝日誌
wtmp 用戶登錄登出記錄 (用last查看)
查看日誌可用cat 或者 more 命令
⑶ linux日誌 audit
我們知道在Linux系統中有大量的日誌文件可以用於查看應用程序的各種信息,但是對於用戶的操作行為(如某用戶修改刪除了某文件)卻無法通過這些日誌文件來查看,如果我們想實現監管企業員工的操作行為就需要開啟審計功能,也就是audit。
1、首先執行以下命令開啟auditd服務
| 1 | service auditd start |
2、接著查看看auditd的服務狀態,有兩種方法可以實現,使用auditctl命令時主要看enabled是否為1,1為開啟,0為關閉
[root@ns-master-c01 ~]``# service auditd status` |
`auditd (pid 20594) is running...
[root@ns-master-c01 ~]``# auditctl -s
| 5 | AUDIT_STATUS: enabled=1 flag=1 pid=20594 rate_limit=0 backlog_limit=320 lost=0 backlog=0 |
3、開啟了autid服務後,所有的審計日誌會記錄在/var/log/audit/audit.log文件中,該文件記錄格式是每行以type開頭,其中紅框處是事件發生的時間(代表從1970年1月1日到現在過了多久,可以用date命令轉換格式),冒號後面的數字是事件ID,同一個事件ID是一樣的。
4、audit可以自定義對指定的文件或命令進行審計(如監視rm命令被執行、/etc/passwd文件內容被改變),只要配置好對應規則即可,配置規則可以通過命令行(臨時生效)或者編輯配置文件(永久生效)兩種方式來實現。
命令行語法(臨時生效****)****:
| 1 | auditctl -w /bin/``rm -p x -k removefile ``#-w指定所要監控的文件或命令 |
| 2 | #-p指定監控屬性,如x執行、w修改 |
| 3 | #-k是設置一個關鍵詞用於查詢 |
編輯配置文件(****永久生效)****:
auditd的配置文件為/etc/audit/audit下的auditd.conf 和audit.rules,auditd.conf 主要是定義了auditd服務日誌和性能等相關配置,audit.rules才是定義規則的文件,下面是一個例子,其實就是把auditctl的命令直接拿過來即可,auditctl里支持的選項都可以在這個文件里指定
修改完後重啟服務
| 1 | service auditd restart |
5、如果直接使用tailf等查看工具進行日誌分析會比較麻煩,好在audit已經提供了一個更好的事件查看工具—— ausea****rch, 使用auserach -h查看下該命令的用法:
這里列出幾個常用的選項:
-a number #只顯示事件ID為指定數字的日誌信息,如只顯示926事件:ausearch -a 926
-c commond #只顯示和指定命令有關的事件,如只顯示rm命令產生的事件:auserach -c rm
-i #顯示出的信息更清晰,如事件時間、相關用戶名都會直接顯示出來,而不再是數字形式
-k #顯示出和之前auditctl -k所定義的關鍵詞相匹配的事件信息
通過下圖可以看到每個事件被虛線分開,用戶名和執行的操作也都能清晰的看到了:
6、使用auditctl還可以查看和清空規則
查看源碼
<embed width="16" height="16" id="highlighter_638828_clipboard" type="application/x-shockwave-flash" title="復制到剪貼板" allowscriptaccess="always" wmode="transparent" flashvars="highlighterId=highlighter_638828" menu="false" src="http://www.linuxe.cn/content/plugins/et_highlighter51/scripts/clipboard.swf" style="margin: 0px; padding: 0px; outline: 0px; zoom: 1; max-width: 96%;">
摘自 http://www.linuxe.cn/post-255.html
| 1 | auditctl -l 查看定義的規則 |
| 2 | auditctl -D 清空定義的規則 |
⑷ Linux常見日誌統計分析命令
在上文中,我們已經詳細介紹 linux 三劍客的基本使用,接下來我們看看具體在性能測試領域的運用,本文主要介紹的是在 Tomcat 和 Nginx access日誌的統計分析。
server.xml 使用配置方式,%D-請求時間,%F-響應時間
欄位說明如下:
日誌樣例:
使用默認 combined 的經典格式上擴展 response_time&upstream_response_time
nginx.conf 使用配置方式:
欄位說明如下:
日誌示例:
為了能理解 AWK 程序,我們下面概述其基本知識。
模式( pattern ) 用於匹配輸入中的每行文本。對於匹配上的每行文本,awk 都執行對應的 動作( action )。模式和動作之間使用花括弧隔開。awk 順序掃描每一行文本,並使用 記錄分隔符(一般是換行符)將讀到的每一行作為 記錄,使用 域分隔符( 一般是空格符或製表符 ) 將一行文本分割為多個 域, 每個域分別可以使用 2, … 表示。1 表示第一個域,表示第二個域,n 表示第 n 個域。 $0 表示整個記錄。模式或動作都可以不指定,預設模式的情況下,將匹配所有行。預設動作的情況下,將執行動作 {print},即列印整個記錄。
此處使用Nginx access.log 舉例,Tomcat 日誌自己舉一反三。 使用 awk 分解出Nginx access日誌中的信息
以此類推…… 當我們使用默認的域分割符時,我們可以從日誌中解析出下面不同類型的信息:
我們不難發現,僅使用默認的域分隔符,不方便解析出請求行、引用頁和瀏覽器類型等其他信息,因為這些信息之中包含不確定個數的空格。 因此,我們需要把域分隔符修改為 「 ,就能夠輕松讀出這些信息。
注意:這里為了避免 Linux Shell 誤解 「 為字元串開始,我們使用了反斜杠,轉義了 「 。 現在,我們已經掌握了 awk 的基本知識,以及它是怎樣解析日誌的。
此處使用Nginx access.log 舉例,Tomcat 日誌自己舉一反三。
如果我們想知道那些類型的瀏覽器訪問過網站,並按出現的次數倒序排列,我可以使用下面的命令:
此命令行首先解析出瀏覽器域,然後使用管道將輸出作為第一個 sort 命令的輸入。第一個 sort 命令主要是為了方便 uniq 命令統計出不同瀏覽器出現的次數。最後一個 sort 命令將把之前的統計結果倒序排列並輸出。
我們可以使用下面的命令行,統計伺服器返回的狀態碼,發現系統可能存在的問題。
正常情況下,狀態碼 200 或 30x 應該是出現次數最多的。40x 一般表示客戶端訪問問題。50x 一般表示伺服器端問題。 下面是一些常見的狀態碼:
HTTP 協議狀態碼定義可以參閱: https://www.w3.org/Protocols/rfc2616/rfc2616.html
查找並顯示所有狀態碼為 404 的請求
統計所有狀態碼為 404 的請求
現在我們假設某個請求 ( 例如 : URI: /path/to/notfound ) 產生了大量的 404 錯誤,我們可以通過下面的命令找到這個請求是來自於哪一個引用頁,和來自於什麼瀏覽器。
有時候會發現其他網站出於某種原因,在他們的網站上使用保存在自己網站上的圖片。如果您想知道究竟是誰未經授權使用自己網站上的圖片,我們可以使用下面的命令:
注意:使用前,將 www.example.com 修改為自己網站的域名。
統計共有多少個不同的 IP 訪問:
統計每一個 IP 訪問了多少個頁面:
將每個 IP 訪問的頁面數進行從小到大排序:
統計 2018 年 8 月 31 日 14 時內有多少 IP 訪問 :
統計訪問最多的前十個 IP 地址
查看某一個 IP訪問了哪些頁面:
統計某個 IP 的詳細訪問情況,按訪問頻率排序
列出傳輸大小最大的幾個文件
列出輸出大於 204800 byte ( 200kb) 的頁面以及對應頁面發生次數
列出訪問最頻的頁面(TOP100)
列出訪問最頻的頁面([排除php頁面】(TOP100)
列出頁面訪問次數超過100次的頁面
列出最近1000條記錄,訪問量最高的頁面
統計每分鍾的請求數,top100的時間點(精確到分鍾)
統計每小時的請求數,top100的時間點(精確到小時)
統計每秒的請求數,top100的時間點(精確到秒)
統計當天的 pv
說明:
可以使用下面的命令統計出所有響應時間超過 3 秒的日誌記錄。
注意:NF 是當前記錄中域的個數。$NF 即最後一個域。
列出php頁面請求時間超過3秒的頁面,並統計其出現的次數,顯示前100條
列出相應時間超過 5 秒的請求,顯示前20條
統計蜘蛛抓取次數
統計蜘蛛抓取404的次數
通過本文的介紹,我相信同學們一定會發現 linux三劍客強大之處。在命令行中,它還能夠接受,和執行外部的 AWK 程序文件,可以對文本信息進行非常復雜的處理,可以說「只有想不到的,沒有它做不到的」。
⑸ 如何查看linux系統警告日誌
1、打開WDCP服務管理系統登錄界面,輸入用戶名和密碼,點擊登錄。
6、在操作日誌中,可以看到進行的操作,必要時可以找回誤刪的數據。
⑹ 4-9 Linux 中的日誌分析
日誌:系統、軟體 和 用戶操作交互信息的記錄文件。用於系統審核,日常故障快速定位和排錯。
日誌文件保存在 /var/log 和 /var/run 目錄下。在 RedHat 7 中,系統日誌消息由兩個服務負責處理,它們是 systemd-journald 和 rsyslogd。
日誌的保存時間系統默認是4周,可以通過 cat /etc/logrotate.conf 裡面的一項參數查到。rotate 可以修改。
主要日誌文件介紹:
/var/log/messages:系統日誌,主要記錄內核和公共消息。
/var/log/cron:計劃執行任務日誌。
/var/log/dmesg:系統引導日誌。
/var/log/maillog:郵件日誌。
/var/log/lastlog:用戶登錄日誌。(用 lastlog 命令)
/var/log/boot.log:系統啟動日誌。
/var/log/secure:安全和身份驗證日誌 。
/var/log/wtmp:記錄所有用戶登錄的詳細信息。(用 last 命令)
/var/log/btmp:記錄失敗的登錄記錄(用 lastb 命令)
/var/run/utmp:用戶登錄、注銷及系統開、關等事件。(用 w / who 命令)
(wtmp、btmp 和 utmp 是二進制文件,不能用cat、vi、tail、more這些命令打開查看)
1、/var/log/messages:系統日誌,主要記錄內核和公共消息。
1)、messages 信息項包括:事件發生的日期和時間、主機,終端名、進程 和 事件日誌。
2)、紅色下劃線:systemctl restart sshd 重啟 sshd 服務。
黃色下劃線:tail /var/log/messages 查看 messages 日誌。
藍色方框:messages 日誌已經可以查到重啟 sshd 服務的記錄。
綠色下劃線:每個動作都記錄得很清楚。暫停中(Stopping)、已暫停(Stopped)、啟動中(Starting) 和 已啟動(Started)
2、/var/log/cron:計劃執行任務日誌。
1)、cron 信息項包括:事件發生的日期和時間、主機,終端名、進程 和 事件日誌。
2)、cron 保存的是計劃任務的日誌,我們也可以通過特定輸出查看計劃進程的一些規律。從中也可以梳理一下計劃任務的概念。好像 run-parts(/etc/cron.hourly) 進程,基本都是從開機開始,整點 1 個小時就執行一次。一次由兩個事件為一組,一條 starting 0anacron ,另一條 finished 0anacron。
輸入 grep run-parts'('/etc/cron.hourly')' 的時候,()括弧需要用單引號引起來。
CROND進程,基本上也是從開機開始,整點 1 個小時就執行一次。
run-parts(/etc/cron.daily) 進程每天開機執行一次。一次由四個事件為一組,四個事件裡面有兩個事件是對應關系。starting man-db.cron 對應 finished man-db.cron,starting logrotate 對應 finished logrotate。
從 cron 日誌知道系統的計劃任務什麼時候觸發,執行了什麼事件,產生了什麼信息。
3、/var/log/dmesg:系統引導日誌,顯示硬體相關的信息。
head -20 dmesg | nl 列出開頭 20 行信息。
4、/var/log/maillog:郵件日誌。
紅色下劃線:tail maillog 查看 maillog 後 10 行信息。
黃色下劃線:starting the Postfix mail system 啟動 Postfix 郵件系統。daemon started 守護進程啟動完成。
maillog 記錄的信息都是和郵件有關。
5、/var/log/lastlog:記錄所有用戶登錄最後一次登錄本系統的時間信息。用 lastlog 讀取信息。lastlog 的幾列內容:Username(用戶名)、Port(埠)、From(登錄IP)、Latest(最後登錄時間)。
系統用戶是調用系統當中一些特殊服務的用戶,不能登錄系統(所以它們的登錄狀態都是顯示「**Never logged in**」從來沒有登錄)。能夠登錄系統的只有 root 和 新建的普通用戶。
6、/var/log/boot.log:系統啟動日誌。
head /var/log/boot.log 列出頭 10 條系統啟動的信息(內容較長,裡面記錄了多次啟動的信息)。
通過 3 次的重啟,查看 boot.log 大小。每重啟一次文件的容量就會增大。也證明了每次啟動都會往 boot.log 這個文件寫信息。
7、/var/log/secure:安全和身份驗證日誌 。
tail secure 列出 secure 文件最後 10 行信息。通過 secure 的信息可以發現記錄的是安全相關的信息,記錄最多的是哪些用戶登錄伺服器的相關日誌。
黃色下劃線:Failed password for root —— root 的密碼錯誤。
紅色下劃線:Accepted password for root —— 密碼正確,root 用戶接受的密碼。
綠色下劃線:pam_unix(sshd:session): session opened for user root —— 為 root 用戶建立會話。
8、/var/log/wtmp:記錄所有用戶登錄的詳細信息。一個二進制文件,不能用cat、vi、tail、more這些命令打開查看。用 last 命令查看。last 作用是顯示近期用戶或終端登錄的情況(包括:登錄、注銷及系統的啟動、停機的事件。因此隨著系統正常運行時間的增加,該文件的大小也會越來越大,)
last -n 10 —— -n 跟一個數字,指定顯示最近登錄的數據。(或者 last -10 一樣效果)
顯示的內容有六列:
第一列:用戶名。
第二列:終端位置。(pts/0 偽終端,SSH 或 telnet 等工具遠程連接的用戶,tty0 直接連接到計算機或本地連接的用戶,後面的數字代表連接編號)。
第三列:登錄 IP 或 內核。(如果是 0.0 或者 什麼都沒有,意味著用戶通過本地終端連接,除了啟動活動,內核版本會顯示在狀態中)。
第四列:開始時間。
第五列:結束時間。(still、login in 尚未推出,down 直到正常關機,crash 直到強制關機)。
第六列:持續時間。
9、/var/log/btmp:記錄失敗的登錄記錄,主要查看錯誤的登錄信息。一個二進制文件,不能用cat、vi、tail、more這些命令打開查看。用 lastb 命令查看。
lastb -n 10 —— -n 跟一個數字,指定顯示最近登錄的數據。(或者 lastb -10 一樣效果)
顯示的內容有六列:
第一列:用戶名。
第二列:終端位置。(連接失敗:notty)。
第三列:登錄 IP。
第四列:開始時間。
第五列:結束時間。
第六列:持續時間。
10、/var/run/utmp:用戶登錄、注銷及系統開、關等事件。一個二進制文件,不能用cat、vi、tail、more這些命令打開查看。用 w / who 命令查看。
w 命令:查看登錄者的信息及行為。
第一行:系統當前時間、系統沒有中斷持續性的運行時間、當前登錄用戶數、CPU在之前 1 分鍾、5分鍾、15分鍾的平均負載。
USER: 登錄用戶名。
TTY:登錄後系統分配的終端號。(tty:物理機本機終端、pts:遠程終端)
FROM:遠程主機名 IP。(tty 物理機本機不顯示、pts 遠程終端會顯示 IP)
LOGIN@ :登錄時間。
IDLE:用戶閑置時間 。這是個計時器,用戶執行任何操作,計時器就會被重置。(這里顯示的時間是距離上次命令操作後多久沒有進行操作的閑置時間)
JCPU:執行命令進程所消耗的總時間。 終端連接的所有進程佔用時間,包括當前正在運行作業佔用的時間。
PCPU:當前進程所消耗 CPU 的時間。
WHAT:用戶正在運行的進程 或 命令。(-bash 進程是終端進程)
who 命令:顯示關於當前在本地系統上的所有用戶信息。who 和 w 差不多,who 顯示的內容更為簡潔。who 命令顯示以下內容:登錄名、tty、登錄日期 和 時間。如果用戶是從遠程終端登錄的,那麼該終端的 IP 也會顯示出來。
11、whoami:顯示自己的登錄用戶。
⑺ Linux的audit.log日誌審計怎麼斷定被黑客入侵了
查看日誌啊,,你的伺服器時間登錄結束,,什麼時間你沒有操作,, 而上邊顯示有登錄了,,你懂得
⑻ Linux中與安全審計有關的函數
我的答案是最正確的 請採納我的內核審計系統的介面函數在Linux內核需要輸出審計信息時,它先調用函數audit_log_start創建緩沖區。接著,調用函數audit_log或audit_log_format寫緩沖區寫入審計信息,最後調用函數audit_log_end發送審計信息,並釋放緩沖區。這三個函數分別說明如下:1.函數audit_log_start 函數audit_log_start申請審計緩沖區,如果任務當前在系統調用中,系統調用被標識為可審計的,並在系統調用退出時,產生一條審計記錄。函數audit_log_start的參數ctx為審計上下文結構實例;參數gfp_mask為分配內存的類型,如:__GFP_WAIT表示可以等待和重調度;參數type為審計消息類型。如果緩存區申請成功,它返回審計緩沖區的指針,否則返回NULL表示錯誤。函數audit_log_start申請審計緩沖區,當審計緩沖區鏈表的緩沖區個數超過上限時,當前進程需要等待用戶空間的後台進程將審計消息寫入log文件,直到緩沖區個數小於上限值為止。函數audit_log_start在申請並初始化審計緩沖區後,給緩沖區加時間戳和審計記錄序列號。函數audit_log_start列出如下(在linux26/kernel/audit.c中)://聲明等待隊列頭,用於等待審計消息被後台進程寫入log文件static DECLARE_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 timespect;unsigned intserial;int reserve;unsigned long timeout_start = jiffies; //開始的時間if (!audit_initialized)//如果已初始化,就直接退出return NULL;if (unlikely(audit_filter_type(type)))return NULL;if (gfp_mask & __GFP_WAIT)reserve = 0;elsereserve = 5; /*允許調用者多出5個條目*/ //當鏈表中審計緩沖區數超出上限時,進程等待auditd處理鏈表中緩沖區while (audit_backlog_limit&& skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time && time_before(jiffies, timeout_start + audit_backlog_wait_time)) {/* 等待後台進程auditd從隊列中處理部分緩沖區 */DECLARE_WAITQUEUE(wait, current);set_current_state(TASK_INTERRUPTIBLE); //設置當前進程的狀態為可中斷等待狀態add_wait_queue(&audit_backlog_wait, &wait); //將當前進程加入等待隊列if (audit_backlog_limit && skb_queue_len(&audit_skb_queue) > audit_backlog_limit)schele_timeout(timeout_start + audit_backlog_wait_time - jiffies);//調度__set_current_state(TASK_RUNNING);//設置當前進程為運行狀態remove_wait_queue(&audit_backlog_wait, &wait);continue;} //檢查每秒發送的記錄數不能超過上限,以防止受非法攻擊if (audit_rate_check())printk(KERN_WARNING "audit: audit_backlog=%d > " "audit_backlog_limit=%d\n", 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);//申請審計緩沖區if (!ab) {audit_log_lost("out of memory in audit_log_start");return NULL;}//得到當前時間存入t,計算審計記錄的序列號,存入serialaudit_get_stamp(ab->ctx, &t, &serial); //將時間戳和序列號寫入審計記錄audit_log_format(ab, "audit(%lu.%03lu:%u): ", t.tv_sec, t.tv_nsec/1000000, serial);return ab;}函數audit_buffer_alloc申請審計緩沖區,先嘗試從空閑鏈表上取下一個緩沖區,如果空閑鏈表中沒有,就分配一個緩沖區。然後,填充netlink消息頭。該函數列出如下: 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; //從空閑鏈表中得到一個緩沖區spin_lock_irqsave(&audit_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);//釋放鎖 //如果空閑鏈表中沒有空閑緩沖區成員,就分配一個緩沖區if (!ab) {ab = kmalloc(sizeof(*ab), gfp_mask);if (!ab)goto err;}ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);//分配套接字緩沖區if (!ab->skb)goto err;ab->ctx = ctx;ab->gfp_mask = gfp_mask; //擴展套接字緩沖區skb的已使用數據區,將netlink消息頭數據nlmsghdr加到skbnlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));nlh->nlmsg_type = type;nlh->nlmsg_flags = 0;nlh->nlmsg_pid = 0;nlh->nlmsg_seq = 0;return ab;err:audit_buffer_free(ab);return NULL;}2.函數audit_log_format函數audit_log_format將一個審計消息按格式寫入審計緩沖區,參數ab為審計緩沖區,參數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, args);va_end(args);}函數audit_log_vformat將一個審計消息按格式寫入套接字緩沖區中,如果審計緩沖區沒有足夠的空間,就擴展套接字緩沖區的數據域。由於printk緩沖區為1024,擴展的套接字緩沖區最小應為1024。函數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;BUG_ON(!ab->skb);skb = ab->skb;avail = skb_tailroom(skb);//計算套接字緩沖區的空閑數據空間if (avail == 0) {//如果套接字緩沖區沒有空閑數據空間,擴展空間avail = audit_expand(ab, AUDIT_BUFSIZ);// AUDIT_BUFSIZ為1024,if (!avail)goto out;}va_(args2, args);len = vsnprintf(skb->tail, avail, fmt, args);//將信息寫入到緩沖區if (len >= avail) {//如果實際信息長度比可用的緩沖區大,擴展空間/* 由於printk緩沖區是1024,因此,擴展空間最少為1024 */avail = audit_expand(ab,max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail));if (!avail)goto out;len = vsnprintf(skb->tail, avail, fmt, args2); //將審計信息寫入到緩沖區}if (len > 0)skb_put(skb, len); //將寫入信息的數據緩沖區附加到skb上out:return;}
函數audit_expand擴展在審計緩沖區中的套接字緩沖區,擴展成功,返回可用的空間大小,擴展失敗返回0,表示沒有空間。參數ab表示審計緩沖區的指針,參數extra表示加到套接字緩沖區skb尾部的緩沖區空間大小。函數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 < 0) {audit_log_lost("out of memory in audit_expand");return 0;}return skb_tailroom(skb);//返回可用的緩沖區空間大小}3.函數audit_log_end當進程完成了將審計記錄寫入審計緩沖區的操作時,它調用函數audit_log_end將套接字緩沖區中的審計記錄數據發送給用戶空間後台進程,由後台進程寫入到log文件。如果審計後台進程存在,使用netlink機制傳輸數據,由審計後台將套接字緩沖區中的審計記錄數據寫入審計文件audit.log中;如果審計後台不存在,使用函數printk記錄數據,然後由日誌後台進程將數據寫入到日誌文件中。當數據發送完成後,函數audit_log_end喚醒等待隊列kauditd_wait。有些進程因為審計套接字緩沖區鏈表上的緩沖區數量超過上限而在隊列kauditd_wait等待,當其他進程發送了數據時,應喚醒這些等待進程。函數audit_log_end列出如下:void audit_log_end(struct audit_buffer *ab){if (!ab)return;if (!audit_rate_check()) {//檢查審計系統的傳輸速度,如果netlink機制傳輸速度超過上限,則返回錯誤audit_log_lost("rate limit exceeded");} else {if (audit_pid) {//如果審計後台的進程ID存在,使用netlink機制傳輸數據struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);skb_queue_tail(&audit_skb_queue, ab->skb);ab->skb = NULL;wake_up_interruptible(&kauditd_wait);//發送了數據,喚醒等待隊列} else {//使用printk記錄數據printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0));}}audit_buffer_free(ab);}