用 dm-crypt 创建 Linux 加密文件系统
一个加密的文件系统可以保障硬盘不受硬件层面的攻击。任何人将硬盘弄到手后,依然要用蛮力猜测加密金钥,构成夺取你数据的一个重大阻碍。
Windows 及 Mac OS X 各自提供了它们的标准加密文件系统工具,但 Linux 当然提供了大量工具来完成这个工作。现时盛行的工具似乎是 dm-crypt。通过 cryptsetup 这个工具程序,dm-crypt 为 Linux 提供了一个颇为简洁及易用的加密文件系统工具。
此外,CentOS 5 包括了一个支持 LUKS 的改良版 dm-crypt。LUKS 是一个即将面世的标准,指定有关加密磁盘区的信息如何放置在硬盘上。有关加密数据的中继数据是放置在分区的标头,好让它能兼容不同系统及支持多个用户密码。此外,GNOME 及 HAL 拥有处理 LUKS 磁盘区的支持,而且当带有 LUKS 磁盘区的卸除式媒体被插入时,会自动要求输入密码。如果你不需要兼容较旧版的 CentOS 或未支持 LUKS 的系统,我们推荐你使用 LUKS 的方案。这份文章内的样例亦有描述用来设置加密 LUKS 磁盘区的指令。
这里有些脚本是采用了下面描述的方法,可将创建、卸下、及重新挂载 LUKS 加密文件系统自动化。
1. 所需组件
在开始之前,请确定所有必须的组件都已经安装了:
- cryptsetup(CentOS-5 是 cryptsetup-luks)
- device-mapper
- util-linux
然而,它们很可能都已经存在于你的系统上,除非你进行了一个极度基本的安装。
2. 创建初期文件系统
我多数将文件加密,而不是整个分区,因此我将 dm-crypt 与 losetup 回路设备管理工具合并。下面是用 Unix 指令壳的原始语言描述如何创建及挂载一个加密文件系统。
# 创建一个适合你需要的空白文件。这个样例将会创建一个 8GB 的稀疏 # 文件,意即没有真正的数据块会被写入。由于我们稍后将会强制分派资 # 料块,现在做的并没有意义,因为这些数据块将会被重新写入。 dd of=/path/to/secretfs bs=1G count=0 seek=8 # 限制文件的访问权 chmod 600 /path/to/secretfs # 将文件与回路设备挂钩 losetup /dev/loop0 /path/to/secretfs # 加密设备内的数据。在这个例子里,cryptsetup 会利用 Linux 的设备 # 映射器来创建 /dev/mapper/secretfs。-y 这个选项指定你将会被问及 # 密码两次(有一次作检查之用)。 cryptsetup -y create secretfs /dev/loop0 # 又或者,如果你想使用 LUKS,你应该使用以下两个(与及额外的)指 # 令参数。首个指令将磁盘区初始化,并设置一条原始金钥。第二个指令开 # 启分区并创建一个映射(在样例中是 /dev/mapper/secretfs)。 cryptsetup -y luksFormat /dev/loop0 cryptsetup luksOpen /dev/loop0 secretfs # 检查它的状况(选择性) cryptsetup status secretfs # 现在我们将新加密的设备填满零。这会强制分派数据块。由于这些零已 # 被加密,它们对外就看似随机的数据,即管有人将藏有加密文件系统的 # 文件弄到手上,要找寻被加密的数据块差不多是没可能。 dd if=/dev/zero of=/dev/mapper/secretfs # 创建一个文件系统及检查它的状况 mke2fs -j -O dir_index /dev/mapper/secretfs tune2fs -l /dev/mapper/secretfs # 将新文件系统挂载在一个方便的位置 mkdir /mnt/cryptofs/secretfs mount /dev/mapper/secretfs /mnt/cryptofs/secretfs
3. 卸下及保障文件系统
要手动地卸下及保障加密文件系统,你基本上要反向执行尾部份的指令。
# 卸下文件系统 umount /mnt/cryptofs/secretfs # 删除设备映射 cryptsetup remove secretfs # 或者,如果是一个 LUKS 磁盘区 cryptsetup luksClose secretfs # 将文件与回路设备脱钩 losetup -d /dev/loop0
4. 重新挂载加密文件系统
一旦你已经创建了一个加密文件系统,重新挂载它的程序是相对地简单:
# 将文件与回路设备挂钩 losetup /dev/loop0 /path/to/secretfs # 将映射设备加密。你将会被问及密码 cryptsetup create secretfs /dev/loop0 # 或者,如果是一个 LUKS 磁盘区 cryptsetup luksOpen /dev/loop0 secretfs # 挂载文件系统 mount /dev/mapper/secretfs /mnt/cryptofs/secretfs
请注意,就算你打错了密码,cryptsetup 亦不会提供有用的错误信息。你只会从 mount 得到一个不大有用的信息:
mount: you must specify the filesystem type
如果出现这个情况,请反复用 cryptsetup 尝试重新挂载那个文件系统:
cryptsetup remove secretfs cryptsetup create secretfs /dev/loop0 mount /dev/mapper/secretfs /mnt/cryptofs/secretfs
这点并不适用 LUKS 磁盘区,因为 cryptsetup 在 luksOpen 这一步将会提供有用的错误信息。
5. 在一个 LUKS 磁盘区内加入额外的金钥
如上面所提及,LUKS 这个格式容许使用多条金钥。意思是你可以加入多于一条用来打开加密设备的金钥。要新增金钥,你只须:
cryptsetup luksAddKey <设备>
举个例说,你使用 /dev/loop0 这个回路,你可以执行:
cryptsetup luksAddKey /dev/loop0
cryptsetup 要求你输入现有的密码两次。之后,你将会被问及新的密码两次。当这一步完成后,你便可以使用现有的金钥,或者新增的金钥来打开这个磁盘区。
6. 在系统开机时设置加密磁盘区
有些时候你或许会想在系统开机时设置加密磁盘区,例如为一台笔记本设置一个加密了的 home 分区。在 CentOS 5 上,这件事情可以通过 /etc/crypttab 轻易地完成。/etc/crypttab 描述那些须要在开机时创建映射的加密磁盘区及分区。记录是以新行分隔,而当中包含了以下数据栏:
映射名称 设备名称 密码文件路径 选项
当然,你一般不会需要全部四栏:
LUKS 磁盘区会忽视选项栏内的多数选项,因为 LUKS 磁盘区在磁盘区标头内已收录了一切关于密码、密码长度、及散列的必须信息。另外,
一般来说,你不会想将一个纯文本的密码档存储在根分区内。你当然可以将它存储在其它地方,但是 rc.sysinit 在开机的这一个阶段多数只会以只读式挂载了根目录。如果密码栏并不存在,或者数值是 none,系统在开机时会要求你输入密码。
因此,如果你使用 LUKS 磁盘区,而且想系统在开机时询问密码,你只需头两栏。让我们看一个简短的样例:
cryptedHome /dev/sdc5
这个做会为 /dev/sdc5 上的加密磁盘区创建一个名叫 cryptedHome 的映射,而这个加密磁盘区先前是用 crypsetup luksFormat /dev/sdc5 来创建的。如果你亦在加密磁盘区上创建了一个文件系统,你可以在 /etc/fstab 内新增一个记录,好让文件系统在开机时被挂载:
/dev/mapper/cryptedHome /home ext3 defaults 1 2
有两个选页是不会被 LUKS 磁盘区所忽视的:
swap:当映像被设置后,这个磁盘区将会被格式化成为调换分区。
tmp:这个磁盘区将会被格式化成为 ext2 文件系统,并设置合适的权根作为临时文件案用的文件系统。
这两个选项要求 /etc/fstab 内含有使用相关映像的记录,而且这些选项都有破坏力。一个为加密调换分区而设的记录可能会看似:
cryptedSwap /dev/sda2 none swap
或者如果你不想在每次开机时为调换分区输入密码:
cryptedSwap /dev/sda2 /dev/urandom swap
请注意,如果 /dev/sd2 已经是一个 LUKS 分区,这个方法并不可行,因为 LUKS 分区须要非随机的金钥。
Translation of revision 13