17.6 安全事件审计
进程记账记录每条命令的执行信息,可用于追踪入侵途径。
17.6.1 进程记账
进程记账是安全手段之一,管理员可借此追踪系统资源用量及其在不同用户间的分配,同时监控系统,并可最低限度地追踪用户执行的命令。
进程记账有利有弊。优势是可追溯入侵至入侵点;弊端在于产生海量日志,对磁盘空间要求较高。
17.6.1.1 启用和使用进程记账
启用进程记账前,需执行:
# service accounting enable
# service accounting start记账信息存储于 /var/account 目录,首次启动记账服务时按需自动创建。这些文件包含敏感信息,含所有用户执行过的每条命令。仅 root 可写,仅 root 与 wheel 组成员可读。若需同时阻止 wheel 成员读取,可将 /var/account 目录权限改为仅 root 可访问。
启用后,记账即开始跟踪 CPU 信息、已执行命令等。所有记账日志均为二进制格式,须经 sa 查看。不加选项执行时,sa 打印每位用户的调用次数、总经过时间(分钟)、总 CPU 和用户时间(分钟)及平均 I/O 操作次数等信息。
要显示用户执行的命令,使用 lastcomm。
例如,此命令打印 trhodes 在 ttyp1 终端上所有 ls 的使用记录:
# lastcomm ls trhodes ttyp117.6.2 安全事件审计概述
FreeBSD 操作系统支持安全事件审计。事件审计可对各类安全系统事件作可靠、精细、可配置的日志记录,含登录、配置变更、文件与网络访问。这些日志可用于实时监控、入侵检测及事后分析。FreeBSD 实现了 Sun 发布的 Basic Security Module(BSM)API 及文件格式,与 Solaris 和 macOS 审计实现互通。
本章重点介绍事件审计的安装与配置,阐释审计策略,并提供一个审计配置示例。
审计设施存在一些已知局限性。并非所有安全系统事件均可审计,且部分登录机制(如基于 Xorg 的显示管理器和第三方守护进程)无法正确为用户登录会话配置审计。
安全事件审计设施可生成极详细的系统活动日志。繁忙系统若配置为高细节级别,跟踪文件数据量可能极其庞大,某些配置下每周可超过数 GB。管理员应考虑高数据量审计配置对磁盘空间的需求。例如,可能需要为 /var/audit 分配专用文件系统,避免写满后影响其他文件系统。
17.6.2.1 安全事件审计关键术语
以下术语与安全事件审计相关:
- 事件(event):可审计事件即审计子系统能够记录的任何事件。安全事件示例包括创建文件、建立网络连接或用户登录。事件分“有归属”(attributable,可追溯至已认证用户)和“无归属”(non-attributable)两类。无归属事件例如认证前发生的错误密码尝试等。
- 类(class):一组命名相关事件,用于选择表达式。常用事件类包括“文件创建”(fc)、“执行”(ex)和“登录_注销”(lo)。
- 记录(record):描述安全事件的审计日志条目。记录包括事件类型、执行主体(用户)信息、日期时间、涉及的对象或参数,以及成功或失败条件。
- 跟踪(trail):由一系列描述安全事件的审计记录组成的日志文件。跟踪大致按事件完成时间排列。仅授权进程可向审计跟踪提交记录。
- 选择表达式(selection expression):一个字符串,包含前缀列表和审计事件类名称,用于匹配事件。
- 预选择(preselection):系统确定管理员关注哪些事件的过程。预选择配置使用一系列选择表达式,确定对哪些用户审计哪些事件类,以及同时适用于已认证和未认证进程的全局设置。
- 精简(reduction):从现有审计跟踪中筛选记录以供保存、打印或分析的过程;同样也是从审计跟踪中移除不需要的审计记录的过程。管理员可借助精简实施审计数据保存策略。例如,详细审计跟踪可保留一个月,之后可精简跟踪,仅保留登录信息以供归档。
17.6.2.2 审计配置
事件审计的用户空间支持已随 FreeBSD 基础系统安装。GENERIC 内核默认提供内核支持,启用 auditd:
# service auditd enable然后启动审计守护进程:
# service auditd start使用定制内核的用户,须在其配置文件中加入:
options AUDIT17.6.2.2.1 事件选择表达式
选择表达式用于审计配置,确定应审计的事件。表达式包含待匹配的事件类列表,从左至右求值,合并两个表达式即前后拼接。
以下汇总了默认审计事件类:
| 类名 | 描述 | 操作 |
|---|---|---|
| all | 全部 | 匹配所有事件类。 |
| aa | 认证与授权 | |
| ad | 管理 | 面向系统整体的管理操作。 |
| ap | 应用程序 | 应用程序定义的操作。 |
| cl | 文件关闭 | 审计对 close 系统调用的调用。 |
| ex | 执行 | 审计程序执行。命令行参数和环境变量的审计通过 audit_control 中的 policy 设置,使用 argv 和 envv 参数控制。 |
| fa | 文件属性访问 | 审计对象属性的访问,如 stat(1) 和 pathconf(2)。 |
| fc | 文件创建 | 审计文件创建相关事件。 |
| fd | 文件删除 | 审计文件删除相关事件。 |
| fm | 文件属性修改 | 审计文件属性修改相关事件,如 chown(8)、chflags(1) 和 flock(2)。 |
| fr | 文件读取 | 审计读取数据或为读取而打开文件的事件。 |
| fw | 文件写入 | 审计写入数据或写入/修改文件的事件。 |
| io | ioctl | 审计 ioctl 系统调用的使用。 |
| ip | 进程间通信 | 审计各种形式的进程间通信,包括 POSIX 管道和 System V IPC 操作。 |
| lo | 登录_注销 | 审计 login(1) 和 logout(1) 事件。 |
| na | 无归属 | 审计无归属事件。 |
| no | 无效类 | 不匹配任何审计事件。 |
| nt | 网络 | 审计与网络操作相关的事件,如 connect(2) 和 accept(2)。 |
| ot | 其他 | 审计其他杂项事件。 |
| pc | 进程 | 审计进程操作,如 exec(3) 和 exit(3)。 |
可修改配置文件 /etc/security/audit_class 和 /etc/security/audit_event 自定义上述审计事件类。
每个审计事件类可附带前缀,表示匹配成功或失败的操作,以及该条目为该类及类型增加还是移除匹配。审计事件类前缀汇总如下:
| 前缀 | 操作 |
|---|---|
| + | 审计该类中成功的事件。 |
| - | 审计该类中失败的事件。 |
| ^ | 既不审计该类中成功也不审计失败的事件。 |
| ^+ | 不审计该类中成功的事件。 |
| ^- | 不审计该类中失败的事件。 |
如果没有前缀,该事件成功与失败实例均受审计。
以下示例选择字符串选择成功和失败的登录/注销事件,但仅选择成功的执行事件:
lo,+ex17.6.2.2.2 配置文件
安全事件审计的以下配置文件位于路径 /etc/security 中:
/etc/security
├── audit_control -> 控制审计子系统
├── audit_class -> 审计类定义
├── audit_event -> 系统审计事件
├── audit_user -> 用户特定的审计要求
└── audit_warn -> 警告消息脚本- /etc/security/audit_control:控制审计子系统的各方面,如默认审计类、审计日志卷上保留的最小磁盘空间以及最大审计跟踪大小。
- /etc/security/audit_class:包含审计类定义。
- /etc/security/audit_event:系统审计事件的文本名称与描述,以及每个事件所属的类列表。
- /etc/security/audit_user:用户特定的审计要求,在登录时与全局默认值合并。
- /etc/security/audit_warn:由 auditd 使用的可自定义 shell 脚本,用于在异常情况下生成警告消息,例如审计记录空间即将耗尽或审计跟踪文件已完成轮替时。
审计配置文件应谨慎编辑和维护,配置错误可能造成事件日志记录失当。
多数情况下,管理员仅需修改 /etc/security/audit_control 和 /etc/security/audit_user。前者控制系统级审计属性与策略,后者可按用户精细调整审计。
17.6.2.2.2.1 audit_control 文件
可在 /etc/security/audit_control 文件中指定审计子系统的若干默认值:
dir:/var/audit
dist:off
flags:lo,aa
minfree:5
naflags:lo,aa
policy:cnt,argv
filesz:2M
expire-after:10M以上是基本系统中 /etc/security/audit_control 文件的默认值,其源代码位于 contrib/openbsm/etc/audit_control。
作用解释:
| 条目 | 作用 | 说明 |
|---|---|---|
dir | 审计日志目录 | 设定一个或多个审计日志存储目录;如果有多个,则按顺序依次写满后切换;通常建议使用独立文件系统以避免写满影响其他系统组件。 |
dist | 分发(硬链接) | 设为 on 或 yes 时,在 /var/audit/dist 中为所有审计跟踪文件创建硬链接。 |
flags | 默认预选择掩码(有归属事件) | 定义系统范围内“有归属事件”的默认审计类;例如登录/注销成功与失败、认证与授权等事件。 |
minfree | 最小空闲空间 | 指定审计日志所在文件系统允许的最小剩余空间百分比。 |
naflags | 无归属事件掩码 | 指定“无归属事件”应审计的类别,例如登录/注销过程及认证与授权。 |
policy | 审计策略 | 以逗号分隔的策略标志列表;cnt 表示审计失败时系统继续运行(推荐),argv 表示记录 execve(2) 的命令行参数。 |
filesz | 跟踪文件大小限制 | 指定单个审计跟踪文件自动终止并轮替前的最大大小;0 表示禁用自动轮替;小于 512k 的值会被忽略并记录日志。 |
expire-after | 日志过期策略 | 指定审计日志文件的到期时间,到期后自动删除。 |
17.6.2.2.2.2 audit_user 文件
管理员可在 /etc/security/audit_user 文件中为特定用户指定更多审计要求。
每行以两个字段为用户配置审计:
alwaysaudit字段指定始终对该用户审计的事件集neveraudit字段指定始终不对该用户审计的事件集。
audit_user 文件默认值如下:
root:lo:no以下示例条目为 root 用户审计登录/注销事件和成功的命令执行,为 www 用户审计文件创建和成功的命令执行。配合默认 audit_control 时,root 的 lo 条目多余,www 的登录/注销事件也会受审计。
root:lo,+ex:no
www:fc,+ex:no17.6.2.3 处理审计跟踪
由于审计跟踪以 BSM 二进制格式存储,FreeBSD 提供了若干内置工具用于修改或转换为文本。要将跟踪文件转换为简易文本格式,可使用 praudit。
要精简审计跟踪文件以供分析、归档或打印,可使用 auditreduce。此工具支持多种选择参数:事件类型、事件类、用户、事件日期或时间,以及操作所涉文件路径或对象。例如,以纯文本形式转储指定审计日志的全部内容:
# praudit /var/audit/审计日志其中 审计日志 为要转储的审计日志。
审计跟踪由一系列审计记录组成,每条记录由若干令牌(token)构成,praudit 按顺序每行打印一个。
每个令牌均属特定类型,例如 header(审计记录头)或 path(名称查找产生的文件路径)。
以下为一条 execve 事件的示例:
header,133,10,execve(2),0,Mon Sep 25 15:58:03 2006, + 384 msec
exec arg,finger,doug
path,/usr/bin/finger
attribute,555,root,wheel,90,24918,104944
subject,robert,root,wheel,root,wheel,38439,38032,42086,128.232.9.100
return,success,0
trailer,133此审计记录表示一次成功的 execve 调用,执行了 finger doug 命令。
解释:
exec arg令牌包含 shell 传递给内核的已处理命令行。path令牌持有内核查找到的可执行文件路径。attribute令牌描述该二进制文件,含文件模式。subject令牌存储审计用户 ID、有效用户 ID 和组 ID、真实用户 ID 和组 ID、进程 ID、会话 ID、端口 ID 以及登录地址。
注意
审计用户 ID 与真实用户 ID 不同,因用户
robert执行此命令前已切换至root账户,但命令仍以原始认证用户审计。
return令牌指示执行成功,trailer结束该记录。
由于审计日志可能异常庞大,可使用 auditreduce 选取记录子集。以下示例选取审计日志文件中(AUDITFILE 为占位符,需替换为实际文件名,如 20240521140528.not_terminated)为用户 trhodes 产生的所有审计记录:
# auditreduce -u trhodes /var/audit/AUDITFILE | prauditaudit 组默认为空,故仅 root 可读 /var/audit 中的审计跟踪;将用户加入 audit 组可授予审计审阅权限。
审计日志含敏感信息,故建议审慎授予审计审阅权限。
17.6.2.3.1 使用审计管道进行实时监控
审计管道为可克隆伪设备,应用程序可借此接入实时审计记录流,主要面向入侵检测和系统监控程序开发者。审计管道设备也为管理员提供了便捷的实时监控手段,不受审计跟踪文件所有权或日志轮替中断事件流的影响。要追踪实时审计事件流:
# praudit /dev/auditpipe默认情况下,审计管道设备节点仅可由 root 用户访问。要使 audit 组成员也能访问,可在 /etc/devfs.rules 中添加一条 devfs 规则:
add path 'auditpipe*' mode 0440 group audit审计事件容易产生反馈循环:每查看一条审计事件便会生成更多审计事件。例如,如果审计了所有网络 I/O,并通过 SSH 会话运行 praudit,则会持续高速产生审计事件流,因为打印的每个事件都会触发新事件。因此建议在无细粒度 I/O 审计的会话中运行 praudit(接审计管道设备)。
17.6.2.3.2 轮替与压缩审计跟踪文件
审计跟踪由内核写入,审计守护进程 auditd 管理。管理员不应使用 newsyslog.conf(5) 等工具直接轮替审计日志,应改用 audit 关闭审计、重新配置并轮替日志。以下命令令审计守护进程创建新审计日志,并通知内核切换。旧日志终止后重命名,可供管理员后续处理:
# audit -n如果 auditd 当前未运行,此命令失败并报错。
在 /etc/crontab 中加入以下行,每 12 小时执行一次轮替:
0 */12 * * * root /usr/sbin/audit -n保存 /etc/crontab 文件后此更改即生效。
基于文件大小自动轮替审计跟踪文件可通过 audit_control 中的 filesz 实现。
审计跟踪文件可能变得极大,审计守护进程关闭跟踪后,通常需压缩或归档。audit_warn 脚本可针对各类审计事件执行自定义操作,包括跟踪在轮替时正常终止的情形。例如,可在 /etc/security/audit_warn 中添加以下内容,以在关闭时压缩审计跟踪:
#
# Compress audit trail files on close.
#
if [ "$1" = closefile ]; then
gzip -9 $2
fi其他归档操作可能含复制跟踪文件至中央服务器、删除旧跟踪文件,或精简审计跟踪以移除不需要的记录。此脚本仅在审计跟踪文件正常终止时运行,非正常关机遗留的未终止跟踪则不触发。
17.6.3 课后习题
启用进程记账功能后,在系统中执行一系列操作(创建文件、运行命令、切换用户),使用
lastcomm导出记录并解释各字段含义,找出对应的记录条目。使用
sa -u生成按用户统计的命令使用报告,分析“cpu”和“re”两列的含义差异,说明为何这两个值通常不相等。讨论进程记账可能带来的隐私问题及多用户系统中的应对措施。