第六章:GELI

GELI是FreeBSD最受欢迎的磁盘加密方法。非常适合在冷磁盘上隐藏数据。

首先要加载内核,可以将 geom_eli_load="YES" 添加到 /boot/loader.conf 中,然后重启;或者直接运行 geli load 命令。

GELI使用主密钥(master key)加密geoms。

主密钥保存在物理存储设备上,但使用密钥文件和/或密码短语进行加密。

可以拥有多个密钥文件和密码短语,能够解密主密钥。如果员工忘记了笔记本电脑的密码,管理员可以为他解锁。

GELI优于GBDE。GELI允许加密计算机的根分区。可以验证文件的完整性,具有临时文件系统和交换空间上的一次性密钥的特定功能。甚至可以暂停和恢复加密设备。

在加密层之前,请记住随机化geom。geli(8) 手册页提供了更多信息。


GELI是FreeBSD最受欢迎的磁盘加密方案,这要归功于它的许多功能和灵活性。当您想在冷磁盘上隐藏数据时,GELI是一个不错的选择。如果你想让被盗笔记本电脑的文件无法访问,或者你想预先粉碎你的财务数据存储以便于销毁,GELI是你的朋友。

通过加载内核模块开始玩GELI。您可以在 /boot/loader.conf 中设置 geom_eli_load=“YES” 并重新启动,也可以运行 geli load

GELI使用主密钥对geoms进行加密。此主密钥存储在物理存储设备上,但使用密钥文件和/或密码短语进行加密。您可以设置多个密钥文件和密码短语,能够解密主密钥,这样如果员工忘记了笔记本电脑的密码,公司安全官员就可以为他解锁。

为什么选择GELI而不是GBDE?GELI允许您加密计算机的根分区。

然而,与这些特征相匹配具有复杂性。我们将从单个geom的基本加密开始,然后进行更高级的使用。

在加密层之前,请记住随机化您的geom。还要记住,虽然我对GELI进行了相当广泛的概述,但您可以通过阅读 geli(8) 手册页了解更多信息。

我更喜欢使用标签(labels)来标记加密的geom名称——我更容易记住,我必须激活分区 /dev/label/encrypted1 ,而不是 /dev/da4p3/dev/md6 。我的大多数示例都使用原始设备名称,因为它们更短,在学习时更容易阅读。

第六章:GELIGELI 扇区尺寸GELI基本使用创建GELI密钥文件初始化 GELI 提供者激活GELI设备创建文件系统停用(deactivating)GELI 设备GELI密钥技巧多密钥更改密钥或密码短语没有密码短语的密钥没有密钥文件的密钥擦除主密钥的副本杀掉GELI设备备份和还原GELI元数据密码短语文件一次性密钥GELI调整大小GELI启动rc.conf 中配置GELI在启动加载器(boot loader)中配置GELI排错

GELI 扇区尺寸

在GELI中,扇区大小一词不仅仅是底层物理存储介质上最小分配单元的大小。这也是它加密数据块的大小。

如果将GELI提供者指定为具有512B扇区大小,则它会对每512B的存储执行加密。对写入512B扇区驱动器的文件进行加密所需的加密处理量是将同一个文件写入4096KB扇区驱动器的8倍。

FreeBSD建议GELI始终使用4096KB的扇区大小,即使底层媒体是512B的扇区,以最大限度提高性能。在创建GELI分区时,将其与4096KB扇区对齐。

GELI基本使用

使用GELI需要创建密钥文件(key file),初始化GELI设备,在设备上创建文件系统,然后激活、使用和停用GELI设备。

创建GELI密钥文件

使用 dd(1) 命令获取 /dev/random 并将其转储到文件中,用于创建GELI密钥。对于笔记本电脑或工作站,直接在USB闪存驱动器等可移动介质上创建密钥。

以下示例将密钥文件写入 /media 上的 geli-da0p1.key 文件,提取一个(count=1)64字节的块(bs=64):

