image.png

简单的使用:
auditd
auditctl -R /etc/audit/rules.d/audit.rules
cat /var/log/audit/audit.log 就可以查看audit记录的信息

auditd对应的源码在:audit-2.7.1/src/auditd.c,其中audit-2.7.1/lib 对应着库的源码,简单的浏览一下源码就能知道auditd每个选项的作用和它的主要工作
-s指定启动时的audit工作状态,可选的状态有:startup_disable,startup_enable,startup_nochange,如果未指定,默认为
enum startup_state opt_startup = startup_enable;

auditctl对应的源码在:audit-2.7.1/src/auditctl.c,简单浏览一下源码就能知道auditctl每个选择的作用和程序的主要原理。
auditctl的工作流程大概如下:

int main(int argc, char *argv[])
{
if ((argc == 3) && (strcmp(argv[1], “-R”) == 0)) {
fd = audit_open();
if (is_ready(fd) == 0)
return 0;
fileopt(argv[2])
}
}

其中需要特别注意的是is_ready(),如果-R选项,也就是从文件中读取规则,则audit系统必须要先处于enable状态,is_ready()的实现如下:

static int is_ready(int fd)
{
if (audit_is_enabled(fd) == 2) { //规则不可改变
audit_msg(LOG_ERR, “The audit system is in immutable mode,”
“ no rule changes allowed”);
return 0;
} else if (errno == ECONNREFUSED) { //audit处于disable状态
audit_msg(LOG_ERR, “The audit system is disabled”);
return 0;
}
return 1;
}

接着上面的分析,fileopt()打开规则文件:

static int fileopt(const char file)
{
rc = open(file, O_RDONLY);
if (rc < 0) {
… //规则文件不存在,返回错误
}
… //接下来判读规则文件的访问权限,当前进程是否是root,*规则文件是否全局可写
,是否是常规文件
while (get_line(f, buf)) { //循环读取文件中的每一行
preprocess(buf);
ptr = audit_strsplit(buf); //去除行首的空白
if (ptr == NULL) //空行标志着规则文件的结束
break;
if (ptr[0] == ‘#’) { //#开头为注释,直接跳过,读取下一行
lineno++;
continue;
}
reset_vars();//复位变量,也就是说规则是以行为单位的,行之间无关联
rc = setopt(i, lineno, fields); //分析每一行的选项,分析的结果放在rule_new中
if (rc != -3) {
handle_request(rc);//如果规则没错,这执行存放在rule_new中的分析结果
}
lineno++;
}//while
}

需要说明的选项是:
-e: 0表示disable,1表示enable,2表示设置规则不可变
-f:当audit反应严重错误是应该采取的动作,0=silent啥都不干, 1=printk 打印错误,2=panic

配置文件详解
/etc/audit/auditd.conf存放在配置文件,决定auditd程序的行为,对其中一些重要的选项进行说明:

log_file
指定log文件存放的位置

max_log_file
指定单个log文件的最大大小,单位是Mbyte

max_log_file_action
当log文件达到max_log_file设定的大小时执行的动作,可选的动作 有:ignore/syslog/suspend/rotate, ignore表示忽略max_log_file设置的限制,继续写log文件,syslog表示会向syslog中写入一条warning,suspend表示auditd不再写log文件,但是auditd继续运行,rotate表示分多个log文件,一个log文件达到上限后在创建一个新的不同名字的log文件,后面会继续讲解该选项。

space_left
表示log_file 文件所在的分区空闲空间少于这个设定的值时,触发相应的动作,单位是Mbyte

