# 19.4.使用审计跟踪

由于审计日志以 BSM（二进制审计日志）格式存储，因此提供了几种内置工具来修改或转换这些日志为文本格式。要将审计日志文件转换为简单的文本格式，可以使用 `praudit`。若要减少审计日志文件的大小以便分析、归档或打印，可以使用 `auditreduce`。该工具支持多种选择参数，包括事件类型、事件类别、用户、事件日期或时间，以及操作的文件路径或对象。

例如，要以纯文本格式输出指定审计日志的所有内容：

```sh
# praudit /var/audit/AUDITFILE
```

其中 *AUDITFILE* 是要输出的审计日志文件。

审计日志由一系列审计记录组成，每条记录由多个令牌（tokens）组成，`praudit` 会按顺序逐行打印这些令牌。每个令牌具有特定的类型，如 `header`（审计记录头部）或 `path`（从名称查找的文件路径）。以下是一个 `execve` 事件的示例：

```sh
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` 令牌结束该记录。

还支持 XML 输出格式，可以通过包含 `-x` 选项来选择。

由于审计日志文件可能非常大，可以使用 `auditreduce` 来选择一部分记录。以下示例选择存储在 **AUDITFILE** 中的所有为用户 `trhodes` 生成的审计记录：

```sh
# auditreduce -u trhodes /var/audit/AUDITFILE | praudit
```

属于 `audit` 组的成员有权限读取 **/var/audit** 中的审计日志。默认情况下，`audit` 组为空，因此只有 `root` 用户能够读取审计日志。用户可以被添加到 `audit` 组，以便委派审计检查权限。由于能够跟踪审计日志内容能显著揭示用户和进程行为，因此建议谨慎地进行审计审查权限的委派。

## 19.4.1. 使用审计管道进行实时监控

审计管道是克隆伪设备，允许应用程序连接到实时审计记录流。这对入侵检测和系统监控应用程序的开发者尤为重要。然而，审计管道设备是管理员让实时监控变得方便的一种方式，避免了审计日志文件所有权或日志轮换中断事件流的问题。要跟踪实时的审计事件流，可以使用：

```sh
# praudit /dev/auditpipe
```

默认情况下，审计管道设备节点仅对 `root` 用户可访问。要使其对 `audit` 组的成员可访问，可以在 **/etc/devfs.rules** 中添加以下 `devfs` 规则：

```sh
add path 'auditpipe*' mode 0440 group audit
```

有关配置 devfs 文件系统的更多信息，请参见 [devfs.rules(5)](https://man.freebsd.org/cgi/man.cgi?query=devfs.rules\&sektion=5\&format=html)。

> **警告**
>
> 很容易产生审计事件反馈循环，其中每个审计事件的查看会导致更多审计事件的生成。例如，如果审计了所有的网络 I/O，且在 SSH 会话中运行 `praudit`，将会生成大量的审计事件，因为每个输出的事件都会生成一个新的事件。出于这个原因，建议在没有精细网络 I/O 审计的会话中运行 `praudit`。

## 19.4.2. 审计日志文件的轮换和压缩

审计日志由内核写入，并由审计守护进程 [auditd(8)](https://man.freebsd.org/cgi/man.cgi?query=auditd\&sektion=8\&format=html) 管理。管理员不应尝试使用 [newsyslog.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=newsyslog.conf\&sektion=5\&format=html) 或其他工具直接轮换审计日志。相反，应该使用 `audit` 来关闭审计、重新配置审计系统并执行日志轮换。以下命令会导致审计守护进程创建一个新的审计日志，并向内核发送信号以开始使用新的日志。旧日志将被终止并重命名，此时管理员可以对其进行操作：

```sh
# audit -n
```

如果 [auditd(8)](https://man.freebsd.org/cgi/man.cgi?query=auditd\&sektion=8\&format=html) 当前没有运行，执行此命令将失败，并会产生错误消息。

将以下行添加到 **/etc/crontab** 文件中，将使日志轮换每十二小时执行一次：

```ini
0     */12       *       *       *       root    /usr/sbin/audit -n
```

保存 **/etc/crontab** 后，改动将生效。

可以使用 **audit\_control** 中的 `filesz` 项来基于文件大小自动轮换审计日志文件，具体描述请参见 [The audit\_control File](https://docs.freebsd.org/en/books/handbook/audit/#audit-auditcontrol)。

由于审计日志文件可能非常大，因此通常希望在审计守护进程关闭日志文件后将其压缩或归档。可以使用 **audit\_warn** 脚本来执行多种审计相关事件的定制操作，包括在日志轮换时清理关闭的审计日志文件。例如，以下内容可添加到 **/etc/security/audit\_warn** 中，以便在关闭时压缩审计日志文件：

```sh
#
# 压缩时关闭审计日志文件。
#
if [ "$1" = closefile ]; then
        gzip -9 $2
fi
```

其他归档活动可能包括将日志文件复制到集中式服务器、删除旧日志文件或减少审计日志以删除不需要的记录。此脚本仅在审计日志文件干净地终止时运行，若日志在不正常关闭后仍未终止，则不会执行此脚本。
