19.16. 加密磁盘分区

Contributed by Lucky Green.

FreeBSD 提供了极好的数据保护措施,防止未受权的数据访问。 文件权限和强制访问控制(MAC)(看 第 17 章 强制访问控制) 可以帮助预防在操作系统处于运行状态和计算机加电时未受权的第三方访问数据。 但是,和操作系统强制受权不相关的是,如果黑客有物理上访问计算机的可能, 那他就可以简单的把计算机的硬件安装到另一个系统上复制出敏感的数据。

无论攻击者如何取得停机后的硬件或硬盘驱动器本身, FreeBSD GEOM Based Disk Encryption (基于 GEOM 的磁盘加密, gbde)geli 加密子系统都能够保护计算机上的文件系统数据, 使它们免受哪怕是训练有素的攻击者获得有用的资源。 与那些只能加密单个文件的笨重的加密方法不同, gbdegeli 能够透明地加密整个文件系统。 明文数据不会出现在硬盘的任何地方。

19.16.1. 使用 gbde 对磁盘进行加密

  1. 成为 root

    配置 gbde 需要超级用户的权力。

    % su -
    Password:
  2. 在内核配置文件中添加对 gbde(4) 的支持

    在您的内核配置中加入下面一行:

    options GEOM_BDE

    按照 第 9 章 配置FreeBSD的内核 所进行的介绍重新编译并安装内核。

    重新引导进入新的内核。

  3. 另一种无需重新编译内核的方法, 是使用 kldload 来加载 gbde(4)

    # kldload geom_bde

19.16.1.1. 准备加密盘

下面这个例子假设您添加了一个新的硬盘在您的系统并将拥有一个单独的加密分区。 这个分区将挂接在 /private目录下。 gbde 也可以用来加密 /home/var/mail, 但是这需要更多的复杂命令来执行。

  1. 添加新的硬盘

    添加新的硬盘到系统中可以查看在 第 19.3 节 “添加磁盘” 中的说明。 这个例子的目的是说明一个新的硬盘分区已经添加到系统中如: /dev/ad4s1c。在例子中 /dev/ad0s1* 设备代表系统中存在的标准 FreeBSD 分区。

    # 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 Lock 文件

    # mkdir /etc/gbde

    gbde lock 文件包含了 gbde 需要访问的加密分区的信息。 没有 lock 文件, gbde 将不能解密包含在加密分区上的数据。 每个加密分区使用一个独立的 lock 文件。

  3. 初始化 gbde 分区

    一个 gbde 分区在使用前必须被初始化, 这个初始化过程只需要执行一次:

    # gbde init /dev/ad4s1c -i -L /etc/gbde/ad4s1c.lock

    gbde(8) 将打开您的编辑器, 提示您去设置在一个模板文件中的配置变量。 使用 UFS1 或 UFS2,设置扇区大小为 2048:

    $FreeBSD: src/sbin/gbde/template.txt,v 1.1 2002/10/20 11:16:13 phk Exp $
    #
    # Sector size is the smallest unit of data which can be read or written.
    # Making it too small decreases performance and decreases available space.
    # Making it too large may prevent filesystems from working.  512 is the
    # minimum and always safe.  For UFS, use the fragment size
    #
    sector_size     =       2048
    [...]
    

    gbde(8) 将让您输入两次用来加密数据的密钥短语。 两次输入的密钥必须相同。 gbde 保护您数据的能力依靠您选择输入的密钥的质量。 [10]

    gbde init 命令为您的 gbde 分区创建了一个 lock 文件, 在这个例子中存储在 /etc/gbde/ad4s1c.lock中。 gbde lock 文件必须使用 .lock 扩展名才能够被 /etc/rc.d/gbde 启动脚本正确识别。

    小心:

    gbde lock 文件 必须 和加密分区上的内容同时备份。 如果发生只有 lock 文件遭到删除的情况时, 就没有办法确定 gbde 分区上的数据是否是解密过的。 另外, 如果没有 lock 文件, 即使磁盘的合法主人, 不经过大量细致的工作也无法访问加密分区上的数据, 而这是在设计 gbde(8) 时完全没有考虑过的。

  4. 把加密分区和内核进行关联

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

    在加密分区的初始化过程中您将被要求提供一个密码短语。 新的加密设备将在 /dev 中显示为 /dev/device_name.bde

    # 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. 在加密设备上创建文件系统

    当加密设备和内核进行关联后, 您就可以使用 newfs(8) 在此设备上创建文件系统, 使用 newfs(8) 来初始化一个 UFS2 文件系统比初始化一个 UFS1 文件系统还要快,摧荐使用 -O2 选项。

    # newfs -U -O2 /dev/ad4s1c.bde

    注意:

    newfs(8) 命令必须在一个 gbde 分区上执行, 这个分区通过一个存在的 *.bde 设备名进行标识。

  6. 挂接加密分区

    为加密文件系统创建一个挂接点。

    # mkdir /private

    挂接加密文件系统。

    # mount /dev/ad4s1c.bde /private
  7. 校验加密文件系统是否有效

    加密的文件系统现在对于 df(1) 应该可见并可以使用。

    % 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