space_left_action
指定space_left触发后执行的动作,可选的选项有:ignore/syslog/suspend/single/halt,前面三个选项与max_log_file_action相似,single表示audit进程会将系统模式变为单用户模式,halt表示audit进程将会触发系统关机
admin_space_left
系统管理员用户对于的空间,space_left讲的是普通用户
admin_space_left_action
与space_left_action类似,但是对于系统管理员
disk_full_action
磁盘满了之后应该采取的动作
disk_error_action
磁盘写错误之后应该采取的动作
flush
表示日志文件的刷新方式,可选的选项有:NONE、INCREMENTAL、DATA和SYNC,如果设置为NONE,则不需要做特殊努力来将数据刷新到日志文件中。如果设置为INCREMENTAL,则用freq选项的值确定多长时间发生一次向磁盘的刷新。如果设置为DATA,则审计数据和日志文件一直是同步的。如果设置为SYNC,则每次写到日志文件时,数据和元数据是同步的。
num_logs
表示保留日志文件的最大个数,只有在max_log_file_action=rotate时该选项该有意义,必须是0~99之间的数。如果设置为小于2,则不会循环日志。如果递增了日志文件的数目,就可能有必要递增/etc/audit/audit.rules中的内核backlog设置值,以便留出日志循环的时间。如果没有设置num_logs值,它就默认为0,意味着从来不循环日志文件。当达到指定文件容量后会循环日志文件,但是只会保存一定数目的老文件,这个数目由num_logs参数指定。老文件的文件名将为audit.log.N,其中 N是一个数字。这个数字越大,则文件越老。
规则文件详解
auditd服务的配置文件在/etc/audit/auditd.conf中,配置文件内容以及重要命令注释如下:

log_file定义了audit日志文件的存放路径

log_file = /var/log/audit/audit.log

log_format定义了log日志的储存方式,可选值有RAW和NOLOG,设置成RAW表示日志中存储的内容就是kernel产生的内容,如果设置成NOLOG,所有日志均不会写入磁盘

log_format = RAW

log_group = root

priority_boost = 4

flush = INCREMENTAL

freq这个值表示audit进程每隔20条会将记录下来的日志flush到日志文件中。这个值仅当flush属性设置为incremental时有效

freq = 20

log file的文件数量

num_logs = 5

disp_qos定义了dispatcher的缓冲区(128KB)满了的时候的处理方式,可选值:lossy/lossless,当选择lossy时,如果缓冲区已满,事件会被丢弃。如果选择lossless,则audit进程会等待缓冲队列中有空间时再写入事件

disp_qos = lossy

当audit进程启动时,会启动dispatcher进程,audit进程会将所有的事件发送到该进程的标准输入流(stdin)中

dispatcher = /sbin/audispd

name_format = NONE

max_log_file定义了单个日志文件的最大size,单位MB

max_log_file = 6

max_log_file_action定义了当系统检测到当前日志文件达到最大size时的处理方式,可选值:ignore/syslog/suspend/rotate,前三个选项见space_left_action,rotate表示文件转储,即将文件重命名(加一个数字后缀),然后生成一个空的新文件用于写入日志

max_log_file_action = ROTATE

定义额磁盘空间“快要”不足的阈值,单位MB

space_left = 75

space_left_action定义了当系统检测到磁盘空间“快要”不足的时候的处理方式,可选值:ignore/syslog/suspend/single/halt,ignore表示audit进程不做任何处理,syslog表示会向syslog中写入一条warning,suspend表示audit进程会停止向磁盘继续写入日志(进程会继续运行),single表示audit进程会将系统模式变为单用户模式,halt表示audit进程将会触发系统关机

space_left_action = SYSLOG

action_mail_acct = root

admin_space_left定义了磁盘剩余空间不足的阈值,单位MB,该值要小于space_left

admin_space_left = 50

admin_space_left_action定义了当系统检测到磁盘空间不足时的处理方式,可选值:ignore/syslog/suspend/single/halt,解释同上

admin_space_left_action = SUSPEND

disk_full_action定义了当写入日志时遇到磁盘满的情况的处理方式,可选值:ignore/syslog/suspend/single/halt,解释同上

disk_full_action = SUSPEND

disk_error_action定义了当遇到磁盘写错误的时候,audit进程应该如何处理,可选值:ignore/syslog/suspend/single/halt,解释同上

disk_error_action = SUSPEND

tcp_listen_port =

tcp_listen_queue = 5

tcp_max_per_addr = 1

