文章大纲
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.rules
audit-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
文件的最大大小,单位是MiB
max_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