如何使用DM-Crypt加密Linux文件系统?
读者经常询问我们的一个常见问题是,如何为 Linux 实施一种文件系统加密方法。在深入探讨这个话题之前,我想要阐明两点:
首先,很难在网上找到这方面足够多的信息。于是,我会向大家介绍几个好不容易找到的确实很棒的资源(实际上是几篇教程)。
其次,明白这个问题的技术细节很重要。这也是我在本文中所要探讨的,之后我会介绍如何实现加密,然后介绍其他资源。
人们时常说想要加密数据,但是他们常常忽视了一个根本的方面:他们到底想对什么进行加密?他们是想从软件包里面对数据进行加密,然后将该数据存储到硬驱上的单个文件中?比如说,他们是想让 LibreOffice 创建整个 .odt 文字处理文档,对它进行加密,然后将加密的结果作为单个文件写入到文件系统,就像下图那样?还是说他们想让 Linux 在文件系统层面自行处理加密?
一种方法就是从软件包里面加密数据,然后将该数据存储到硬驱上的单个文件中。或者 Linux 会在文件系统层面自行处理加密。
以 Linux 处理加密事务为例, LibreOffice 除了读取和写入文件外,什么也不做,就像它目前所做的那样。 Linux 会加密文件,然后将文件实际写入到磁盘上,解密后回过头来读取文件。这是我在这里采取的方法,但是你还要提出另外许多问题。想要提出合适的问题,你就要明白块存储的工作原理。不妨先看一下块存储。
块级存储
操作系统处理本地驱动器时,操作系统使用 filesystem 软件来格式化驱动器,然后读取并写入单个扇区。保存文件时, filesystem 软件弄清楚需要写入的扇区。读取文件时, filesystem 会弄清楚数据在哪些扇区上,然后读取那些扇区,为你重构文件。想管理文件, filesystem 使用不同类型的索引,它将这些索引也存储在磁盘上。不同的 filesystem 软件使用不同的方式来组织数据,还包括不同的安全机制;最终结果就是有了不同的文件系统,比如 ext4 和 NTFS 。
底层细节
我们已交待清楚了块级设备的工作原因,不妨考虑这个:操作系统使用其 filesystem 软件,将数据扇区写入到驱动器。 filesystem 软件确定将数据扇区写入到何处、如何组织它们,包括创建描述文件名称、组织方式等信息的元数据。但是 filesystem 软件为了执行实际读取并写入到驱动器的操作,就需要有设备驱动程序来做实际控制设备本身的工作,如下图的左边所示(驱动程序在 /dev 目录里面的文件系统层次结构中已有表示)。
filesystem 软件能够在写入数据之前进行加密。或者,位于 filesystem 软件与设备驱动程序之间的某个软件能进行加密。
就在 filesystem 软件与设备驱动程序之间的这个点,加密方面需要做出选择:你是想让 filesystem 软件进行加密,然后写入数据呢?还是说,我们实际上将一个软件嵌入到 filesystem 软件与设备驱动程序之间怎么样?这样一来, filesystem 会像平常那样运转,但是当它试图访问设备时,其调用改而由加密软件来处理,如上图的右边所示。我们在本文中要采用这种方法。不过先不妨谈论另外几个问题。
顺便说一下,如果你想看看设备驱动程序在 Linux 系统的 /dev 目录中如何存在,可以参阅本文: http://www.linuxdevcenter.com/pub/a/linux/2007/07/05/devhelloworld-a-simple-introduction-to-device-drivers-under-linux.html?page=1 。它包括编程方面,但是如果你不是编程员,就点击到第 2 页,向下滚动鼠标,找到标为 Hello, World! Using /dev/hello_world 的章节,阅读第一段,上面作了具体细致的解释。)
如果你想加密整个分区,可以考虑加密整个驱动器。不过这里存在一个小问题。如果计算机从该驱动器启动,驱动器就需要一个小小的分区 专门用于存放启动代码。该启动代码是机器代码,计算机读入后执行,才能启动计算机。如果整个硬驱经过了加密,包括这部分数据,计算机就需要某种方式来解读 数据。但是计算机还没有装入文件系统,所以它没法读取解密它的程序。看到问题之所在了吗?解密代码需要在 BIOS 本身里面。但是大多数计算机没有这种代码。而这意味着启动记录其实无法被加密。不过人们已经讨论了解决这个问题的种种方法(参阅: http://www.linuxquestions.org/questions/linux-security-4/full-disk-encryption-on-boot-partition-626270/ ),比如把启动代码放在可移动 USB 驱动器上面。
远程驱动器
如果你的驱动器是远程驱动器,有几种方法可以访问数据;这对于你了解可以使用哪种类型的加密很重要。两种方法是:
• 块级存储 就像使用本地驱动器那样,因而你的 filesystem 软件可以读取并直接写入到远程磁盘上的扇区。
• 文件级存储 ,你的操作系统将文件发送到远程服务器,远程服务器有自己的操作系统和 filesystem 软件;该远程服务器进而将文件写入到其磁盘上。
如果是文件级存储,你在加密方面没有太多的选择。如果你想加密数据,就需要在你的应用程序中加密它,然后将数据发送到远程服务器上存储起来。
但如果是块级远程存储,确实有几个办法。比如说,如果你使用云托管服务,因而你能将不同的卷连接到分配的服务器,你通常可以使用块级存储。卷未必 物理连接到你的托管服务器;不过,服务器可以访问它们,好像它们就是本地卷那样,并且格式化卷,读取和写入单个扇区,就好像驱动器是本地挂载的。这意味 着,如果是块级远程存储,你可以在文件系统层面执行加密,就好像在本地计算机和本地驱动器上执行加密那样。
软件
现在我们知道了想要完成的任务;问题是,你该如何实现呢?事实上, Linux 内置了一个软件包,使用我之前介绍的那种方法,即把软件嵌入到 filesystem 软件与设备驱动程序之间。该软件名为 dm-crypt 。而 dm-crypt 可以加密数据,然后使用一种名为 LUKS 的存储格式,将数据写入到存储设备(通过设备驱动程序)上。
LUKS ( Linux 统一密钥设置)是驱动器本身上面所用的格式,它实际上用来取代 ext4 之类的文件系统。 dm-crypt 系统位于 filesystem 软件与设备驱动程序之间; filesystem 软件读取和写入 ext4 ,而 ext4 数据通过 dm-crypt 加以推送,然后 dm-crypt 将数据以 LUKS 格式存储到驱动器上。因而,实际上 ext4 或 NTFS 之类的文件系统就在经过加密的 LUKS 格式的“上面”。
请注意: dm-crypt 是子系统的名称,你可以使用诸多工具来处理它。没有名为 dm-crypt 的单个命令。你可以使用一些程序来管理 dm-crypt :
• cryptsetup : 这个命令行程序为你提供了底层访问权,以便管理创建 dm-crypt 管理的设备这一任务。
• cryptmount : 这个程序提供了更多的功能特性,更易于使用一点,具体可参阅几年前的这篇文章: http://www.enterprisenetworkingplanet.com/netsecur/article.php/3742191/Create-Encrypted-Volumes-With-Cryptmount-and-Linux.htm 。
其他功能特性
dm-crypt 系统的一个优点在于,它没必要直接处理磁盘驱动程序。相反,它可以将所有数据保存到单个文件中,而不是使用 LUKS 和整个磁盘分区。这就意味着,你可以让 dm-crypt 创建单个文件,然后你可以在单个文件里面创建整个文件系统。之后,你可以将该单个文件作为单独的驱动器来挂载,然后从任何软件来访问它,就像你对待其他任何驱动器那样。
云驱动器
由于一些云服务提供商(比如亚马逊网络服务)为你提供了全面的根访问权,可以访问连接到你服务器的块设备,你可以充分利用 dm-crypt ;可以用 LUKS 格式来格式化块设备,然后将它准备用于你的 dm-crypt 系统;之后,你完全可以用 ext4 文件系统来格式化它。最终结果就是完全加密的驱动器驻留在云端,你可以自行管理这个驱动器。想不想试一试?这篇教程就介绍了使用 cryptsetup 程序来加密: http://silvexis.com/2011/11/26/encrypting-your-data-on-amazon-ec2/ 。
另外一些云服务提供商不像 AWS 那样让你可以直接访问块设备。比如说, Digital Ocean 就不允许你直接访问;不过你仍可以创建一个文件,安装 dm-crypt 来使用那个文件,然后在文件里面创建一个所谓的“容器”,它代表了文件系统。实际上,这个过程与你在自己的本地机器上创建一个加密的容器文件如出一辙。这里有一篇出自 Digital Ocean 网站的教程: https://www.digitalocean.com/community/tutorials/how-to-use-dm-crypt-to-create-an-encrypted-volume-on-an-ubuntu-vps ,介绍了创建 dm-crypt LUKS 容器文件。在该教程中要注意:就像使用块设备那样,你可以创建整个文件系统(比如 ext4 ),不过在这里,该文件系统驻留在容器文件里面。
本地驱动器
而这就引出了我们如何在本地实现这一切的话题。在亚马逊上创建加密驱动器的上述教程涉及的步骤与在你自己的硬驱上本地创建加密驱动器一个样。不过另一篇教程( https://www.howtoforge.com/tutorial/how-to-encrypt-a-linux-partition-with-dm-crypt-luks/ )给出了逐步的说明,以便在你自己的硬驱上本地创建,它也使用 cryptsetup 。
如果你想创建一个本地容器驱动器,含有整个经过加密的文件系统,只要遵循上面 Digital Ocean 教程中的步骤即可。
或者,如果你想使用另一个程序 cryptmount 来加密整个分区或创建容器文件,请关注这篇教程: http://www.enterprisenetworkingplanet.com/netsecur/article.php/3742191/Create-Encrypted-Volumes-With-Cryptmount-and-Linux.htm 。作者 Carla Schroder 给出了几个明确的步骤。
结束语
就是这样。想知道如何加密,重要的一点是先要完全了解你实际上试图完成什么任务:让应用程序加密和解密数据,还是让操作系统处理加密;是加密整个 分区,还是仅仅加密个别文件;是不是想创建保存加密文件的容器。之后,你可以遵照我在本文中给出链接的几个教程中提到的步骤,顺利完成加密。