如何将linux audit产生的审计信息传入到其他程序中(利用audispd)

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

你可能感兴趣的:(audit)