64字节是512位,足以满足大多数目的。GELI密钥不可读。

初始化 GELI 提供者

GELI将其设置和主加密密钥存储在geom的最后一个扇区中。例如,如果将分区 /dev/da0p1 加密,则该分区的最后一个扇区就包含了GELI信息。

这与加密文件系统的最后一个扇区不同,后者可能位于底层分区的任何扇区上。

添加此信息会初始化分区。以下操作仅能执行一次,否则会销毁并重建加密分区:

初始化例程有助于打印GELI元数据备份的位置,并为管理员提供如何还原它的说明。

将此备份文件复制到系统外的某个位置。如果底层硬盘发生故障,可以还原替换硬盘上的元数据。


GELI将其设置和主加密密钥存储在geom的最后一个扇区中。我想把我的加密分区放在 /dev/da0p1 上,这样 /dev/da0p1 的最后一个扇区就包含了GELI信息。(这与加密文件系统的最后一个扇区不同,后者可能位于底层分区的任何扇区上。)添加此信息会初始化分区。除非您打算销毁并重新创建加密设备,否则每个GELI分区只能执行一次此操作。

GELI需要两个强制设置,扇区大小和密钥文件。

与任何需要输入新密码的事情一样,geli(8) 会提示您输入两次密码。它不会在您键入密码短语时显示密码。

初始化例程有助于打印GELI元数据备份的位置,并为您提供如何还原它的说明。将此备份文件复制到系统外的某个位置。如果底层硬盘发生故障,您可能需要还原替换硬盘上的元数据。

激活GELI设备

现在已经有了一个密钥和一个准备好的分区。将密钥附加到分区上,启动GELI。再一次使用 -k 指定密钥文件,在这里,我将我的密钥 geli-da0p1.key 附加到分区 da0p1

输入密码短语,GELI在物理分区上创建一个加密的磁盘设备。GELI将其放在 /dev 目录中,而不是 /dev/geli 目录中,并用设备名称加上扩展名 .eli 来命名它。例如 /dev/da0p1.eli

如果想要以只读方式挂载,可以加入 -r 选项。虽然不能在只读设备上创建文件系统,但如果该设备上有文件系统,则可以将其作为自读设备挂载。

创建文件系统

一旦你有了一个加密的存储设备,就像在任何其他存储设备上一样,在它上面创建一个文件系统。我在这里将使用UFS,因为这本书涵盖了UFS,但您可以使用ZFS、FAT32或任何其他文件系统。

加密设备上的UFS文件系统可以使用软更新日志记录。可以在加密磁盘设备上使用任何文件系统功能。感谢GEOM,加密发生在较低层。

停用(deactivating)GELI 设备

完成加密文件系统后,卸载它并将密钥从GELI设备中分离出来:

要再次访问数据,必须重新使用密钥挂载加密的设备。

GELI密钥技巧

GELI支持用钥匙做各种事情。以下一些是我认为最有用的,一些是人们最常问的。(这两个群体不是同义词。)

多密钥

在某些环境中,可能需要多人能够解密GELI设备,每个人有自己单独的密钥。

每个GELI设备都有一个主密钥,在初始化GELI设备时创建。

密钥对每个GELI设备都是唯一的,只要设备存在,密钥就永远不会改变。

GELI使用密码和密码短语来加密和解密主密钥。可以更改密码,可以更改密码短语,但不能更改主密钥,甚至永远不会看到它。

GELI元数据有空间,或称 slots(插槽),用于存储加密主密钥的两个副本。

GELI命令默认使用slot 0。可以在slot 1中添加第二个副本,使用不同的密钥和密码短语进行加密。

如果GELI可以解密主密钥的一个副本,它就可以解密设备并访问文件系统。

一旦有了一个可用的GELI设备,就可以添加第二个密钥和密码短语。使用 geli setkey 命令可以slot 1中的主密钥副本分配密钥文件和密码短语。