19.16.1.2. 挂接已有的加密文件系统

每次系统启动后, 在使用加密文件系统前必须和内核重新进行关联, 校验错误和再次挂接。使用的命令必须由 root用户来执行。

  1. 关联 gbde 分区到内核

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

    接下来系统将提示您输入在初始化加密的 gbde 分区时所用的密码短语。

  2. 校验文件系统错误

    加密文件系统不能列在 /etc/fstab 文件中进行自动加载, 在加载前必须手动运行 fsck(8) 命令对文件系统进行错误检测。

    # fsck -p -t ffs /dev/ad4s1c.bde
  3. 挂接加密文件系统

    # mount /dev/ad4s1c.bde /private

    加密后的文件系统现在可以有效使用。

19.16.1.2.1. 自动挂接加密分区

可以创建脚本来自动地附加、 检测, 并挂接加密分区, 然而, 处于安全考虑, 这个脚本不应包含 gbde(8) 密码。 因而, 我们建议这类脚本在控制台或通过 ssh(1) 执行并要求用户输入口令。

除此之外, 系统还提供了一个 rc.d 脚本。 这个脚本的参数可以通过 rc.conf(5) 来指定, 例如:

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

在启动时将要求输入 gbde 的口令。 在输入正确的口令之后, gbde 加密分区将被自动挂接。 对于将 gbde 用在笔记本电脑上时, 这就很有用了。

19.16.1.3. gbde 提供的密码学保护

gbde(8) 采用 CBC 模式的 128-位 AES 来加密扇区数据。 磁盘上的每个扇区都采用不同的 AES 密钥来加密。 要了解关于 gbde 的密码学设计, 包括扇区密钥如何从用户提供的口令字中生成等细节, 请参考 gbde(4)

19.16.1.4. 兼容性问题

sysinstall(8) 是和 gbde 加密设备不兼容的。 在启动 sysinstall(8) 时必须将 *.bde 设备和内核进行分离,否则在初始化探测设备时将引起冲突。 与加密设备进行分离在我们的例子中使用如下的命令:

# gbde detach /dev/ad4s1c

还需要注意的是, 由于 vinum(4) 没有使用 geom(4) 子系统, 因此不能同时使用 gbdevinum 卷。

19.16.2. 使用 geli 对磁盘进行加密

撰写者 Daniel Gerzo.

还有另一个可用于加密的 GEOM class ── geli。 它目前由 Paweł Jakub Dawidek 开发。 Geli 工具与 gbde 不同; 它提供了一些不同的功能, 并采用了不同的方式来进行密码学运算。

