加密您的根文件系统
在 Linux Journal 文章 “实现加密的家目录”(2003 年 8 月)中,我描述了如何透明地加密家目录。本文描述了如何实现另一种技术,即加密的根文件系统。我讨论了 GNU/Linux 启动过程和软件要求,介绍了一些说明,介绍了 Open Firmware 并讨论了其他相关注意事项。我用来教授这些概念的系统是一台基于 New World PowerPC 的 Apple iBook,运行的是 Fedora Core 3 的预发布版本。尽管存在这些具体细节,但本文中的概念和过程可以应用于任何设备、架构或操作系统。我的说明假设您有一个备用的 USB 闪存盘,并且您的系统固件具有从中启动的能力。
我还假设读者可以熟练地应用源代码补丁和编译程序。截至 Fedora Core 3 Test 3,mkinitrd 和 initscripts 软件包需要打补丁才能支持加密的根文件系统。还需要基本了解如何管理分区和创建文件系统。执行 Linux 发行版的基本安装不在本文的范围之内。
在介绍所涉及的技术步骤之前,必须讨论一个更高层次的概念,即信任。信任与密码学和身份验证交织在一起。任何拥有电子密钥的设备都被赋予了隐含的信任假设。例如,当我与自动取款机共享我的银行账户 PIN 时,我信任 ATM 不会将我的 PIN 与不适当的第三方共享。同样,当我向计算机提供加密密钥时,我假设密钥不会与其他人共享。我信任计算机在我们之间保守秘密。
那么,您能信任您的计算机吗?除非您随身携带它,否则您真的不能。即使磁盘已被加密,情况也是如此。考虑这种情况:有人在您睡觉时偷走了您的计算机。窃贼复制了计算机加密内容,即使这些内容在没有加密密钥的情况下对他来说毫无用处。然后,他用一些更邪恶的东西替换了加密的笔记本电脑内容,并将计算机放回原处。当您第二天醒来时,计算机像往常一样每天早上都会提示输入加密密码。但是这次当您提供密钥时,它会以电子方式将密钥传输给窃贼。因为他现在有了您的数据和密钥的副本,所以他可以读取您的文件。
这种情况可能有点牵强,但它确实说明了一个问题。您不能信任您的笔记本电脑。它太大了,无法一直放在您的视线之内。因此,无论您的加密系统实施得多么好,它都是在没有信任的先决条件基础的情况下构建的。
为了确保我们可以信任计算机的启动过程,我们需要将其与计算机分离。考虑一下:您随身携带汽车钥匙,而不是随身携带汽车。您的加密密钥是汽车钥匙的自然概念飞跃。您可以更轻松地保护您的加密密钥,因此您不必随身携带计算机。为了更进一步并解决上述情况,我们还将启动计算机所需的软件放在此密钥上。闪存盘将充当此密钥。通过保护最初启动系统的软件,以及加密密钥,我们可以减轻启动过程被劫持的风险。
需要了解您的计算机如何启动,因为解锁加密的根文件系统是引导过程不可或缺的一部分。当前的稳定内核系列 2.6 可选择使用 initramfs 来帮助启动,如 LWN.net 的 “Initramfs Arrives” 中所述。Initramfs 是一个 cpio 存档,内核现在知道如何将其解压缩到基于 RAM 的磁盘中。这个解压缩的文件系统包含一个脚本,该脚本传统上加载挂载根文件系统所需的内核模块。在我们的例子中,此脚本还会解锁加密的根文件系统。有关此主题的更多信息,请参见 Linux 内核源代码随附的文件 buffer-format.txt 和 initrd.txt。
Linux 有几个文件系统加密接口可用。Jari Ruusu 的 Loop-AES 是其中一个项目。也存在一些提供加密回环设备的 cryptoloop 变体。本文重点介绍最新 2.6 Linux 内核提供的 dm-crypt 接口。Fedora 项目目前首选此接口,并且 Fedora 的内核软件包提供了 dm-crypt 模块。还需要静态链接的 cryptsetup。此实用程序简化了 dm-crypt 设备的管理。最后,parted 和 hfsutils 用于管理启动文件系统。
不幸的是,Fedora Core 的 anaconda 安装程序尚不支持开箱即用地安装到加密文件系统。为了绕过此限制,您必须留出一个空闲分区,安装 Fedora,将空闲分区格式化为加密文件系统,并将最初安装的数据复制到新的加密文件系统上。为了简单起见,我假设 Fedora 将安装到两个分区:/dev/hda4,挂载到 /home,以及 /dev/hda5,挂载到 /。由于 /home 在 Fedora 安装后才会被填充,因此我们可以使用 /dev/hda4 作为备用分区,/dev/hda3 作为交换分区。
安装 Fedora Core 3,将 /dev/hda4 挂载到 /home,并将 /dev/hda5 挂载到 /。暂时不要添加任何非 root 用户,因为 /home 稍后将被清除。此时,您应该拥有一个功能齐全的 Linux 系统。
在设置加密文件系统之前,您应该随机化它将占用的分区。这消除了有关磁盘内容的潜在信息泄露。图 1 显示了一个抽象磁盘,该磁盘半满且未正确随机化。图 2 显示了一个磁盘,该磁盘在格式化为包含加密文件系统之前已正确随机化。请注意,给定图 1,人们可以获得一些关于其内容的知识(例如,它们跨越磁盘的一半)。图 2 不会让攻击者获得这种便利。在这种情况下,磁盘可能像空的一样容易满。通过使用随机数据覆盖分区的内容来随机化分区dd if=/dev/urandom of=/dev/hda4。此过程可能需要很长时间,因为创建随机数据有些困难。

