前提了解:
首先我们要了解的一点前提是, 在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
#include
#include
#include
#include
#include
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,那么我们只要建立一个, 本地通信的客户端,在那一直等待消息,就能获得审计信息了