按提示输入第二个密码短语。

现在GELI设备有两个key。可以通过密码短语指定任意密钥来附加GELI设备。


在某些环境中,您希望多个人能够解密GELI设备,每个人都有自己的单独密钥。我以前在公司环境中见过这种情况,公司安全官或IT技术主管有一个密钥,系统管理员也有一个。如果系统管理员被车撞了,仍然有人可以解密文件系统。这需要对GELI密钥有更多的了解。

每个GELI设备都有一个主密钥,在初始化GELI设备时创建。密钥对每个GELI设备都是唯一的,只要设备存在,密钥就永远不会改变。GELI使用您的密码短语和密钥文件来加密和解密主密钥。您可以更改密码,可以更改密钥文件,但不能更改主密钥。你甚至永远不会看到它。

GELI元数据有空间,或称 slots(插槽),用于存储加密主密钥的两个副本。GELI命令默认使用 slot 0。您可以在 slot 1 中添加第二个副本,使用不同的密钥和密码短语进行加密。如果GELI可以解密主密钥的一个副本,它就可以解密设备并访问文件系统。一旦你有了一个可用的GELI设备,你就可以添加第二个密钥和密码短语。使用 geli setkey 命令为 slot 1中的主密钥副本分配密钥文件和密码短语。

出现提示时输入第二个密码短语。

GELI设备现在有两个密钥。现在,您可以使用任一密钥及其密码短语来连接GELI设备。

更改密钥或密码短语

更改密钥文件或密码短语就像添加新密钥一样。

严格来说,不能更换密钥。而是用新的加密主密钥加载到两个slot中的一个,覆盖掉现有的加密主密钥。

初始化GELI设备时,GELI会将密钥放在slot 0中,以下示例在那个slot中写入新密钥:

输入新的密码短语,然后就有了新的密钥和密码短语。

没有密码短语的密钥

没有密码短语的GELI密钥会降低GELI的保护。能做,但不该做。

初始化GELI密钥时,添加 -P 选项可以禁止请求密码短语:

将密钥附加到设备以解密分区时,使用 -p 标志抑制对密码短语的请求:

在进行无密码短语加密之前,请尝试想出另一种方法来解决试图解决的问题。


使用没有密码短语的GELI密钥会降低GELI的保护。你可以做到,但你不应该。我经常听说人们希望他们的系统自动启动,而无需输入密码短语。加密硬盘,但让它自动解密,就像为你的门买一把真正好的锁,用一根绳子把钥匙绑在锁上,这样你就永远不会把自己锁在外面。在可移动只读介质上拥有密钥会有所帮助,但键入密码短语真的有那么多工作吗?

初始化GELI密钥时,添加 -P 标志可以禁止请求密码短语。

当您将密钥附加到设备以解密分区时,使用 -p 标志抑制对密码短语的请求。

在进行无密码短语磁盘加密之前,请尝试想出另一种方法来解决您试图解决的问题。

没有密钥文件的密钥

有时,您可能希望仅使用密码保护GELI设备。当您使用GELI创建适度的隐私而不是保护高度机密的数据时,这是有道理的。如果你想让你的笔记本电脑在被盗时变得不可读,但不想为密钥文件携带单独的设备,那么只使用密码并不是不合理的。跳过在 initattach 命令上指定密钥文件。

此分区仅受密码短语保护。要使用加密设备,请运行 geli attach 并给出设备名称。

输入密码短语后即可使用该设备。

擦除主密钥的副本

使用 geli delkey 命令可以销毁主密钥的两个副本之一。使用 -n 选项指定要删除的slot:

如果设备已经被附加,不需要指定slot号。系统会自动销毁当前用于附加设备的主密钥。

记住,当设备被附加时,主密钥在系统内存中是未被加密的,因此可以使用 geli setkey 恢复密钥。一旦分离了一个没有主密钥副本的GEIL设备,将无法再次解密该设备,只能从备份中还原数据。