tcp_client_ports = 1024-65535

tcp_client_max_idle = 0

enable_krb5 = no

krb5_principal = auditd

krb5_key_file = /etc/audit/audit.key

当修改配置文件后,需要重启auditd服务来应用修改后的配置。

理解audit日志:

默认Audit日志存放在/var/log/audit/andit.log中,可以通过auditctl命令来定义自己的audit规则,auditctl的使用方法参考:https://linux.die.net/man/8/auditctl。

以下面三条audit log为例:

type=SYSCALLmsg=audit(1364481363.243:24287): arch=c000003e syscall=2 success=no exit=-13a0=7fffd19c5592 a1=0 a2=7fffd19c4b50 a3=a items=1 ppid=2686 pid=3538 auid=500uid=500 gid=500 euid=500 suid=500 fsuid=500 egid=500 sgid=500 fsgid=500tty=pts0 ses=1 comm=”cat” exe=”/bin/cat”subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023key=”sshd_config”

type=CWDmsg=audit(1364481363.243:24287): cwd=”/home/shadowman”

type=PATHmsg=audit(1364481363.243:24287): item=0 name=”/etc/ssh/sshd_config”inode=409248 dev=fd:00 mode=0100600 ouid=0 ogid=0 rdev=00:00obj=system_u:object_r:etc_t:s0

type=SYSCALL这一行说明了audit的消息类型,audit消息类型可以对照https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Security_Guide/sec-Audit_Record_Types.html的表格进程查看,SYSCALL说明此次audit记录的是一次系统调用Kernel的记录
msg=audit(1364481363.243:24287)这一行的格式是(time_stamp:ID),time_stamp是unix时间,可以将其转化为其他时间格式,可以使用站长工具进行转换:http://tool.chinaz.com/Tools/unixtime.aspx。相同的audit event可能会产生多条time_stamp和event ID相同的log
msg后面跟了很多形式为“name=value”的键值对,这些键值对由kernel或者用户空间的进程产生。
arch=c000003e标明CPU的类型,c000003e对应x86_64,使用ausearch查看audit日志时会自动将其解码

syscall=2指出了发送给kernel的系统调用的类型,可以使用ausyscall —dump来显示所有的syscall的说明:
[root@DanCentOS65 audit]# ausyscall —dump

Using x86_64 syscall table:

0 read

1 write

2 open

3 close

……

succeed=yes/no,说明此次syscall成功或失败
exit=-13说明syscall的返回值是-13
a0,a1,a2,a3指明了前4个参数,也是编码成16进制,通过ausearch命令可以解码查看
items指出event中的path记录的数量
ppid指明Parent Process ID,即父进程ID
pid指明了进程ID
auid指出audit user ID,即当时的登陆uid
uid指出了对应进程的所有者ID
gid对应进程的group ID
euid对应进程的effective user ID
suid对应set user ID
fsuid对应file system user ID
egid对应effective group ID
sgid对应set group ID
fsgid对应file system group ID
tty指出对应进程是在哪个终端启动的
ses指出了对应进程的session ID
comm对应了进程执行的命令
exe指出了进程的执行文件的路径
subj指出进程执行时selinux上下文
key是管理员定义的标明是哪条rule输出了这条audit日志
第二条日志中CWD指出了进程的执行目录(current working directory),cwd字段指出了第一条日志中syscall的执行路径
第三条日中用来记录所有传递给syscall作为参数的路径,在这个audit事件中,仅有/etc/ssh/sshd_config作为参数进行传递,通过name字段指明
inode指出了与文件或目录相对应的inode number,可以通过下面的命令查看inode对应的文件或目录:
find/ -inum -print

dev=fd:00指出文件或目录对应的device ID,在例子中,对应/dev/fd/0这个设备
mode=0100600对应文件或目录的权限,这里0100600被解析为-rw———-
ouid对应文件的owner’s user ID
ogid对应文件的owner’s group ID

audit report命令:

使用aureport -x —summary可以生成一个summary,例如:

