Linux 审计功能文档

@Ta 2023-03-30发布,2023-03-31修改 2367点击
评论关闭

Linux 审计功能文档

参考文档

https://documentation.suse.com/sles/15-SP1/html/SLES-all/cha-audit-comp.html

安装审计组件

sudo apt install auditd
sudo systemctl enable auditd
sudo systemctl start auditd

审计功能设置

以下所有命令均需要root权限,请自行添加sudo或切换到root会话。

如果想让规则永久生效,可把传递给auditctl的参数添加到/etc/audit/rules.d/audit.rules文件里,每条命令一行。

例如,要让auditctl -e 2开机自动生效,则把-e 2作为单独一行添加到/etc/audit/rules.d/audit.rules文件里。

要让/etc/audit/rules.d/audit.rules文件里的规则立即生效,可以执行augenrules --load命令。

注意:在audit.rules里尽量不要给字符串加引号,否则可能不起作用。

启用/禁用审计

# 禁用审计
auditctl -e 0

# 启用审计
auditctl -e 1

# 强制启用审计(设为2后,重启前不能再调整为0或1)
auditctl -e 2

查询当前审计状态

auditctl -s

示例输出:

enabled 2      # 0:禁用;1:启用;2:强制启用(重启前不能关闭)
failure 1      # 0:写审计日志失败时静默;1:失败时打印内核日志;2:失败时 kernel panic
pid 569        # 当前用户pid
rate_limit 0   # 日志速率限制,每秒条数,0不限制
backlog_limit 8192    # 日志缓冲条数上限
lost 20               # 因限制而丢失的日志条数
backlog 0             # 尚未写入磁盘的日志条数
backlog_wait_time 60000    # 写入磁盘等待的秒数,超时还未写入则丢弃
loginuid_immutable 0 unlocked    # 是否已启用登录UID不可变特性,启用后无法利用root权限来冒充其他用户

列出现有的审计规则

auditctl -l

清除所有审计规则

auditctl -D

/etc/audit/rules.d/*.rules 加载审计规则

augenrules --load

设置写入审计日志失败时的处理方法

设置在审计日志写入磁盘失败时采取的措施。
写入失败不一定是因为IO问题(磁盘满了等情况),也可能是因为达到了下面设置的速率限制。

# 保持静默
auditctl -f 0

# 打印内核日志
auditctl -f 1

# 产生 kernel panic 使系统停止运行(不会进行磁盘同步,可能会丢失文件)
auditctl -f 2

设置审计日志速率限制

如果超过速率限制,则丢弃日志并执行-f设定的动作。设为0不限制。

auditctl -r 每秒消息条数

# 例如每秒100条
auditctl -r 100

设置审计日志缓冲条数上限

如果未完成写入的日志条数超过限制,则丢弃日志并执行-f设定的动作。设为0不限制。

auditctl -b 缓冲条数上限

# 例如1000条
auditctl -b 1000

审计规则设置

以下所有命令均需要root权限,请自行添加sudo或切换到root会话。

如果想让规则永久生效,可把传递给auditctl的参数添加到/etc/audit/audit.rules文件里,每条命令一行。

例如,要让auditctl -w /etc -p rx开机自动生效,则把-w /etc -p rx作为单独一行添加到/etc/audit/audit.rules文件里。

审计文件访问

auditctl -w <文件或目录路径> [-p (r|w|x|a)] [-k <搜索关键字>]

### -p 的参数值:r 读;w 写;x 执行;a 获取文件状态(stat系统调用)
### -k 用于给给审计日志条目加自定义关键字,方便搜索(不要使用特殊字符,可能不生效。在`audit.rules`文件里指定时不要加引号)

### 例子

# 审计对 /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

列出审计模块支持的系统调用列表

# 列出审计模块支持的系统调用名称和id列表
ausyscall (b32|b64|<架构名称>) --dump

# 例子
ausyscall --dump         # 列出本机默认模式的系统调用
ausyscall b32 --dump     # 列出本机32位模式的系统调用
ausyscall b64 --dump     # 列出本机64位模式的系统调用
ausyscall aarch64 --dump # 列出指定架构的系统调用
  • 注意该列表是架构特定的,除非明确指定架构,否则打印的名称和id不适用于其他架构的平台。
  • 某些架构可能没有某些系统调用,或者名称、id不同。
  • CPU模式(32位/64位)也会影响列表的内容。
  • 某些系统调用在32位和64位模式中具有不同的id,此时必须明确指定规则要匹配的架构,否则可能会产生意外结果(在某一边匹配到无关系统调用)。

审计系统调用

用户和程序在Linux中的大部分操作都可以通过系统调用方式进行审计,以下是添加系统调用审计规则的方法:

# 添加系统调用审计规则到规则列表的末尾
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。
    • 其他

      • a0, a1, a2, a3:系统调用的前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 --help

列出当前审计日志中的所有内容

ausearch -i

列出指定关键字的内容

ausearch -i -k <搜索关键字>

注意:搜索关键字须为审核规则里通过-k参数或-F key=字段指定的值,其他值无效。支持部分匹配。

搜索包含特定文件名的内容

ausearch -i -f <要搜索的文件名>

# 例如,搜索所有和ping命令有关的记录
ausearch -i -f ping

审计案例

审计 uid 1000 启动的程序

root用户:

# 设置审计规则
auditctl -a always,exit -F arch=b64 -S execve -F uid=1000 -k uid1000exec
auditctl -a always,exit -F arch=b32 -S execve -F uid=1000 -k uid1000exec

uid 1000:

cat /etc/passwd
ping baidu.com

root用户:

# 查看审计日志
ausearch -i -k uid1000exec

将打印 uid 1000 执行命令的记录。

审计 uid 1000 通过 vim 命令打开的文件

root用户:

# 设置审计规则
# 通过 realpath $(command -v vim) 找到 vim 的实际路径是 /usr/bin/vim.basic
auditctl -a always,exit -F arch=b64 -S openat -F uid=1000 -F exe=/usr/bin/vim.basic -k uid1000vim
auditctl -a always,exit -F arch=b32 -S openat -F uid=1000 -F exe=/usr/bin/vim.basic -k uid1000vim

uid 1000:

vim ~/test.txt

root用户:

# 查看审计日志
ausearch -i -k uid1000vim

将打印 uid 1000 通过 vim 打开文件的记录(包括 ~/test.txt,以及 vim 在运行过程中打开的其他文件)。

审计 uid 1000 打开的网络连接(TCP连接)

root用户:

# 设置审计规则
auditctl -a always,exit -F arch=b64 -S connect -F uid=1000 -F success=1 -k uid1000conn
auditctl -a always,exit -F arch=b32 -S connect -F uid=1000 -F success=1 -k uid1000conn

uid 1000:

curl https://www.baidu.com/

root用户:

# 查看审计日志
ausearch -i -k uid1000conn

将打印 uid 1000 打开的 IP 和端口。

回复列表(0|隐藏机器人聊天)
帖子没有回复
添加新回复
该帖子已关闭评论,仅楼主可回复。