用户空间的审核系统

用户空间的审核系统

<linux系统自动化运维》

用户空间审核系统用于设置规则和审核系统状态、记录审核日志。用户空间审核系统由多个应用程序组成,应用程序auditd是负责接收来自内核的审核消息,然后通过一个工作线程将审核消息写入到审核日志文件中。另外,该应用程序还通过一个与套接字绑定的管道将审核消息发送给dispatcher应用程序。
1.审核规则管理命令
auditctl命令是用于对内核中的audit进行控制,包括获取audit的状态和增删规则等。该命令的语法格式如下。
auditctl [options]
auditctl命令常用的功能选项如下:
 -e [0|1]:停止或启动内核审核的功能;
 -a:将规则追加到链表;
 -w path:为文件系统对象 插入一个监视;
 -p:设置文件权限;
 -k key:设置审核规则上过滤关键词,关键词是唯一识别监控产生的审核记录,它是长度不超过32字节长的任意字符串;
 -D:删除所有的规则和监控;
 -s:报告状态;
以下是auditctl应用的例子说明。
(1)查看audit的运行状态
[[email protected] ~]# auditctl –s
enabled 1
flag 1
pid 22403
rate_limit 0
backlog_limit 320
lost 0
backlog 0
loginuid_immutable 0 unlocked
对于该命令输出的信息,可以通过enabled、flag、rate_limit等参数就可以知道audit的运行状态是否正常。其中,enabled的值为0或1时表示的是启用或禁用audit审核;flag是用于设置失败标记的等级,值为0、1或2时分别表示不输出日志,输出printk日志,大量输出日志信息。
(2)审核规则管理之调用监控
 要监控某个用户的调用时,可以使用auditctl命令添加一条audit规则,如要记录cent6用户对open的系统调用(设该用户的UID为501)。
[[email protected] ~]# auditctl -a exit,always -S open -F auid=501
命令行的open表示要查看某一指定用户打开的文件,那么在该UID的用户登录系统并执行如ls命令时就被记录到审核日志中。
 查看程序所有的系统调用。
[[email protected] ~]# auditctl -a entry,always -S all -F pid=1005
 查看不成功的open系统调用。