[root@DanCentOS65 audit]# aureport -x —summary

Executable Summary Report

=================================

total file

=================================

107895 /usr/sbin/sshd

3150 /usr/sbin/crond

34 /usr/bin/sudo

34 /bin/su

8 /sbin/shutdown

4 /usr/bin/passwd

2 /sbin/telinit

/sbin/load_policy

使用aureport -failed可以生成失败的events summary,例如:

[root@DanCentOS65 audit]# aureport —failed

Failed Summary Report

======================

Range of time in logs: 02/15/2017 18:54:57.612 -02/27/2017 13:35:17.927

Selected time for report: 02/15/2017 18:54:57 -02/27/2017 13:35:17.927

Number of changes in configuration: 0

Number of changes to accounts, groups, or roles: 0

Number of logins: 0

Number of failed logins: 5652

Number of authentications: 0

Number of failed authentications: 58251

Number of users: 1

Number of terminals: 1

Number of host names: 61

Number of executables: 1

Number of commands: 0

Number of files: 0

Number of AVC’s: 0

Number of MAC events: 0

Number of failed syscalls: 0

Number of anomaly events: 0

Number of responses to anomaly events: 0

Number of crypto events: 0

Number of integrity events: 0

Number of virt events: 0

Number of keys: 0

Number of process IDs: 5321

Number of events: 63904

使用aureport -f -i生成文件访问的记录

也可以使用aureport -f -i —summary生成一个summary

aureport参数说明:

-au, —auth:生成关于认证请求(尝试)的report

-a, —avc:生成avc message的report

—comm:生成关于执行命令的report

-c, —config:生成关于配置修改的report

-cr, —crypto:生成crypto events的report

-e, —event:生成events的report,例如:

  1. 02/04/2017 00:20:01 1003451 USER_ACCT -1 yes
  2. 02/04/2017 00:20:01 1003452 CRED_ACQ -1 yes
  3. 02/04/2017 00:20:01 1003453 LOGIN 0 yes
  4. 02/04/2017 00:20:01 1003454 USER_START 0 yes
  5. 02/04/2017 00:20:01 1003455 CRED_DISP 0 yes
  6. 02/04/2017 00:20:01 1003456 USER_END 0 yes
  7. 02/04/2017 00:21:13 1003457 CRYPTO_KEY_USER -1 yes
  8. 02/04/2017 00:21:13 1003458 CRYPTO_KEY_USER -1 yes

-f, —file:生成关于files和af_unixsocket的report

—failed:打印所有failed的events

-h, —host:打印host的report

—help:打印帮助

-i, —interpret:将数字编码解析问字符串(很多字段都进行了数字编码,通过此参数还原)

-if, —input file|directory:使用给定的文件或者目录来生成report,用于分析其他机器的日志

—input-logs:使用auditd.conf中配置的日志文件路径来做检索,该参数用于写cron job的时候配合使用

—integrity:生成完整事件的report

-k, —key:生成audit rule key的report(标明日志来源的key)

-l, —login:生成login的report

-m, —mods:生成account modification(账号修改)的report

-ma, —mac:生成MAC(MandatoryAccess Control,Linux系统中有两种自主访问控制策略,一种是9位权限码(User-Group-Other),另一种是访问控制列表ACL(Access Control List)。)events的report

-n, —anomaly:生成不正常的event report,例如网卡变为混杂模式,程序异常等等

—node node-name:生成特定node的report

-nc, —no-config:排除CONFIG_CHANGE event,生成report

-p, —pid:生成process的report

-r, —response:将所有不正常event的response做成report

-s, —syscall:生成syscall的report

—success:生成所有成功的events的report

—summary:将report整理成一个概述(统计数量分类输出)

-t, —log:生成所有日志文件的起止时间

—tty:生成tty(终端设备)的输入(按键)report

-te, —end[end-date][end-time]:匹配time stamp等于或早于给定参数的event来生成report,时间格式与本地时间格式匹配,如果省略掉日期,则默认指定today作为默认值。如果省略掉时间,则now作为默认值,使用24小时制。例如09/03/2009 18:00:00。常用的一些预定义的关键字:now/recent/today/yesterday/this-week/week-ago/this-month/this-year,其中,recent表示10分钟之前,其他的都可以按照字面意思理解

