前提了解:
首先我們要了解的一點前提是, 在audit啓動的時候會到日誌分發做初始化,其中包括對/sbin/audispd的啓動(在配置文 件/etc/audit/auditd.conf中配置), 然後審計auditd會將產生的審計發送給audispd一份, 再接着,audispd可以根據自己的配置將審計信息發送給一個或多個程序,很明顯我們要想將auditd的審計發送給我們的程序,就要對audispd下手.
audispd配置介紹
從上面我們知道,要想讓auditd的審計信息發送給我們的程序,那麼我們需要看下audispd的配置是怎麼玩的
配置/etc/audisp/audispd.conf內容如下:
q_depth = 250
overflow_action = SYSLOG
priority_boost = 4
max_restarts = 10
name_format = HOSTNAME
#name = mydomain
plugin_dir = /etc/audisp/plugins.d/
其他的配置項先不管我們主要看下 plugin_dir這個配置項,這個指定了二級配置,關於插件的配置存放目錄,那麼這個插件配置就是我們要關心的,因爲在插件配置要配置我們的程序
插件配置目錄
我們先看看插件配置目錄/etc/audisp/plugins.d/中有什麼文件
ls /etc/audisp/plugins.d/
af_unix.conf mytset.conf syslog.conf
我們看到有三個文件,你可能會看到兩個文件因爲 mytset.conf是我自己寫的,用於啓動我的程序
插件配置內容
插件配置中有什麼信息呢? 我們先看看af_unix.conf
active = no //此插件是否激活 no 或者yes no表示不激活,yes表示激活, 要想你的程序收到審計信息,此處是要設置成yes
direction = out //表示我們是信息接受者,此處設置成out就可以
path = builtin_af_unix //表示你程序的路徑, 在這的builtin_af_unix表示的是audispd自己內部存在的,對於builtin_af_unix //會 建立一個af_unix本地通信的服務端
type = builtin //類型,值爲 builtin或者always, builtin表示自己內部已經存在, always你自己的程序一般可以設置成這個值
args = 0640 /var/run/audispd_events //傳給你程序的參數
format = string //輸出的格式 字符串方式輸出
寫我們自己的配置, 好了看了上面的af_unix.conf的配置,那麼我們自己寫個自己的配置,讓審計信息發送給我們的程序
cat /etc/audisp/plugins.d/mytset.conf
active = yes //激活我們的插件
direction = out
path = /yuan/test.sh //我們程序的路徑 此處爲了方便 我直接用腳本來寫的
type = always
args = hello
format = string
我們自己程序如何寫?
cat /yuan/test.sh
#!/bin/bash
while (( 1 ))
do
read name
echo "${name}" >> /yuan/1.txt
done
很簡單就這幾行, 啥意思呢, 首先read是從標準輸入中讀取數據,也就是從終端等待獲得數據,爲啥要這麼寫,看後面.
然後echo 一行,把從終端讀取的數據存放到了一個文件中
看着有沒有矇蔽, 不是要獲得審計信息碼,咋從終端讀取數據來了,別急,我們馬上揭祕此處的玄機
揭祕玄機
我們首先要了解,那就是這個test.sh腳本不是我們自己主動調用的而是audispd主動調用的, 在audispd創建了一個socke對,並將socket對的pair[0],重定向了標準輸入中,然後就創建了個子進程啓動了test.sh,很顯然,子進程繼承了父進程的socket對並且標準輸入變成了從socket對的pair[0],那麼test.sh中的 read 就是從socket對中的pari[0]中讀取數據, 在產生審計信息後, auditd將審計信息傳給了audispd, audispd又將審計信息寫入socket對的pair[1]中,然後test.sh就通過read從pair[0]中讀取了數據.
上面說了這麼多,無非就是採用了父進程子進程通信的技術(socket pair),讓父進程給子進程發送消息. 這樣大家應該不在蒙 蔽了把.
存在的問題
很顯然上面的這種方式,有個不好的點,就是我們的程序不是自己啓動的而是audispd啓動的,這讓人感覺有點不舒服啊,正常的是應該我們啓動自己的程序,然後我們做其他的事情,當有數據的時候你就傳給我, 那這怎麼辦呢,這得看接下來的另一個方法
利用af_unix.conf來讓我們自己啓動程序後接受信息
我們修改/etc/audisp/plugins.d/af_unix.conf 如下
active = yes //將此處的no改爲了yes 表示要啓動此功能
direction = out
path = builtin_af_unix
type = builtin
args = 0640 /var/run/audispd_events
format = string
當然你要重新啓動auditd
然後我們寫c程序如下
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
struct sockaddr_un server_addr;
char buff[1024]={0};
server_addr.sun_family = AF_UNIX;
//此處的路徑是配置中的路徑
strcpy(server_addr.sun_path, "/var/run/audispd_events");
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(sockfd < 0)
return -1;
//本地通信 連接audisp啓動的服務端
int result = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(result < 0)
{
close(sockfd);
return -1;
}
while(1)
{
memset(buff,0,1024);
if(read(sockfd,buff,1024) > 0)
{
printf("%s\n",buff);
}
}
return 0;
}
建立一個本地af_unix本地通信, 其實在 audispd中會根據 af_unix.conf建立一個本地通信的服務端, 路徑就是配置中的/var/run/audispd_events,那麼我們只要建立一個, 本地通信的客戶端,在那一直等待消息,就能獲得審計信息了