文章大纲
Linux Audit 系统会根据预配置的规则,生成日志条目来记录系统上所发生的事件的相关信息。
安装配置
auditd 服务源于 audit 软件包,在 RHEL 中这个包默认已安装,且服务设置为了开机自启。
配置目录位于 /etc/audit/ :
[root@rhel9 ~]# ls /etc/audit/
auditd.conf audit.rules audit-stop.rules plugins.d rules.d
auditd.conf是审计服务的配置文件audit.rules是审计服务的规则文件,但不要去修改因为它是由auditd服务通过rules.d目录中的规则文件自动生成的,如果修改系统重启后就会被覆盖掉rules.d存放持久规则的目录,目录下的规则文件以.rules作为后缀,并在服务启动时将所有文件内容汇集到audit.rulesaudit-stop.rules是审计服务停止时应用的配置,默认设置的时关闭审计和删除所有规则plugins.d与审计事件交互的插件配置存放的目录
审计服务配置
在 /etc/audit/auditd.conf 中常用的配置:
log_file:定义审计日志存放的位置,默认为/var/log/audit/audit.log建议为/var/log或/var/log/audit挂载独立的文件系统max_log_file指定audit.log文件的最大大小,单位是MiBmax_log_file_action:审计日志文件一旦超过了max_log_file定义的大小对应的操作,默认是ROTATE轮转日志,保存的日志文件数为num_logs定义的值,默认为5,建议设置为keep_logs防止审计日志因轮转导致覆盖space_left:指定磁盘上剩余的可用空间量,必须设置一个数字,单位是MiB或者是百分比,会根据log_file所在文件系统的空间计算大小,能够让管理员有足够的时间来响应并释放磁盘空间space_left_action:达到space_left定义的值后触发的操作,默认是SYSLOG发送日志消息,建议修改为email发送邮件或者exec执行处理脚本admin_space_left和admin_space_left_action:指定绝对最小可用空间量和对应的操作disk_full_action:指定磁盘没有可用空间时触发的操作,必须设置为halt或single当审计无法记录事件时,确保系统关闭或进入单用户模式flush:设置为incremental_async通过异步的方式将日志写入磁盘,配合freq参数设置在强制与磁盘进行同步之前可以将多少条记录发送到磁盘,推荐设置为100,提升吞吐量
配置更改后,使用 service auditd restart 对 auditd 进行重启,不能使用 systemctl ,因为要正确记录 auid ,systemctl 只能用于 enable 和 status 操作。
审计功能
在 auditd 服务启动后,可以使用 auditctl 与审计服务进行交互。
启用与禁用审计
使用 auditctl -e 来临时的调整审计状态,接受三个参数:
0禁用1启用2强制启用,重启前不能再调整为0或1
查询审计状态
通过 auditctl -s 查看当前状态:
[root@rhel9 ~]# auditctl -s
enabled 1 # 启用的状态
failure 1 # 审计日志写失败时状态,0:静默, 1:打印 Kernel 日志 2:Kernel panic
pid 645 # auditd 进程 id
rate_limit 0 # 日志速率限制,每条条数,0 不限制
backlog_limit 8192 # 日志缓冲条数上线
lost 0 # 因限制而丢失的日志数
backlog 0 # 尚未写入磁盘的日志数
backlog_wait_time 60000 # 写入磁盘等待秒数
backlog_wait_time_actual 0 # 当前等待的日志数
loginuid_immutable 0 unlocked # 是否已启用登录 UID 不可变性
使用 auditctl 管理规则
使用 auditctl -l 列出所有的规则:
[root@rhel9 ~]# auditctl -l
No rules
使用 auditctl -D 清除所有的审计的规则(临时):
[root@rhel9 ~]# auditctl -D
No rules
从 /etc/audit/rules.d/*.rules 加载审计规则:
[root@rhel9 ~]# augenrules --load
/usr/sbin/augenrules: No change
No rules
enabled 1
failure 1
pid 650
rate_limit 0
backlog_limit 8192
lost 0
backlog 4
backlog_wait_time 60000
backlog_wait_time_actual 0
enabled 1
failure 1
pid 650
rate_limit 0
backlog_limit 8192
lost 0
backlog 4
backlog_wait_time 60000
backlog_wait_time_actual 0
enabled 1
failure 1
pid 650
rate_limit 0
backlog_limit 8192
lost 0
backlog 4
backlog_wait_time 60000
backlog_wait_time_actual 0
设置写入审计日志失败时的动作
审计写入日志失败可能是一系列的原因,磁盘满了,超过了限制等等。
使用 auditctl -f 设置写入失败时执行的操作:
0:保持静默1:打印内核日志2:kernel panic
设置审计日志的速率限制和缓存条数限制
如果审计日志写入超过速率限制,就会丢弃日志并执行 -f 设置的操作。
将日志速率限制为每秒 100 条:
[root@rhel9 ~]# auditctl -r 100
enabled 1
failure 1
pid 650
rate_limit 100 # 限制为 100 如果设置为 0 则不限制
backlog_limit 8192
lost 0
backlog 0
backlog_wait_time 60000
backlog_wait_time_actual 0
如果未写入磁盘的日志超过缓存条数,则丢弃日志并执行 -f 设置的操作。
将审计日志缓存条数设置为 500:
[root@rhel9 ~]# auditctl -b 500
enabled 1
failure 1
pid 650
rate_limit 100
backlog_limit 500 # 设置为 0 表示不限制
lost 0
backlog 0
backlog_wait_time 60000
backlog_wait_time_actual 0
审计日志规则设置
可以使用 auditctl 设置规则,但规则是临时生效的,如果想要永久生效需要将规则写入到 /etc/auditd/rules.d/ 中。
审计文件访问
对文件的审计使用的是 -w 选项,用法:
auditctl -w <文件或目录路径> [-p (r|w|x|a)] [-k <搜索关键字>]
-p :r 读;w 写;x 执行;a 获取文件状态(stat系统调用)
例子:
# 审计对 /etc/passwd 的访问
auditctl -w /etc/passwd
# 审计对 /etc/group 的写入
auditctl -w /etc/group -p w
# 审计对 /etc/shadow 的读取,把审核记录标记为 read_shadow
auditctl -w /etc/shadow -p r -k read_shadow
如果要删除规则,只需将 -w 换成 -W 即可,如:
auditctl -W /etc/shadow -p r -k read_shadow
审计系统调用
审计系统调用首先需要知道支持哪些系统调用。
使用 ausyscall 列出所支持的系统调用:
# 列出审计模块支持的系统调用名称和id列表
ausyscall (b32|b64|<架构名称>) --dump
ausyscall --dump # 列出本机默认模式的系统调用
ausyscall b32 --dump # 列出本机32位模式的系统调用
ausyscall b64 --dump # 列出本机64位模式的系统调用
ausyscall aarch64 --dump # 列出指定架构的系统调用
为系统调用添加审计规则的方式:
# 添加系统调用审计规则到规则列表的末尾
auditctl -a <规则列表>,<操作> [-S <系统调用名称或id>]... [-F <条件字段><操作符><条件值>]... [-k <搜索关键字>]
auditctl -a <操作>,<规则列表> [-S <系统调用名称或id>]... [-F <条件字段><操作符><条件值>]... [-k <搜索关键字>]
# 添加到规则列表的开头
auditctl -A <规则列表>,<操作> [-S <系统调用名称或id>]... [-F <条件字段><操作符><条件值>]... [-k <搜索关键字>]
auditctl -A <操作>,<规则列表> [-S <系统调用名称或id>]... [-F <条件字段><操作符><条件值>]... [-k <搜索关键字>]
# 删除规则
auditctl -d <规则列表>,<操作> [-S <系统调用名称或id>]... [-F <条件字段><操作符><条件值>]... [-k <搜索关键字>]
auditctl -d <操作>,<规则列表> [-S <系统调用名称或id>]... [-F <条件字段><操作符><条件值>]... [-k <搜索关键字>]
参数说明:
-S指定要匹配的系统调用,-F指定要匹配的条件规则,两者均可传递多个。- 至少要指定一个
-S或-F参数。 - 如果想无条件匹配所有系统调用,可以传递
-S all。 - 如果不传递
-S,则所有匹配-F的系统调用都会被记录。 - 最多支持64个
-F参数。 -k用于给审计日志条目加自定义关键字,方便搜索。注意不要使用特殊字符,可能不生效。在audit.rules文件里指定时不要加引号。
参数列表:
- 操作
never:用于忽略特定的审计事件,匹配的事件将不记录在审计日志中。always:将匹配的规则记录在审计日志中。
- 规则列表
task:在创建新进程/线程时触发该审计规则。exit:在每次系统调用完成时触发该审计规则。user:用于过滤第三方程序(比如SSH服务器)发来的审计日志,与never操作配合使用。exclude:用于过滤不想看到的事件,与never操作配合使用(即使传递always,也被视为never)。filesystem:用于过滤不想看到的文件系统事件,与never配合使用。
- 系统调用名称或id
- 通过
ausyscall [架构] --dump命令查看审计模块支持的系统调用名称和id。 - 也可传入
all,表示所有系统调用。 - 可同时传入多个id或名称,用逗号分隔,例如:
-S openat,mkdirat。 - 注意系统调用匹配同时作用于32位和64位模式,如果两个模式的调用名称和id不完全相同,就应该通过
-F arch=(b32|b64)来明确指定要匹配的架构,否则可能会产生意外结果(在某一边匹配到无关调用)。
- 通过
- 操作符
- =:相等或赋值(具体是比较操作还是赋值操作取决于条件字段的类型)
!=:不相等<:小于>:大于<=:小于或等于>=:大于或等于&:按位与,结果不为0则视为匹配。&=:按位与并更新掩码,用于操作位域字段,在某些情况下与 = 效果相同。
- 条件字段
- 用户和用户组
uid:User ID. May be numeric or the user account name.auid:审计用户id,是用户最初登录时的uid。可传递uid数值或用户名。euid:有效用户id(经历sudo等一系列用户切换后最终生效的uid),可传递uid数值或用户名。suid:Saved User ID. See getresuid(2) man page.gid:进行用户切换前的egid:有效用户组id(经历sudo等一系列用户切换后最终生效的gid),可传递gid数值或用户组名称。sgid:Saved Group ID. See getresgid(2) man page.fsgid:文件系统的用户组id,可传递gid数值或用户组名称。fsuid:文件系统的用户id,可传递uid数值或用户名。
- 设备和文件系统
devmajor:设备的 Major Numberdevminor:设备的 Minor Numberfiletype:文件类型,可以是:file,dir,socket,link,character,block,fifo。inode:操作对象在虚拟文件系统中的 inode 号。dir:要监控的目录绝对路径,会监控当前目录及其中的所有内容,和-w参数效果相同。仅可用于exit规则列表。path:要监控的文件绝对路径,和-w参数效果相同。仅可用于exit规则列表。perm:按访问权限过滤,可以是以下值:r读;w写;x执行;a获取文件状态。仅可用于exit规则列表。
在使用该条件时可不指定具体的系统调用,内核将在程序用到对应权限时产生审计日志。
与-p参数作用相同。
- 进程和线程
arch:指令集架构,可通过uname -m命令获取,也可使用b32代表本机32位模式,b64代表本机64位模式。
注意:如果32位和64位系统调用的id不同,则必须指定该参数,否则可能会在某一边匹配到无关调用。exe:可执行程序的绝对路径,只支持 = 和!=操作,每条规则只能出现一次。pid:进程id。ppid:父进程id。
- 其他
a0,a1,a2,a3:系统调用的前4个参数,只支持数值,不支持字符串。exit:系统调用的返回值。如果返回值是错误号(errno),也可用对应的枚举名称代替(比如EACCES等,参见man errno)。key:设置搜索关键字,与-k参数作用相同。msgtype:事件记录类型,仅可用于exclude和user规则列表,用于排除指定的事件。pers:操作系统特定的数值saddr_fam:网络类型,IPv4为2,IPv6为10。sessionid:用户的登录会话id。success:如果系统调用的返回值(exit字段的值)大于等于0,success的值为1,否则值为0。
- SELinux
obj_uid:Object’s UIDobj_gid:Object’s GIDobj_user:Resource’s SE Linux Userobj_role:Resource’s SE Linux Roleobj_type:Resource’s SE Linux Typeobj_lev_low:Resource’s SE Linux Low Levelobj_lev_high:Resource’s SE Linux High Levelsubj_user:Program’s SE Linux Usersubj_role:Program’s SE Linux Rolesubj_type:Program’s SE Linux Typesubj_sen:Program’s SE Linux Sensitivitysubj_clr:Program’s SE Linux Clearance
- 用户和用户组
查询审计日志
审计日志的查询可以通过 ausearch 配合多个选项实现。
指定原始日志文件并进行解析:
ausearch -i -if /var/log/audit/raw.log
使用 -p 打印指定 PID 的审计日志:
[root@rhel9 ~]# ausearch -p 716 -i
----
type=USER_END msg=audit(12/10/2024 16:15:45.958:427) : pid=716 uid=root auid=root ses=1 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 msg='op=PAM:session_close grantors=pam_selinux,pam_loginuid,pam_selinux,pam_namespace,pam_keyinit,pam_keyinit,pam_limits,pam_systemd,pam_unix,pam_umask,pam_lastlog acct=root exe=/usr/bin/login hostname=rhel9.example.com addr=? terminal=/dev/tty1 res=success'
使用 -a 指定审计事件 ID 进行查询:
[root@rhel9 ~]# ausearch -a 427 -i
----
type=PROCTITLE msg=audit(08/26/2024 07:32:02.318:427) : proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(08/26/2024 07:32:02.318:427) : arch=x86_64 syscall=sendmsg success=yes exit=144 a0=0x6 a1=0x7ffe7d971dc0 a2=0x0 a3=0x7ffe7d960c6c items=0 ppid=1 pid=675 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=firewalld exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(08/26/2024 07:32:02.318:427) : table=firewalld_policy_drop:14 family=inet entries=2 op=nft_unregister_table pid=675 subj=system_u:system_r:firewalld_t:s0 comm=firewalld
----
type=USER_END msg=audit(12/10/2024 16:15:45.958:427) : pid=716 uid=root auid=root ses=1 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 msg='op=PAM:session_close grantors=pam_selinux,pam_loginuid,pam_selinux,pam_namespace,pam_keyinit,pam_keyinit,pam_limits,pam_systemd,pam_unix,pam_umask,pam_lastlog acct=root exe=/usr/bin/login hostname=rhel9.example.com addr=? terminal=/dev/tty1 res=success'
使用 -m 按照消息类型进行搜索。
消息类型可以访问 https://access.redhat.com/articles/4409591
[root@rhel9 ~]# ausearch -m LOGIN -i
type=LOGIN msg=audit(12/13/2024 11:29:00.721:74) : pid=1277 uid=root subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 old-auid=unset auid=root tty=(none) old-ses=4294967295 ses=3 res=yes
使用 -f 搜索与特定文件名称相关的事件:
[root@rhel9 ~]# ausearch -i -f /etc/testfile
----
type=PROCTITLE msg=audit(12/13/2024 14:14:00.679:171) : proctitle=touch /etc/testfile
type=PATH msg=audit(12/13/2024 14:14:00.679:171) : item=1 name=/etc/testfile inode=33874010 dev=fd:00 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:etc_t:s0 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0
type=PATH msg=audit(12/13/2024 14:14:00.679:171) : item=0 name=/etc/ inode=33685633 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:etc_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0
type=CWD msg=audit(12/13/2024 14:14:00.679:171) : cwd=/root
type=SYSCALL msg=audit(12/13/2024 14:14:00.679:171) : arch=x86_64 syscall=openat success=yes exit=3 a0=AT_FDCWD a1=0x7ffd36145679 a2=O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK a3=0x1b6 items=2 ppid=1282 pid=2077 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=3 comm=touch exe=/usr/bin/touch subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=testfile
审计日志报告
可以使用 aureport 获取审计信息的概览或有关特定类型事件更加详细的报告。
直接运行 aureport 会返回有关日志中存在不同类型的事件的概述。
[root@rhel9 ~]# aureport
Summary Report
======================
Range of time in logs: 07/17/2024 11:16:45.897 - 12/13/2024 14:14:00.679
Selected time for report: 07/17/2024 11:16:45 - 12/13/2024 14:14:00.679
Number of changes in configuration: 269
Number of changes to accounts, groups, or roles: 0
Number of logins: 32
Number of failed logins: 5
Number of authentications: 32
Number of failed authentications: 7
Number of users: 2
Number of terminals: 10
Number of host names: 3
Number of executables: 16
Number of commands: 17
Number of files: 2
Number of AVC's: 0
Number of MAC events: 56
Number of failed syscalls: 0
Number of anomaly events: 5
Number of responses to anomaly events: 0
Number of crypto events: 145
Number of integrity events: 0
Number of virt events: 0
Number of keys: 1
Number of process IDs: 185
Number of events: 3409
可以配合使用 -i 来翻译事件,--summary 将列表精简为摘要:
[root@rhel9 ~]# aureport --login -i
Login Report
============================================
# date time auid host term exe success event
============================================
1. 07/17/2024 11:22:20 root rhel9.example.com tty1 /usr/bin/login yes 68
2. 07/17/2024 11:26:28 root rhel9.example.com tty1 /usr/bin/login yes 58
3. 07/18/2024 13:18:47 root rhel9.example.com tty1 /usr/bin/login yes 65
4. 07/18/2024 13:21:31 root 192.168.56.1 ssh /usr/sbin/sshd yes 96
5. 07/18/2024 13:21:42 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 118
6. 07/18/2024 13:25:32 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 65
7. 07/22/2024 08:37:21 root rhel9.example.com tty1 /usr/bin/login yes 67
8. 07/22/2024 08:38:30 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 86
9. 07/23/2024 09:01:40 root rhel9.example.com tty1 /usr/bin/login yes 60
10. 07/23/2024 09:01:52 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 73
11. 08/11/2024 20:13:36 root rhel9.example.com tty1 /usr/bin/login yes 63
12. 08/12/2024 07:04:55 root rhel9.example.com tty1 /usr/bin/login yes 60
13. 08/12/2024 07:05:11 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 73
14. 08/12/2024 07:57:15 root rhel9.example.com tty1 /usr/bin/login yes 63
15. 08/12/2024 07:57:26 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 79
16. 08/12/2024 11:11:56 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 65
17. 08/12/2024 11:14:54 root 192.168.56.1 /dev/pts/1 /usr/sbin/sshd yes 83
18. 08/14/2024 20:21:16 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 68
19. 08/15/2024 10:47:07 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 68
20. 08/25/2024 20:33:34 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 68
21. 08/26/2024 00:41:34 root rhel9.example.com tty1 /usr/bin/login yes 219
22. 09/05/2024 13:24:59 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 72
23. 09/05/2024 14:24:27 root 192.168.56.1 /dev/pts/1 /usr/sbin/sshd yes 121
24. 11/29/2024 16:39:35 unset rhel9.example.com tty1 /usr/bin/login no 50
25. 11/29/2024 16:39:40 unset rhel9.example.com tty1 /usr/bin/login no 52
26. 11/29/2024 16:39:49 hcai rhel9.example.com tty1 /usr/bin/login no 54
27. 11/29/2024 16:39:59 student rhel9.example.com tty1 /usr/bin/login no 60
28. 11/29/2024 16:40:29 unset rhel9.example.com tty1 /usr/bin/login no 62
29. 11/29/2024 16:40:43 root rhel9.example.com tty1 /usr/bin/login yes 81
30. 11/29/2024 16:41:29 root 192.168.56.1 ssh /usr/sbin/sshd yes 112
31. 11/29/2024 16:41:31 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 115
32. 12/07/2024 09:19:40 root rhel9.example.com tty1 /usr/bin/login yes 64
33. 12/10/2024 07:21:04 root rhel9.example.com tty1 /usr/bin/login yes 64
34. 12/10/2024 07:50:08 root rhel9.example.com tty1 /usr/bin/login yes 66
35. 12/10/2024 07:50:30 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 83
36. 12/13/2024 11:28:47 root rhel9.example.com tty1 /usr/bin/login yes 64
37. 12/13/2024 11:29:00 root 192.168.56.1 /dev/pts/0 /usr/sbin/sshd yes 79
[root@rhel9 ~]# aureport --login -i --summary
Login Summary Report
============================
total auid
============================
32 root
3 unset
1 hcai
1 student