杀掉GELI设备

加密的目的之一是保护数据。销毁加密密钥可以防止数据泄露。可以想象,您可能需要销毁加密密钥以防止数据泄露。geli kill 命令销毁设备上主密钥的所有副本并将其分离,强制卸载设备上的任何文件系统。

使用 -a 选项而不是设备分区,此命令会清除系统上所有打开的GELI设备。

在被杀掉的设备上打开文件的任何进程都无法访问这些文件。这可能会破坏进程的稳定。最佳情况下,它们会崩溃;最坏情况下,它们可能会损坏其他分区上的数据。然而,如果正在杀死加密文件系统,系统的稳定性并不是首要问题。

备份和还原GELI元数据

在创建GELI设备时,GELI会自动备份元数据,包括主密钥的两个副本。可以随时更新此备份,或在擦除所有密钥或终止设备后将备份还原到设备。

要备份设备的GELI元数据,在 geli backup 命令中使用带有底层设备名称和要放入备份的文件:

要还原设备的备份,使用 geli restore 命令。只有在使用 delkeykill 命令删除加密密钥后,或在元数据中以某种方式搞砸了这两个密钥后,才能恢复GELI元数据。可以将此元数据还原到与原始分区大小相同的任何提供者。

恢复GELI元数据不会恢复设备上的任何文件系统或任何用户数据。

当我看到这个功能时,我的第一个想法是“嘿,我可以用相同的密钥和密码创建一大堆GELI提供者!”就像我最初的大多数想法一样,这是一个糟糕的想法。重复使用密钥和密码是一个坏主意。在所有加密设备上重复使用相同的主密钥是一个更糟糕的主意。这两个错误都提高了攻击者破解加密的能力。

密码短语文件

密码短语可以保存在文件中,每个密码短语一行。

使用 -J 参数为 geli init 提供密码短语。

以下示例中,密钥放在一个移动设备上,密码短语放在另一个独立的移动设备上:

geli attach 命令中用 -j 指示密码文件:

可以让FreeBSD在启动时读取密码短语文件。后面详述。


所以你想安全地使用密钥文件和密码短语?太棒了但是你想把密码短语放在系统上的一个文件中,这样你就不必键入密码来连接设备了?GELI 让你这么做。所有关于将密钥放在本地未加密文件系统上的警告都适用于将密码短语放在文件中。

有了所有这些警告,系统管理不仅仅是安全问题。这也涉及政治。也许该组织的所有加密文件系统都必须使用相同的密码,如果你必须创建几十个加密文件系统,你宁愿把密码放在一个文件中,而不是输入三十亿次。也许一个带有密码文件的加密文件系统可以让你应对相互冲突的组织或监管要求。有时,组织系统管理员的工作是保证子弹先生可靠地交付给脚先生。

密码文件也可以满足非常具体的业务需求。一些组织要求安全销毁旧硬盘。该组织并不担心其会计服务器的硬盘被盗,但他们确实关心更换服务器并将硬盘运走进行回收时会发生什么。作为系统管理员,您希望计费服务器在没有人为干预的情况下启动。将密钥和密码放在可移动介质上,用GELI加密硬盘,并让FreeBSD在启动时读取密码文件。当需要停用服务器时,您可以用锤子敲击可移动介质,仍然可以回收硬盘。粉碎CD或销毁USB闪存驱动器比销毁硬盘驱动器容易得多。

文件中的密码必须在一行上。使用 –J 参数为 geli init 提供密码。在这里,我将密钥放在一个可移动设备上,将密码放在完全独立的可移动设备中。

geli attach 命令中用 -j 指示密码文件。

您可以让FreeBSD在启动时读取密码文件,我们将在本章稍后看到。

一次性密钥

像swap那样的应用情况,可能只需要一次性的加密以防止被攻击。使用geli onetime命令告诉geli初始化并使用随机密钥附加提供者:

