# 20.12.加密磁盘分区

## 20.12.1. 使用 gbde 进行磁盘加密

[gbde(4)](https://man.freebsd.org/cgi/man.cgi?query=gbde\&sektion=4\&format=html) 工具的目标是为攻击者提供极大的挑战，防止其访问 *冷存储* 设备的内容。但是，如果计算机在运行时被攻击并且存储设备已被附加，或者攻击者拥有有效的密码短语，它将不会保护存储设备的内容。因此，提供物理安全性是非常重要的，同时也需要保护加密机制所使用的密码短语。

此工具提供了几个障碍来保护每个磁盘扇区中存储的数据。它使用 128 位 AES CBC 模式加密磁盘扇区的内容。磁盘上的每个扇区都使用不同的 AES 密钥进行加密。有关加密设计的更多信息，包括扇区密钥是如何从用户提供的密码短语派生的，请参阅 [gbde(4)](https://man.freebsd.org/cgi/man.cgi?query=gbde\&sektion=4\&format=html)。

FreeBSD 提供了内核模块 gbde，可以使用以下命令加载：

```sh
# kldload geom_bde
```

如果使用的是自定义内核配置文件，请确保它包含以下行：

```ini
options GEOM_BDE
```

以下示例演示了如何向系统添加一块新的硬盘，该硬盘将持有一个加密分区，并将其挂载为 **/private**。

**过程：使用 gbde 加密分区**

1. **添加新硬盘**\
   按照 [添加磁盘](https://docs.freebsd.org/en/books/handbook/disks/#disks-adding) 中的说明将新硬盘安装到系统中。对于本示例，已添加新硬盘分区 **/dev/ad4s1c**，**/dev/ad0s1\*** 代表现有的标准 FreeBSD 分区。

   ```sh
   # ls /dev/ad*
   /dev/ad0        /dev/ad0s1b     /dev/ad0s1e     /dev/ad4s1
   /dev/ad0s1      /dev/ad0s1c     /dev/ad0s1f     /dev/ad4s1c
   /dev/ad0s1a     /dev/ad0s1d     /dev/ad4
   ```
2. **创建用于存储 `gbde` 锁文件的目录**

   ```sh
   # mkdir /etc/gbde
   ```

   gbde 锁文件包含 gbde 访问加密分区所需的信息。如果没有访问锁文件，gbde 将无法解密加密分区中的数据，且不支持进行任何手动干预。每个加密分区使用一个单独的锁文件。
3. **初始化 `gbde` 分区**\
   在使用之前，必须初始化 gbde 分区。此初始化只需要执行一次。执行此命令后将打开默认编辑器，以便在模板中设置各种配置选项。对于 UFS 文件系统，将 `sector_size` 设置为 2048：

   ```sh
   # gbde init /dev/ad4s1c -i -L /etc/gbde/ad4s1c.lock
   #
   # 扇区大小是可以读取或写入的最小数据单位。
   # 将其设置得过小会降低性能并减少可用空间。
   # 将其设置得过大可能会导致文件系统无法正常工作。512 是
   # 最小值且始终安全。对于 UFS，请使用碎片大小

   sector_size	=	2048
   [...]
   ```

   保存编辑后，用户需要两次输入在初始化加密分区时选择的密码短语。密码短语必须一致。gbde 保护数据的能力完全依赖于密码短语的质量。有关如何选择既安全又易于记住的密码短语的提示，请参见 [http://world.std.com/\~reinhold/diceware.htm](http://world.std.com/~reinhold/diceware.html)。

   此初始化会为 gbde 分区创建一个锁文件。在本示例中，它存储为 **/etc/gbde/ad4s1c.lock**。锁文件必须以 ".lock" 结尾，以便 **/etc/rc.d/gbde** 启动脚本能够正确检测。

   > **注意**
   >
   > 锁文件 *必须* 与任何加密分区的内容一起备份。没有锁文件，合法所有者将无法访问加密分区上的数据。
4. **将加密分区附加到内核**

   ```sh
   # gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c.lock
   ```

   此命令将提示输入在加密分区初始化时选择的密码短语。新加密设备将出现在 **/dev** 目录中，名称为 **/dev/device\_name.bde**：

   ```sh
   # ls /dev/ad*
   /dev/ad0        /dev/ad0s1b     /dev/ad0s1e     /dev/ad4s1
   /dev/ad0s1      /dev/ad0s1c     /dev/ad0s1f     /dev/ad4s1c
   /dev/ad0s1a     /dev/ad0s1d     /dev/ad4        /dev/ad4s1c.bde
   ```
5. **在加密设备上创建文件系统**\
   待加密设备附加到内核，就可以在设备上创建文件系统。此示例创建一个启用了软更新的 UFS 文件系统。确保指定具有 **\*.bde** 扩展名的分区：

   ```sh
   # newfs -U /dev/ad4s1c.bde
   ```
6. **挂载加密分区**\
   创建一个挂载点并挂载加密文件系统：

   ```sh
   # mkdir /private
   # mount /dev/ad4s1c.bde /private
   ```
7. **验证加密文件系统是否可用**\
   现在，加密文件系统应该可见并可用：

   ```sh
   % df -H
   Filesystem        Size   Used  Avail Capacity  Mounted on
   /dev/ad0s1a      1037M    72M   883M     8%    /
   /devfs            1.0K   1.0K     0B   100%    /dev
   /dev/ad0s1f       8.1G    55K   7.5G     0%    /home
   /dev/ad0s1e      1037M   1.1M   953M     0%    /tmp
   /dev/ad0s1d       6.1G   1.9G   3.7G    35%    /usr
   /dev/ad4s1c.bde   150G   4.1K   138G     0%    /private
   ```

每次启动后，必须手动将加密文件系统重新附加到内核、检查错误并挂载，才能使用文件系统。为了配置这些步骤，可以将以下行添加到 **/etc/rc.conf**：

```sh
gbde_autoattach_all="YES"
gbde_devices="ad4s1c"
gbde_lockdir="/etc/gbde"
```

这要求在启动时通过控制台输入密码短语。输入正确的密码短语后，加密分区将自动挂载。更多 gbde 启动选项可以在 [rc.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=rc.conf\&sektion=5\&format=html) 中查看。

> **当心**
>
> sysinstall 与 gbde 加密的设备不兼容。所有 **\*.bde** 设备在启动 sysinstall 之前必须从内核中分离，否则它将在初始设备探测期间崩溃。要分离示例中使用的加密设备，请使用以下命令：
>
> ```sh
> # gbde detach /dev/ad4s1c
> ```

## 20.12.2. 使用 `geli` 进行磁盘加密

另一种可用的加密 GEOM 类是 `geli`。该控制实用程序提供了一些功能，并使用不同的加密方案进行工作。它提供以下特性：

* 利用 [crypto(9)](https://man.freebsd.org/cgi/man.cgi?query=crypto\&sektion=9\&format=html) 框架，并在可用时自动使用加密硬件。
* 支持多种加密算法，如 AES-XTS、AES-CBC 和 Camellia-CBCAES。
* 允许加密根分区。在系统启动时，将要求输入用于访问加密根分区的密码。
* 允许使用两个独立的密钥。
* 它执行简单的扇区到扇区的加密，因此速度很快。
* 允许备份和恢复主密钥。如果用户销毁了他们的密钥，仍然可以通过恢复备份的密钥来访问数据。
* 允许使用随机的一次性密钥附加磁盘，这对于交换分区和临时文件系统非常有用。

更多功能和使用示例可以参考 [geli(8)](https://man.freebsd.org/cgi/man.cgi?query=geli\&sektion=8\&format=html)。

以下示例描述了如何生成一个密钥文件，该文件将作为加密提供者的主密钥的一部分，挂载在 **/private** 下。该密钥文件将提供一些随机数据，用于加密主密钥。主密钥也将由密码保护。提供者的扇区大小将设置为 4kB。该示例描述了如何附加到 `geli` 提供者，如何在其上创建文件系统、挂载、操作并最终如何卸载它。

**过程：使用 `geli` 加密分区**

1. 加载 `geli` 支持`geli` 支持作为可加载的内核模块提供。要配置系统在启动时自动加载该模块，请将以下行添加到 **/boot/loader.conf**：

   ```sh
   geom_eli_load="YES"
   ```

   要立即加载内核模块：

   ```sh
   # kldload geom_eli
   ```

   对于自定义内核，确保内核配置文件包含以下行：

   ```sh
   options GEOM_ELI
   device crypto
   ```
2. 生成主密钥\
   以下命令生成一个主密钥，所有数据都将使用该密钥进行加密。此密钥不可更改。它不会直接使用，而是使用一个或多个用户密钥对其进行加密。用户密钥由一个可选的组合构成，包括来自文件 **/root/da2.key** 的随机字节和/或密码。在此例中，密钥文件的数据源是 **/dev/random**。此命令还将提供者的扇区大小设置为 4kB，以提高性能：

   ```sh
   # dd if=/dev/random of=/root/da2.key bs=64 count=1
   # geli init -K /root/da2.key -s 4096 /dev/da2
   输入新密码：
   再次输入新密码：
   ```

   使用密码和密钥文件并不是强制性的，可以单独使用任何一种方法来保护主密钥。

   如果密钥文件作为 "-" 提供，将使用标准输入。例如，以下命令生成三个密钥文件：

   ```sh
   # cat keyfile1 keyfile2 keyfile3 | geli init -K - /dev/da2
   ```
3. 使用生成的密钥附加提供者\
   要附加提供者，请指定密钥文件、磁盘名称和密码：

   ```sh
   # geli attach -k /root/da2.key /dev/da2
   输入密码：
   ```

   这将创建一个新的设备，扩展名为 **.eli**：

   ```sh
   # ls /dev/da2*
   /dev/da2  /dev/da2.eli
   ```
4. 创建新文件系统\
   接下来，使用 UFS 文件系统格式化该设备，并将其挂载到现有挂载点：

   ```sh
   # dd if=/dev/random of=/dev/da2.eli bs=1m
   # newfs /dev/da2.eli
   # mount /dev/da2.eli /private
   ```

   加密文件系统现在应该可以使用：

   ```sh
   # df -H
   Filesystem     Size   Used  Avail Capacity  Mounted on
   /dev/ad0s1a    248M    89M   139M    38%    /
   /devfs         1.0K   1.0K     0B   100%    /dev
   /dev/ad0s1f    7.7G   2.3G   4.9G    32%    /usr
   /dev/ad0s1d    989M   1.5M   909M     0%    /tmp
   /dev/ad0s1e    3.9G   1.3G   2.3G    35%    /var
   /dev/da2.eli   150G   4.1K   138G     0%    /private
   ```

完成对加密分区的操作后，如果不再需要 **/private** 分区，建议通过卸载并将 `geli` 加密分区从内核中分离来将该设备放入冷存储：

```sh
# umount /private
# geli detach da2.eli
```

提供了一个 **rc.d** 脚本，以简化在启动时挂载 `geli` 加密设备。对于此示例，请将以下行添加到 **/etc/rc.conf**：

```sh
geli_devices="da2"
geli_da2_flags="-k /root/da2.key"
```

这将配置 **/dev/da2** 作为具有主密钥 **/root/da2.key** 的 `geli` 提供者。在系统关闭之前，系统将自动将提供者从内核中分离。在启动过程中，脚本将提示输入密码，然后附加提供者。启动过程中的其他内核消息可能会在密码提示之前或之后显示。如果启动过程似乎停滞，请仔细查看其他消息中的密码提示。输入正确的密码后，提供者将被附加。然后，文件系统将挂载，通常通过 **/etc/fstab** 中的条目进行挂载。有关如何配置文件系统以在启动时挂载的说明，请参考 [“挂载和卸载文件系统”](https://docs.freebsd.org/en/books/handbook/basics/#mount-unmount)。


---

# Agent Instructions: 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:

```
GET https://handbook.bsdcn.org/di-20-zhang-cun-chu/20.12.-ci-pan-pei-e.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