geli(8) 最重要的功能包括:

  • 使用了 crypto(9) 框架 ── 如果系统中有加解密硬件加速设备, 则 geli 会自动加以利用。

  • 支持多种加密算法 (目前支持 AES、 Blowfish, 以及 3DES)。

  • 允许对根分区进行加密。 在系统启动时, 将要求输入用于加密根分区的口令。

  • 允许使用两个不同的密钥 (例如, 一个 个人密钥 和一个 公司密钥)。

  • geli 速度很快 ── 它只进行简单的扇区到扇区的加密。

  • 允许备份和恢复主密钥。 当用户必须销毁其密钥时, 仍然可以通过从备份中恢复密钥来存取数据。

  • 允许使用随机的一次性密钥来挂接磁盘 ── 这对于交换区和临时文件系统非常有用。

更多 geli 功能介绍可以在 geli(8) 联机手册中找到。

下面的步骤介绍了如何启用 FreeBSD 内核中的 geli 支持, 并解释了如何创建新和使用 geli 加密 provider。

由于需要修改内核, 您需要拥有超级用户权限。

  1. 在内核中加入 geli 支持

    在内核配置文件中加入下面两行:

    options GEOM_ELI
    device crypto

    按照 第 9 章 配置FreeBSD的内核 介绍的步骤重新编译并安装内核。

    另外, geli 也可以在系统引导时加载。 这是通过在 /boot/loader.conf 中增加下面的配置来实现的:

    geom_eli_load="YES"

    geli(8) 现在应该已经为内核所支持了。

  2. 生成主密钥

    下面的例子讲描述如何生成密钥文件, 它将作为主密钥 (Master Key) 的一部分, 用于挂接到 /private 的加密 provider。 这个密钥文件将提供一些随机数据来加密主密钥。 同时, 主密钥也会使用一个口令字来保护。 Provider 的扇区尺寸为 4kB。 此外, 这里的讨论将介绍如何挂载 geli provider, 在其上创建文件系统, 如何挂接并在其上工作, 最后将其卸下。

    建议您使用较大的扇区尺寸 (例如 4kB), 以获得更好的性能。

    主密钥将由口令字保护, 而密钥文件的数据来源则将是 /dev/random。 我们称之为 provider 的 /dev/da2.eli 的扇区尺寸将是 4kB。

    # dd if=/dev/random of=/root/da2.key bs=64 count=1
    # geli init -s 4096 -K /root/da2.key /dev/da2
    Enter new passphrase:
    Reenter new passphrase:

    同时使用口令字和密钥文件并不是必须的; 您也可以只使用其中的一种来加密主密钥。

    如果密钥文件写作 -, 则表示使用标准输入。 下面是关于如何使用多个密钥文件的例子:

    # cat keyfile1 keyfile2 keyfile3 | geli init -K - /dev/da2
  3. 将 provider 与所生成的密钥关联

    # geli attach -k /root/da2.key /dev/da2
    Enter passphrase:

    新的明文设备将被命名为 /dev/da2.eli

    # ls /dev/da2*
    /dev/da2  /dev/da2.eli
  4. 创建新的文件系统

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

    现在加密的文件系统应该已经可以被 df(1) 看到, 并处于可用状态了:

    # 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
  5. 卸下卷并断开 provider

    一旦在加密分区上的工作完成, 并且不再需要 /private 分区, 就应考虑将其卸下并将 geli 加密分区从内核上断开。

    # umount /private
    # geli detach da2.eli

关于如何使用 geli(8) 的更多信息, 可以在其联机手册中找到。

19.16.2.1. 使用 geli rc.d 脚本

geli 提供了一个 rc.d 脚本, 它可以用于简化 geli 的使用。 通过 rc.conf(5) 配置 geli 的方法如下:

geli_devices="da2"
geli_da2_flags="-p -k /root/da2.key"

这将把 /dev/da2 配置为一个 geli provider, 其主密钥文件位于 /root/da2.key, 而 geli 在连接 provider 时将不使用口令字 (注意只有在 geli init 阶段使用了 -P 才可以这样做)。 系统将在关闭之前将 geli provider 断开。

关于如何配置 rc.d 的详细信息可以在使用手册的 rc.d 一节中找到。



[10] 这个提示教您怎样选择一个安全易记的密钥短语, 请看 Diceware Passphrase 网站。

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.