-ts, —start[start-date][start-time]:与-te参数类似,用于过滤日期和时间晚于给定时间的event生成report。区别是如果时间参数省略,会以midnight作为默认值。

-tm, —terminal:生成terminal的report

-u, —user:生成user的report

-v, —version:打印版本

—virt:生成虚拟化事件的report

-x, —executable:生成executable的report

可以使用autrace来监控一个进程:

autrace /usr/bin/waagent

使用ausearch来查看audit log:

ausearch -p 27020 —raw

ausearch参数说明:

-a, —event audit-event-id:基于event ID检索(msg里包含time_stamp和eventID)

-c, —comm comm-name:基于comm名称检索

-e, —exitexit-code-or-errno:基于exit code或errno检索

-f, —file:基于filename检索

-ga, —gid-all all-group-id:基于group ID或groupname检索

-ge, —gid-effectuve effective-group-id:基于effective group ID或name检索

-gi, —gid group-id:基于group ID或name检索

-h, —help:help

-hn, —host host-name:基于hostname检索,hostname不会进行解析

-i, —interpret:将数字编码解析问字符串(很多字段都进行了数字编码,通过此参数还原)

-if, —input file-name:搜索给定的文件,而不会去系统的audit日志中检索。通过这个参数可以将日志导出到其他机器上进行检索

—input-logs:使用auditd.conf中配置的日志文件路径来做检索,该参数用于写cron job的时候配合使用

—just-one:当出现了第一条匹配的日志时即停止检索,所以只会检索出第一条匹配的结果

-k, —key key-string:基于key进行检索

-l, —line-buffered:如果默认的缓冲规则不能满足需要,通过此参数可以将每条输出都立即flush到连接的stdout流中

-m, —message message-type |comma-sep-message-type-list:使用messagetype进行索引,可以指定某个type,也可以使用“逗号”将多个messagetype并列起来,逗号两侧不能有空格。可以使用ALL作为message type,用于匹配所有message type。

-n, —node node-name:匹配node name

-o, —objectSE-Linux-context-string:匹配tcontext(object)

-p, —pid process-id:匹配process ID

-pp, —ppidparent-process-id:匹配parent process ID

-r, —raw:将未经格式化处理的原日志输出

-sc, —syscallsyscall-name-or-value:匹配syscall参数

-se, —context SE-Linux-context-string:匹配scontext/subject或tcontext/object

—session Login-Session-ID:匹配用户的Login Session ID

-su, —subject SE-Linux-context-string:匹配scontext(subject)

-sv, —success success-value:匹配success value

-te, —end[end-date][end-time]:匹配time stamp等于或早于给定参数的event,时间格式与本地时间格式匹配,如果省略掉日期,则默认指定today作为默认值。如果省略掉时间,则now作为默认值,使用24小时制。例如09/03/2009 18:00:00。常用的一些预定义的关键字:now/recent/today/yesterday/this-week/week-ago/this-month/this-year,其中,recent表示10分钟之前,其他的都可以按照字面意思理解

-ts, —start [start-date][start-time]:与-te参数类似,用于过滤日期和时间晚于给定时间的event。区别是如果时间参数省略,会以midnight作为默认值。

-tm, —terminal terminal:匹配terminal参数

-ua, —uid-all all-user-id:匹配user ID/effective user ID/login user ID(auid)

-ue, —uid-effective effective-user-id:匹配effective user ID

-ui, —uid user-id:匹配user ID

-ul, —loginuid login-id:匹配login user ID

-uu, —uuid guest-uuid:匹配guest UUID

-v, —version:打印版本

-vm, —vm-name guest-name:匹配guest name

-w, —word:条件中如果有字符串匹配,必须完全匹配,例如filename/hostname/terminal/SELinux context

-x, —executable executable:匹配executable名