[[email protected] ~]# auditctl -a exit,always -S open -F success!=0
(3)审核规则管理之动作监控
查看指定用户打开的文件(设该用户的UID为502)。
[[email protected] ~]# auditctl -a exit,always -S open -F auid=502
(4)删除审核规则
如果要删除以上的审核规则,可以执行带有-d选项的auditctl命令行。如果不想看到用户登陆类型的消息,可以添加规则如下的审核规则。
[[email protected] ~]# auditctl -a exclude,always -F msgtype=USER_LOGIN
补充说明:对于32位与64位系统而言,在添加规则是会有所不同,因此在64位的系统中添加审核规则时需要多增arch=b64的参数。
[[email protected] [[email protected] ~]# auditctl -a exit,always -S open -F auid=504
WARNING - 32/64 bit syscall mismatch, you should specify an arch
[[email protected] [[email protected] ~]# auditctl -a exit,always -F arch=b64 -S open -F auid=504
第一条命令执行时是在32位=操作系统中的审核规则命令,放在64位的操作系统中执行就提示错误,通过在命令中添加“-F acrh=b64”的参数后再执行时就没有提示错误的信息,可通过以下的命令来确定命令是否成功执行。
[[email protected] [[email protected] ~]# auditctl -l
LIST_RULES: exit,always watch=/etc/passwd perm=rwxa
LIST_RULES: exit,always auid=502 (0x1f6) syscall=open
LIST_RULES: exit,always auid=504 (0x1f8) syscall=open
LIST_RULES: exit,always arch=3221225534 (0xc000003e) auid=504 (0x1f8) syscall=open
2.审核消息报表设置
开启系统的审核功能后,系统在运行一段时间后审核日志的内容就会在短时间内暴增,这就造成查看日志的难度。为了能在短时间内了解系统存在的安全问题,可以使用aureport命令来生成审核消息报表(以图形方式显示),通过报表就可以很明了地了解系统存在的安全问题。
(1)系统事件整体报告
由于出于安全的考虑,审核日志的读取权限只对root用户开放,而aureport命令是通过读取日志的数据来产生报表,因此在执行该命令时就需要来自root用户的权限,aureport的语法格式如下。
aureport [options]
auditctl命令常用的功能选项如下:
 -a:报告关于访问向量缓冲(access vector cache,AVC)的信息。
 -c:报告有关配置修改的信息。
 -f:报告关于文件的信息。
 -h:报告关于主机的信息。
 -l:报告关于登录系统的信息。
 -m:报告有关账号修改的信息。
 -p:报告进程的信息。
 -s:报告有关系统调用的信息。
要以图形的方式显示(用户空间的)审核系统中记录的事件,首先是需要一个脚本,并在系统中安装gnuplot这个工具(系统自带),脚本代码如下(脚本名称为mkbar)。
01 #!/bin/sh
02 #
03 if [ x"$1" != “x” ] ; then
04 OUT=“ KaTeX parse error: Expected 'EOF', got '#' at position 40: …udit" 07 fi 08 #̲ 09 EXT="png" 1…OUT.dat”
12 gpout=“ O U T . OUT. OUT.EXT”
13 plotcommand= which gnuplot
14 #
15 if [ x"$plotcommand" = “x” ] ; then
16 echo “gnuplot is not installed”
17 exit 1
18 fi
19 #
20 # create gnuplot command file
21 echo “set terminal $EXT small xfdf5e6 x000000 x404040 x0000ff x00ff00” > $gpcommand
22 echo “set grid ytics” >> $gpcommand
23 echo “set nokey” >> $gpcommand
24 echo “set nolabel” >> $gpcommand
25 echo “set data style lines” >> $gpcommand
26 echo “set noxzeroaxis” >> $gpcommand
27 echo “set noyzeroaxis” >> $gpcommand
28 echo “set boxwidth 0.9 relative” >> $gpcommand
29 echo “set style fill solid 1.0” >> g p c o m m a n d 30 e c h o ′ s e t o u t p u t " ′ gpcommand 30 echo 'set output "' gpcommand30echosetoutput"gpout’"’ >> $gpcommand
31 # This is to be able to start with a comma as we read input.
32 echo -n “set xtics rotate (”-1" -1" >> $gpcommand
33 #
34 # make sure we don’t append to pre-existing file
35 rm -f $gpdata
36 #
37 # read input
38 i=0
39 while [ 1 ]
40 do
41 read -t 5 line 2>/dev/null
42 if [ ? − n e 0 ] ; t h e n 43 b r e a k 44 f i 45 i f [ x " ? -ne 0 ] ; then 43 break 44 fi 45 if [ x" ?ne0];then43break44fi45if[x"line" != “x” ] ; then
46 i= expr $i + 1
47 echo $line | awk ‘/ 1/ { printf “, “%s” %d”, KaTeX parse error: Expected 'EOF', got '}' at position 10: 2, 1+num }̲' "num=i" >> $gpcommand
48 echo $line | awk ‘/ 2/ { printf “%d %s\n”, 1+num, KaTeX parse error: Expected 'EOF', got '}' at position 3: 1 }̲' "num=i" >> $gpdata
49 fi
50 done
51 echo -e ‘)\n’ >> g p c o m m a n d 52 e c h o ′ p l o t " ′ gpcommand 52 echo 'plot "' gpcommand52echoplot"gpdata’" with boxes’ >> $gpcommand
53 #
54 # Create the audit
55 gnuplot $gpcommand
56 #
57 # Cleanup
58 rm -f $gpcommand $gpdata
59 #
60 # output results
61 if [ -e $gpout ] ; then
62 echo “Wrote $gpout”
63 exit 0
64 fi
65 exit 1
建议将脚本放在/etc/audit/目录下并授予可执行权,然后执行aureport命令来生成整体事件的图形报告。其中,events是所产生的图形名称,如果执行命令时没有指定那么就以audit作为默认名称,文件以png为后缀。
[[email protected] ~]# aureport -e -i --summary | /etc/audit/mkbar events
Could not find/open font when opening font “arial”, using internal non-scalable font
Wrote events.png
命令执行后就会在当前的目录下(执行命令的目录)产生events.png这个文件,以图形工具打开给文件即可看到其中的内容,如图24-2所示。
用户空间的审核系统
图24-2 审核系统整体的事件报告图
如果要将所产生的图形文件指定在某个目录下并按时更新它的数据,这个可以做一个cron任务,并在任务中执行要执行该脚本的路径。
另外,如果只是想生成某个事件(如只生成登录事件报告),那么可以执行-l的aureport命令,如下。
[[email protected] ~]# aureport -l -i --summary | /etc/audit/mkbar login
Could not find/open font when opening font “arial”, using internal non-scalable font
Warning: empty x range [6:6], adjusting to [5.94:6.06]
Warning: empty y range [24:24], adjusting to [23.76:24.24]
Wrote login.png
之后就在当前的目录下生成一个login.png文件。如果是只想生成用户事件报告,那执行带有-u的aureport命令,如果是生成系统调用事件报告,则带-s选项。
(2)审核对象之间的关系
对于用户与系统调用之类不同的审核对象之间的关系,可以通过以下的脚本来了解,脚本代码如下示(设脚本名称为mkgraph)。
01 #!/bin/sh
02 #
03 if [ x"$1" != “x” ] ; then
04 OUT=“ 1 " 05 e l s e 06 O U T = " g r " 07 f i 08 D O T C M D = ‘ w h i c h d o t 2 > / d e v / n u l l ‘ 09 D O T F I L E = " . / 1" 05 else 06 OUT="gr" 07 fi 08 DOT_CMD=`which dot 2>/dev/null` 09 DOT_FILE="./ 1"05else06OUT="gr"07fi08DOTCMD=whichdot2>/dev/null09DOTFILE="./OUT.dot”
10 IDX_FILE="./ KaTeX parse error: Expected 'EOF', got '#' at position 15: OUT.index" 11 #̲ use png, ps, o…DOT_CMD" = “x” ] ; then
14 echo “graphviz is not installed. Exiting.”
15 exit 1
16 fi
17 echo “digraph G {” > $DOT_FILE
18 # Some options you may want to set
19
20 while [ 1 ]
21 do
22 read -t 5 line 2>/dev/null
23 if [ ? − n e 0 ] ; t h e n 24 b r e a k 25 f i 26 i f [ x " ? -ne 0 ] ; then 24 break 25 fi 26 if [ x" ?ne0];then24break25fi26if[x"line" != “x” ] ; then
27 echo $line | awk ‘{ printf("\t"%s" -> “%s”;\n", $1, $2); }’ >> $DOT_FILE
28 fi
29 done
30 echo “}” >> $DOT_FILE
31 echo " " >> $DOT_FILE
32 #
33 D O T C M D − T DOT_CMD -T DOTCMDTEXT -o ./ O U T . OUT. OUT.EXT $DOT_FILE 1>&2 2>/dev/null
34 if [ $? -ne 0 ] ; then
35 echo “Error rendering”
36 rm -f $DOT_FILE
37 exit 1
38 fi
39 rm -f D O T F I L E 40 i f [ " DOT_FILE 40 if [ " DOTFILE40if["EXT" = “ps” ] ; then
41 echo “Gzipping graph…”
42 rm -f ./ O U T . p s . g z 2 > / d e v / n u l l 43 g z i p − − b e s t . / OUT.ps.gz 2>/dev/null 43 gzip --best ./ OUT.ps.gz2>/dev/null43gzipbest./OUT.ps
44 echo “Graph was written to O U T . OUT. OUT.EXT.gz”
45 else
46 echo “Graph was written to O U T . OUT. OUT.EXT”
47 fi
48 exit 0
将脚本放在/etc/audit/目录下并授予可执行权,之后时就可以通过执行命令来获取审核对象之间的关系状态,如要获取users与executables的关系,可以执行以下的命令。
[[email protected] ~]# aureport -u -i | awk ‘/ 3/ { print $4" "$7 }’ | sort | uniq | /etc/audit/mkgraph users_vs_exec
由于mkgraph 是放在/etc/audit/目录下,而且它又不是命令,因此在执行它时就需要指定它的位置,否则在执行时系统就提示找不到mkgraph文件。
3.审核日志信息搜索
对于审核日志的查询,可以使用ausearch搜索审核记录,所搜索到的结果是以每个记录用虚线隔开,每段记录都有时间标记、执行者的UID、所执行的命令等信息。如通过ausearch命令搜索执行过的ls命令的记录。
[[email protected] ~]# ausearch -x ls

0 tty=pts1 ses=7 comm=“ls” exe="/bin/ls" key=(null)
time->Fri Aug 8 05:57:08 2014
type=PATH msg=audit(1407448628.762:286492): item=0 name="/usr/share/locale/en/LC_MESSAGES/coreutils.mo" inode=5497 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00
type=CWD msg=audit(1407448628.762:286492): cwd="/root"
type=SYSCALL msg=audit(1407448628.762:286492): arch=40000003 syscall=5 success=yes exit=3 a0=99fea78 a1=0 a2=99fec18 a3=99feab0 items=1 ppid=4659 pid=6596 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=7 comm=“ls” exe="/bin/ls" key=(null)

time->Fri Aug 8 05:57:08 2014
type=PATH msg=audit(1407448628.762:286493): item=0 name="/etc/localtime" inode=2123 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00
type=CWD msg=audit(1407448628.762:286493): cwd="/root"
type=SYSCALL msg=audit(1407448628.762:286493): arch=40000003 syscall=5 success=yes exit=3 a0=c72e71 a1=0 a2=1b6 a3=c71a0b items=1 ppid=4659 pid=6596 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=7 comm=“ls” exe="/bin/ls" key=(null)
24.3.3 内核空间的审核系统
审核系统以模块的方式连入操作系统的内核,然后对操作系统内核中发生的审核信息做进一步的处理后将这些信息传送到它特有的缓冲区,之后通过特定的通信机制与内核空间审核系统交互并把信息写入到特定的日志文件系统,而这过程中需要调用多种功能不同的函数来完成。
1.内核审核缓冲区机制
内核审核系统在获取审核信息后,它就将这些信息写入审核用的缓冲区(也称审核缓冲区)。由于审核信息是通过netlink机制发往用户空间审核系统的后台进程,因此审核缓冲区中就需要有sk_buff描述的套接字缓冲区和套接字缓冲区,并通过这两个缓冲区来存储被发送到用户空间审核系统的审核消息。
审核套接字缓冲区由组成链表,这些链表是用于存入填充审核消息的审核套接字缓冲区指针;当链表中的缓冲区个数超过上限时,当前进程就需要等待用户空间的后台进程将审核消息写入日志文件,直到缓冲区个数小于上限值为止。
内核审核系统还使用空闲审核缓冲区链表audit_freelist存放空闲的审核缓冲区,存放的个数上限由AUDIT_MAXFREE所设定,这样就可以维持一定数据的空闲缓冲区数,而对于频繁操作的审核系统来说,这样做可以减少缓冲区的分配与释放次数,从而提高系统性能。
对于审核系统缓冲区的申请,当有缓冲区需求申请时首先查看链表audit_freelist是否存在空闲的审核缓冲区,如果存在就从链表中取下一个返回给申请者,否则就再分配一个审核缓冲区。而对与缓冲区的释放,则是通过调用函数audit_buffer_free来释放,释放前首先检查空闲审核缓冲区链表audit_freelist的空闲审核缓冲区是否超过上限,如果未超过上限时就将审核缓冲区放入链表audit_freelist(留给以后使用),否则就释放缓冲区。
2.内核审核系统接口函数
在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参数:分配内存的类型;
 type参数:审核消息类型;
另外,如果缓冲区申请成功,它返回审核缓冲区的指针,否则返回NULL表示错误。
(2)audit_log_format函数
函数audit_log_format的作用是将一个审核消息按格式写入审核缓冲区。
(3)audit_log_end函数
当进程完成将审核记录写入审核缓冲区的操作后,调用函数audit_log_end就将套接字缓冲区中的审核记录数据发送给用户空间后台进程,再由后台进程写入到日志文件。
在用户空间审核系统中,如果后台进程存在时就使用netlink机制传输数据,并将套接字缓冲区中的审核记录数据写入审核日志文件audit.log中。如果审核后台进程不存在,那么就使用printk函数记录数据,然后再由日志后台进程将数据写入到日志文件中。另外,有些进程因审核套接字缓冲区链表上的缓冲区数量超过上限而在队列kauditd_wait等待,因此在数据发送完成后,audit_log_end函数就唤醒等待队列。


  1. 0-9 ↩︎

  2. 0-9 ↩︎

  3. 0-9 ↩︎