图 1。当您在创建文件系统之前不随机化磁盘分区时,攻击者可以看到它的已满程度。

图 2。随机化分区会隐藏已使用的空间。
要在 /dev/hda4 上创建加密的 ext3 文件系统,请使用以下步骤
1) 确保 aes、dm-mod 和 dm-crypt 模块已加载到内核中。
2) 从 /home 卸载将托管加密根文件系统的分区 /dev/hda4
# umount /dev/hda4
3) 创建一个随机的 256 位加密密钥,并将其存储在 /etc/root-key 中
# dd if=/dev/urandom of=/etc/root-key bs=1c count=32
现在访问 /dev/mapper/root 会在 /dev/hda4 之上提供一个加密层。默认情况下,cryptsetup 创建一个 AES 加密的 dm-crypt 设备,并假定密钥空间为 256 位。
5) 在 /dev/mapper/root 上创建一个 ext3 文件系统
# mkfs.ext3 /dev/mapper/root
6) 挂载新文件系统
# mkdir /mnt/encroot # mount /dev/mapper/root /mnt/encroot
7) 现在您已经有了一个加密的文件系统,您必须用 /dev/hda5(原始根文件系统)的内容填充它
# cp -ax / /mnt/encroot
8) 最后,在 /mnt/encroot/etc/crypttab 中创建一个条目,以便各种实用程序知道如何配置文件系统
root /dev/hda4 /etc/root-key cipher=aes
现在我们已经准备好加密的文件系统,有必要更多地了解目标架构的启动过程。通常,计算机具有固件,该固件将执行权移交给将完成系统启动的软件。保护固件不在本文的范围之内,因此我们假设系统的固件可以信任。大多数读者可能熟悉 BIOS,PC 平台使用的启动固件。我专注于 Open Firmware,这是一种由 Apple、Sun 和 IBM 等计算机制造商使用的启动系统。
NetBSD/macppc 的安装说明很好地介绍了 Open Firmware。我们感兴趣的是使用 Open Firmware 的命令行界面将计算机配置为从可移动闪存盘启动。Open Firmware 允许您查看连接到计算机的设备,以及查看和设置固件变量的值。
在初始启动过程中,按住 New World(G3 及更高版本)Apple 计算机上的 option-command-o-f 可以访问 Open Firmware 提示符。
变量 boot-device 用于确定系统应使用哪个设备启动。printenv 命令允许您检查其当前值
> printenv [...] boot-device hd:,\\:txbi hd:,\\:txbi
这基本上意味着 “通过执行第一个 IDE 磁盘上 HFS 类型 txbi 的文件来启动。” 第二个 : 字符(在 txbi 之前)使令牌被解释为 HFS 文件类型。否则,txbi 将被解释为文件的路径。在我的情况下,令牌 hd 实际上是更复杂的别名/pci@f4000000/ata-6@d/disk@0。此字符串表示通过各种子系统到第一个 IDE 磁盘的路径。您可以使用 Open Firmware 的 devalias 命令查看别名解析为哪个设备。
要正确设置 boot-device,我们需要发现 Open Firmware 用什么名称来识别我们的闪存盘。检查 ls 命令打印的设备树会显示闪存盘的路径
> dev / ls [...] /pci@f2000000 [...] /usb@1b,1 [...] /disk@1 [...]
现在我们对固件对计算机的看法有了一些了解,我们必须花一些时间研究固件最初执行的软件:引导加载程序。通常,在 Apple 的 PowerPC 架构上运行的 Linux 系统使用名为 yaboot 的程序来启动系统。yaboot 类似于 LILO 或 GRUB,包含两个关键程序:ofboot.b 和 yaboot。ofboot.b 提供引导过程的第一阶段。本质上,ofboot.b 的工作是确定要启动哪个操作系统。例如,如果系统同时安装了 Mac OS X 和 Linux,则 ofboot.b 执行 Mac OS X 或 Linux 的引导加载程序。如果用户选择加载 Linux,则 ofboot.b 执行 yaboot,即引导过程的第二阶段。然后,yaboot 加载 Linux 内核,在我们的例子中,加载 initrd。图 3 说明了如何在 PowerPC 架构上使用加密根文件系统启动 Linux。
我们的可移动启动设备需要 ofboot.b 和 yaboot 程序、Linux 内核以及包含加密密钥的 initrd。Apple 当前基于 PowerPC 的架构期望其启动介质使用 HFS 格式化。
1) 使用 parted 程序在闪存盘上创建正确的引导分区(我的闪存盘为 64MB,并使用设备节点 /dev/sda 访问)
# parted /dev/sda (parted) mklabel mac (parted) print Disk geometry for /dev/sda: 0.000-62.500 megabytes Disk label type: mac Minor Start End Filesystem Name Flags 1 0.000 0.031 Apple (parted) mkpart primary hfs 0.031 62.500 (parted) print Disk geometry for /dev/sda: 0.000-62.500 megabytes Disk label type: mac Minor Start End Filesystem Name Flags 1 0.000 0.031 Apple 2 0.031 62.500 untitled (parted) set 2 boot on (parted) name 2 Apple_Boot (parted) quit
2) 在引导分区上创建 HFS
# hformat /dev/sda2
3) 通过修改 /mnt/encroot/etc/yaboot.conf,将 yaboot 配置为从适当的设备启动。以下是一个最低配置
boot=/dev/sda2 ofboot=/pci@f2000000/usb@1b,1/disk@1:2 partition=2 install=/usr/lib/yaboot/yaboot magicboot=/usr/lib/yaboot/ofboot default=linux image=/vmlinux label=linux root=/dev/hda4 initrd=/initrd.gz read-only
值/pci@f2000000/usb@1b,1/disk@1:2来自我们之前对 Open Firmware 设备树的检查,并且/pci@f2000000/usb@1b,1/disk@1是 PCI 总线上 f2000000 处的 USB 总线上的第一个磁盘。我们感兴趣的设备是磁盘,并且:2表示分区 2。
4) 将引导程序和内核安装到 /dev/sda2
# ybin --config /mnt/encroot/etc/yaboot.conf -v # mount /dev/sda2 /media/usbstick # cp /boot/vmlinux /media/usbstick
此时,必须将加密感知 initrd 安装到闪存盘上。Fedora 提供了一个名为 mkinitrd 的工具,可以创建 initrd。但是,在撰写本文时,mkinitrd 不知道如何挂载加密的根目录。 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=124789 上的补丁提供了此功能。应用补丁后,mkinitrd 会读取 /etc/crypttab 并创建一个适当的 initrd
1. mkinitrd --authtype=paranoid -f /media/usbdisk/initrd.gz <kernel version> 2. umount /media/usbstick
应更新文件 /mnt/encroot/etc/fstab 以反映所做的更改
/dev/mapper/root / ext3 defaults 1 1
加密的交换分区或完全没有交换空间是加密文件系统的先决条件。原因可以在 “实现加密的家目录” 和名为 “Mac OS X stores login/Keychain/FileVault passwords on disk” 的 BugTraq 邮件列表线程中找到。当 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=127378 上的补丁应用于 initscripts 软件包时,Fedora 允许用户使用随机生成的会话密钥加密其交换分区。由于通常不需要在重启之间保持交换空间一致,因此系统关闭时不会保存会话密钥。要启用加密的交换分区,请完成以下步骤
1) 将以下行添加到 /mnt/encroot/etc/fstab,替换任何以前的交换记录
/dev/mapper/swap swap swap defaults 0 0
2) 将以下行添加到 /mnt/encroot/etc/crypttab,以告诉系统如何执行加密
swap /dev/hda3 /dev/urandom swap
此时,我们应该能够重启系统并使用我们的加密文件系统。同样,我们需要按住 option-command-o-f 进入 Open Firmware 提示符。
如上所示,闪存驱动器的第二个分区的路径是 /pci@f2000000/usb@1b,1/disk@1:2。了解这一点后,我们可以构建路径/pci@f2000000/usb@1b,1/disk@1:2,\ofboot.b。 , 分隔分区号和文件系统路径; \ofboot.b 是文件系统路径,\ 类似于 UNIX 的 /,文件系统根目录位于设备的根目录
> dir /pci@f2000000/usb@1b,1/disk@1:2,\ Untitled GMT File/Dir Size/ date time TYPE Name bytes 9/ 3/ 4 21:44:41 ???? ???? initrd.gz 2212815 8/28/ 4 12:24:21 tbxi UNIX ofboot.b 3060 9/ 3/ 4 2:21:20 ???? ???? vmlinux 141868 9/28/ 4 12:24:22 boot UNIX yaboot 914 9/28/ 4 12:24:22 conf UNIX yaboot.conf
这证实 Open Firmware 可以读取启动系统所需的文件。将 boot-device 变量的值设置为/pci@f2000000/usb@1b,1/disk@1:2,\ofboot.b会导致系统从闪存盘启动setenv boot-device /pci@f2000000/usb@1b,1/disk@1:2,\ofboot.b.
一旦系统成功从加密的根目录启动,就有必要销毁 /dev/hda5 上的所有数据。这可以使用与随机化根文件系统分区相同的过程来完成dd if=/dev/urandom of=/dev/hda5。您可能需要多次执行此覆盖。有关磁盘清理的一个标准,请参见美国国防部 “国家工业安全计划操作手册” 第 8 章。
在安全清理之后,/dev/hda5 可以用作 /home。/home 文件系统也应该加密。幸运的是,这是一个简单得多的过程,因为系统不需要从 /home 启动。创建文件系统本身类似于创建根文件系统的步骤。
1) 确保 aes、dm-mod 和 dm-crypt 模块已加载到内核中。
2) 从 /home 卸载将托管加密家目录文件系统的分区 /dev/hda5
# umount /dev/hda5
3) 创建一个随机的 256 位加密密钥,并将其存储在 /etc/home-key 中。一种方法是
# dd if=/dev/urandom of=/etc/home-key bs=1c count=32
4) 创建一个 dm-crypt 设备,使用您刚刚生成的密钥进行加密
# cryptsetup -d /etc/home-key create home /dev/hda5
5) 在 /dev/mapper/home 上创建一个 ext3 文件系统
# mkfs.ext3 /dev/mapper/home
6) 挂载新文件系统
# mount /dev/mapper/home /home
7) 在 /etc/crypttab 中创建一个条目,以便各种实用程序知道如何配置文件系统
root /dev/hda5 /etc/home-key cipher=aes
8) 最后,更新 /etc/fstab 以包含 /home 的条目
/dev/mapper/home /home ext3 defaults 1 2
此时,可以开始向系统添加非 root 本地用户帐户。加密根文件系统的设置现已完成。
加密所有数据可能很危险。如果加密密钥丢失,您的数据也会丢失。因此,备份包含密钥的闪存盘副本非常重要。执行加密数据的纯文本备份也至关重要。如果您维护可启动的救援磁盘,则可能需要重新考虑应放在其上的系统组件。您的根目录和家目录文件系统密钥、parted、hfsutils、与密码学相关的内核模块和 cryptsetup 都是极好的选择。
这种技术在保护您的数据方面有多有效?在他的书 Secrets and Lies 中,Bruce Schneier 提出了一种可用于评估此技术的技术。可以使用攻击树来建模威胁。图 4 显示了我们的加密文件系统的攻击树的开头。重要的是要注意,此攻击树并不完整,而且可能永远不会完整。
通过使用本文中的技术和一点创造性思维,可以使硬盘上的数据更能抵抗某些类型的盗窃。重要的是要记住绕过这些防御技术的攻击类型。虽然必须使用其他技术来防御基于网络的攻击和其他攻击,但此处描述的技术是实现整体系统安全目标的强大工具。
本文资源: /article/7865。
Mike Petullo 目前在 WMS Gaming 担任测试工程师。自 1997 年以来,他一直致力于 Linux,并欢迎您在 lj@flyn.org 处发表评论。