一次性密钥仅存在于系统内存中,并且在设备连接时存在。断开设备或重启系统时,密钥将永久丢失。


有时,您并不关心文件系统的长期保留——您只需要一块加密磁盘。重新启动后,写入交换空间的数据对系统没有用处,但它可能会帮助入侵者提高权限。交换空间的一次性加密可以防止这种攻击。使用 geli onetime 命令告诉GELI初始化并使用随机密钥附加提供程序。

一次性密钥仅存在于系统内存中,并且仅在设备连接时存在。断开设备或重新启动系统,密钥将永远消失。

GELI调整大小

您可能需要扩展GELI设备,最常见的是如果您使用虚拟化并扩展虚拟磁盘的大小。您需要扩展底层物理设备,扩展GELI设备,然后扩展文件系统。在这里,我扩展磁盘0上的分区1以填充所有可用空间。

GELI将元数据放在提供者的最后一个扇区。使用 geli resize 命令告诉GELI移动元数据。需要使用 -s 参数给出原始分区大小:

GELI元数据现在安全地存放于物理设备的末尾。将密钥附加到GELI设备,然后就可以扩展文件系统:

加密的文件系统现在填充了整个分区。

GELI启动

rc.conf 中配置GELI

/etc/rc.conf 文件中的 geli_devices 选项中列出在多用于启动期间要配置的每个GELI设备。以下示例使用两个GELI磁盘分区,一个GPT分区还一个标记为加密的分区:

对于列表中的每一个设备,添加一个 rc.conf 行以指定 geli(8) 命令行参数以附加它。每行以 geli_ 开头,给出设备名称,以 _flags 结尾,例如:

如果没有指定密码文件,FreeBSD会中断引导以请求它们。FreeBSD会在引导过程的早期附加所有GELI设备,因此,可以在 /etc/fstab 中引用它们。以下示例自动挂载一个加密的数据库数据分区:

如果需要更早可用的GELI设备,则应在引导加载器中配置它们。

在启动加载器(boot loader)中配置GELI

如果希望GELI在单用户模式下连接并激活加密设备,则必须在初始化设备时使用 -b 参数。没有此标志,引导加载程序将不知道如何尝试连接设备。无法将此标志改装到现有的GELI设备上。

以下示例在标签 /dev/label/enc 上创建一个启动时连接的GELI设备:

将加密密钥文件放置于 /boot 分区。

/boot/loader.conf 中使用可调参数配置GELI启动设备。还可以使用可调变量调试GELI。每个GELI设备需要三个 loader.conf 条目:

为您在单用户模式下配置的每个加密设备自定义 nameprovider 。此GELI设备是 /dev/label/enc ,因此使用 enc 作为名称。提供者始终是您要连接的设备节点,没有前导 /dev/ 。此设备最终具有以下配置。

另外,在启动时加载GELI模块:

下次启动时,启动将停止以请求此设备的密码。

使用其他可调参数调整GELI的行为,详见 geli(8) 手册页。我们大多数人都不应该对所提供的默认值进行调整。

排错

如果无法找出问题所在,可尝试启用调试。两个有用的可调整参数是 boot_verbosekern.geom.eli.debug

boot_verbose 可调参数显示所有内核模块的调试输出,而不仅仅是GELI。通过观看详细的启动过程,您可以深入了解您的系统。除其他事项外,这告诉您GELI为特定的GELI设备找到了什么关键文件(如果有的话)。将 boot_verbose 设置为 1 以启用详细引导。

如果详细引导没有告诉你需要知道什么,请尝试 kern.geom.eli.debug 。将其设置为 13 之间的值,以获得越来越多的调试信息。

如果事情变得非常奇怪,您可以在键入GELI密码时让引导加载程序回显您的GELI密码。在将其设置为 1 之前,请确保没有人在肩上冲浪(shoulder surfing)。

在引导时连接GELI设备是全磁盘加密的必要前提,第11章对此进行了讨论。现在,让我们继续讨论GBDE。