Linux 审计系统

功能强大的 Audit,可用于记录和检查 Linux 安全相关的事件。

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_leftadmin_space_left_action :指定绝对最小可用空间量和对应的操作
  • disk_full_action:指定磁盘没有可用空间时触发的操作,必须设置为 haltsingle 当审计无法记录事件时,确保系统关闭或进入单用户模式
  • flush:设置为 incremental_async 通过异步的方式将日志写入磁盘,配合 freq 参数设置在强制与磁盘进行同步之前可以将多少条记录发送到磁盘,推荐设置为 100 ,提升吞吐量

配置更改后,使用 service auditd restartauditd 进行重启,不能使用 systemctl ,因为要正确记录 auidsystemctl 只能用于 enablestatus 操作。

审计功能

auditd 服务启动后,可以使用 auditctl 与审计服务进行交互。

启用与禁用审计

使用 auditctl -e 来临时的调整审计状态,接受三个参数:

  • 0 启用
  • 1 禁用
  • 2 强制启用,重启前不能再调整为 01

查询审计状态

通过 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 Number
      • devminor:设备的 Minor Number
      • filetype:文件类型,可以是:filedirsocketlinkcharacterblockfifo
      • 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。
    • 其他
      • a0a1a2a3:系统调用的前4个参数,只支持数值,不支持字符串。
      • exit:系统调用的返回值。如果返回值是错误号(errno),也可用对应的枚举名称代替(比如EACCES等,参见man errno)。
      • key:设置搜索关键字,与-k参数作用相同。
      • msgtype:事件记录类型,仅可用于excludeuser规则列表,用于排除指定的事件。
      • pers:操作系统特定的数值
      • saddr_fam:网络类型,IPv4为2,IPv6为10
      • sessionid:用户的登录会话id。
      • success:如果系统调用的返回值(exit字段的值)大于等于0success的值为1,否则值为0
    • SELinux
      • obj_uid:Object’s UID
      • obj_gid:Object’s GID
      • obj_user:Resource’s SE Linux User
      • obj_role:Resource’s SE Linux Role
      • obj_type:Resource’s SE Linux Type
      • obj_lev_low:Resource’s SE Linux Low Level
      • obj_lev_high:Resource’s SE Linux High Level
      • subj_user:Program’s SE Linux User
      • subj_role:Program’s SE Linux Role
      • subj_type:Program’s SE Linux Type
      • subj_sen:Program’s SE Linux Sensitivity
      • subj_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

参考文档:https://docs.redhat.com/zh-cn/documentation/red_hat_enterprise_linux/9/html/security_hardening/auditing-the-system_security-hardening

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理

滚动至顶部