> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/di-28-zhang-an-quan-shen-ji/di-28.2-jie-ru-qin-jian-ce-xi-tong-ids.md).

# 28.2 入侵检测系统（IDS）

mtree 以种子值生成目录校验和规范，可事后比对以识别文件变更。本节介绍规范创建、模拟篡改和校验验证的完整流程。

## 入侵检测系统（IDS）

验证系统文件和二进制文件的完整性，是系统管理与安全团队掌握变更情况的重要手段。凡能监控系统变更的软件，统称为入侵检测系统（Intrusion Detection System, IDS）。

FreeBSD 原生内置基本 IDS——mtree。不过，每夜安全邮件虽会通报变更，但信息存储于本地，恶意用户仍有机会篡改记录以掩盖其操作。因此，宜另建一套独立的二进制签名，置于只读、属主为 root 的目录；存放在可移动 USB 磁盘或远程服务器上更佳。

```sh
初始阶段（建立基线）：
  目录（/bin 等）
     │
     │  mtree -s 种子值 -c
     ▼
  规范文件（含校验和）
     │
     │  安全存储（USB/远程服务器）
     ▼
  基线建立

验证阶段（检测变更）：
  目录（当前状态）
     │
     │  mtree -s 种子值（相同种子）
     ▼
  与规范文件比对
     │
     ├── 一致 ──► 无变更
     │
     │ 不一致
     ▼
  报告变更文件
```

建议在每次更新后运行 `freebsd-update IDS`。目前该命令与 PkgBase 不兼容，报错如下：

```sh
freebsd-update is incompatible with the use of packaged base.  Please see
https://wiki.freebsd.org/PkgBase for more information.
```

## 生成规范文件

内置的 mtree 工具可生成目录内容的规范。规范的生成依赖种子值（数值常量），后续检查同样需要它，以此判断文件或二进制文件是否遭修改。攻击者无法获知种子值，伪造或比对校验和将极其困难，甚至不可行。

建议为存放二进制和配置文件的目录，以及所有包含敏感数据的目录生成规范。常见对象包含 **/bin**、**/sbin**、**/usr/bin**、**/usr/sbin**、**/usr/local/bin**、**/etc** 和 **/usr/local/etc**。

下面的示例为 **/bin** 下的每个系统二进制文件生成一组 SHA-512 哈希值，并存入用户主目录下的隐藏文件 **/home/ykla/.bin\_chksum\_mtree**：

```sh
# mtree -s 123456789 -c -K cksum,sha512 -p /bin > /home/ykla/.bin_chksum_mtree
```

> **技巧**
>
> 上述示例中的 `123456789`、**/home/ykla** 为占位符，须替换为实际的值。

`123456789` 代表种子值，应随机选取。种子值应牢记，且不应泄露。

输出应类似于以下内容：

```sh
mtree: /bin checksum: 492144657
```

同时应防止恶意用户获取种子值与校验和输出结果。

## 规范文件结构

mtree 格式描述文件系统对象集合，通常用于创建或验证目录层次结构。

mtree 文件由一系列行组成，每行描述一个文件系统对象（mtree 始终忽略前导空白）。

FreeBSD 系统规范存放于 **/etc/mtree** 目录中。

前面创建的规范文件可说明其格式与内容：

```sh
#	   user: ykla	# 创建规范的用户
#	machine: ykla	# 机器的主机名
#	   tree: /bin	# 目录路径
#	   date: Mon May  4 18:35:28 2026	# 规范生成的日期和时间

# .
/set type=file uid=0 gid=0 mode=0555 nlink=1 flags=uarch	# ①
.               type=dir mode=0755 nlink=2 time=1777888070.971124000
    \133        nlink=2 size=11384 time=1777874933.000000000 \
                cksum=490895202 \	# ②
                sha512=a86c4119b31f6b51a61de9b257e195f3809ed16360ba1bec7f75a13e10c24c2959338f59735f8fea76cf32b140194487080b2dd33374d09cf003ea0cf5ccfbf2
    cat         size=13424 time=1777874930.000000000 cksum=3028726120 \	# ③
                sha512=3512dafe9764cd4dd94941cd0e9fb35f3c430bb39bd2897fe1011d33b7477bf2e7bf0dd4cc0268aef42ee87dafa987c6e1a3c96a8062ab27feb737849422ecc6
    chflags     size=7944 time=1777874930.000000000 cksum=3958012774 \	# ③

……以下省略部分输出……
```

内容解释：

* ①：`/set` 特殊命令，定义从分析文件中提取的部分设置。
* ②：引用解析目录，表示其类型、模式、硬链接数及 UNIX 格式修改时间等信息。
* ③：引用一份文件，展示其大小、时间及一系列完整性校验哈希值。

## 验证规范文件

要验证二进制文件是否发生变更，可将目录当前内容与先前规范进行比较，并将结果写入文件。

该命令需要生成原始规范时所用的种子值：

```sh
# mtree -s 123456789 -p /bin < /home/ykla/.bin_chksum_mtree >> /home/ykla/.bin_chksum_output
```

该命令应当输出与创建规范时一致的 **/bin** 校验和。

```sh
mtree: /bin checksum: 492144657
```

如果目录中的二进制文件未曾变更，**/home/ykla/.bin\_chksum\_output** 将是一个空文件。

```sh
# cat /home/ykla/.bin_chksum_output
#
```

为了模拟一次变更，可先用 `touch` 修改 **/bin/cat** 的时间戳，再执行验证命令：

```sh
# touch /bin/cat
```

再次运行验证命令：

```sh
# mtree -s 123456789 -p /bin < /home/ykla/.bin_chksum_mtree >> /home/ykla/.bin_chksum_output
mtree: /bin checksum: 492144657
```

随后检查 **/home/ykla/.bin\_chksum\_output** 文件的输出内容：

```sh
# cat /home/ykla/.bin_chksum_output
```

输出应类似于以下内容：

```sh
cat:    modification time (Mon May  4 14:08:50 2026, Mon May  4 18:42:53 2026)
```

以上为命令输出示例，说明元数据修改后的情形。

## 课后习题

1. 使用 `mtree` 为 **/etc** 目录创建完整性基线，随后人为修改 **/etc/motd** 并添加一名用户，再次运行 `mtree` 检测变更。将检测输出与各项修改操作逐一对应，说明每条检测记录的含义。
2. 查阅 AIDE（Advanced Intrusion Detection Environment）的文档，比较 `mtree` 与 AIDE 在功能特性上的差异，说明在生产环境中为何通常选择 AIDE 而非系统自带的 `mtree`。
3. 设计一个实验：安装一个 rootkit 演示工具（如 `chkrootkit`），运行后阅读其检测逻辑，结合 IDS 的原理分析为什么完整性校验工具能够或不能检测出内核级 rootkit。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/di-28-zhang-an-quan-shen-ji/di-28.2-jie-ru-qin-jian-ce-xi-tong-ids.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
