跳转至内容

dm-crypt/全盘加密

来自 ArchWiki
(从 全盘加密 重定向而来)

以下是使用dm-crypt对整个系统进行加密的常见场景示例。它们解释了对正常安装过程需要进行的所有调整。所有必需的工具都在安装镜像上。

如果您想加密现有的未加密文件系统,请参阅dm-crypt/Device encryption#加密现有的未加密文件系统

概述

保护根文件系统是dm-crypt在功能和性能方面表现出色的地方。与选择性加密非根文件系统不同,加密的根文件系统可以隐藏诸如已安装程序、所有用户帐户的用户名以及常见的潜在数据泄露途径(如locate/var/log/)等信息。此外,加密的根文件系统大大增加了篡改系统的难度,因为除引导加载程序和(通常)内核外,所有内容都已加密。

以下所有场景都具有这些优势,其他区分它们的优点和缺点总结如下

场景 优点 缺点
#分区上的LUKS

展示了一个基本且直接的完全LUKS加密根的设置。

  • 不灵活;需要加密的磁盘空间必须预先分配
#带TPM2和安全启动的分区上的LUKS

与上面的示例类似,安全启动和TPM2提供了额外的安全层。

与上述相同的优点,以及

  • 与上述相同的缺点。
#LUKS上的LVM

通过在单个LUKS加密分区内使用LVM来实现分区灵活性。

  • 简单的分区设置,需要LVM知识
  • 只需一个密钥即可解锁所有卷(例如,轻松从磁盘恢复设置)
  • 锁定后卷布局不可见
  • 允许磁盘休眠的最简单方法
  • LVM增加了额外的映射层和钩子
  • 如果单个卷应接收单独的密钥,则不太有用
  • 如果您有一个卷组中有几个LVM物理卷(PV),您想在LUKS中使用它们,那么每个物理卷必须单独使用LUKS进行加密。为了使用它们,在系统启动期间激活卷组之前,必须单独解锁所有容器。
#LVM上的LUKS

仅在LVM设置完成后使用dm-crypt。

  • LVM可用于让加密卷跨越多个磁盘
  • 轻松混合使用未加密/加密的卷组
  • 复杂;更改卷需要同时更改加密映射器
  • 卷需要单独的密钥
  • 锁定后LVM布局可见
  • 启动时间较慢;每个加密的LV必须单独解锁
#软件RAID上的LUKS

仅在RAID设置完成后使用dm-crypt。

  • 类似于LVM上的LUKS
  • 类似于LVM上的LUKS和加密的引导分区(GRUB)
#纯dm-crypt

使用dm-crypt纯模式,即不带LUKS头和多密钥选项。
此场景还使用了USB设备用于/boot和密钥存储,这可以应用于其他场景。

  • 对于LUKS头可能损坏的情况,数据具有弹性
  • 允许可否认加密
  • 有助于解决SSD的问题
  • 需要非常小心所有加密参数
  • 单一加密密钥,无法更改
  • 对普通使用的系统而言设置非常复杂
#加密的引导分区 (GRUB)

展示了如何使用GRUB引导加载程序加密引导分区。
此场景还使用了EFI系统分区,这可以应用于其他场景。

  • 与安装所基于的场景(本例中为LVM上的LUKS)相同的优点
  • 未加密的数据更少,即引导加载程序和EFI系统分区(如果存在)
  • 与安装所基于的场景(本例中为LVM上的LUKS)相同的缺点
  • 配置更复杂
  • 其他引导加载程序不支持
  • GRUB解锁LUKS需要很长时间,从而减慢启动速度
#ZFS上的根
  • 在加密的zpool的情况下,所有数据集都包含在相同的加密环境中,易于双引导和跨安装共享数据。
  • 备份可以备份到具有未加密zfs设置的目的地。快照将在目的地进行原生加密
  • ZFS不会加密与池结构相关的元数据,包括数据集和快照名称、数据集层次结构、属性、文件大小、文件空洞以及重复数据删除表(尽管重复删除的数据本身是加密的)。
  • 池创建要求用户对磁盘几何形状设置有更深入的了解,甚至包括块大小(ashift)以获得最佳性能。
  • ZFS在其aes实现方面存在一些问题,并且某些加密算法可能表现不佳
  • zvol上的交换或数据集内的文件是一个 오래되된 고질적인 문제,没有变通方法,只能在另一个分区或lv中有交换,并禁用磁盘休眠(见下文)。

虽然以上所有场景都比加密的辅助文件系统提供了更好的保护,免受外部威胁,但它们也存在一个共同的缺点:任何拥有加密密钥的用户都可以解密整个驱动器,从而可以访问其他用户的数据。如果这令人担忧,可以使用块设备和堆叠文件系统加密的组合,并获得两者的优势。请参阅数据加密进行规划。

有关场景中使用的分区策略的概述,请参阅dm-crypt/Drive preparation#Partitioning

另一个需要考虑的方面是是否设置加密的交换分区以及哪种类型。有关替代方案,请参阅dm-crypt/Swap encryption

如果您预计不仅要保护系统数据免受物理盗窃,还需要采取预防措施防止逻辑篡改,请参阅dm-crypt/Specialties#保护未加密引导分区以了解在遵循任一场景后的更多可能性。

对于固态驱动器,您可能希望启用TRIM支持,但请注意,这可能存在安全隐患。有关更多信息,请参阅dm-crypt/Specialties#固态驱动器(SSD)的Discard/TRIM支持

警告
  • 在任何场景下,切勿直接在加密卷上使用文件系统修复软件(如fsck),否则将破坏恢复用于解密文件的密钥。此类工具必须在解密(打开)的设备上使用。
  • Argon2密钥派生函数根据设计具有高RAM使用量,默认每个加密映射器使用1 GiB。低RAM和/或同时解锁多个LUKS2分区的机器可能在启动时出错。请参阅--pbkdf-memory选项以控制内存使用。[1]
  • GRUB对LUKS2的支持有限;有关详细信息,请参阅GRUB#加密的/boot。对于GRUB需要解锁的分区,请使用PBKDF2(cryptsetup luksFormat --pbkdf pbkdf2)的LUKS2。[1]
  • 从ZFS数据集唤醒磁盘休眠可能会损坏您的池,因此在设置休眠时要格外小心,即使交换分区位于zvol之外。有关详细信息,请参阅此处

分区上的LUKS

本示例涵盖了使用dm-crypt + LUKS在简单分区布局中实现全盘加密。

+-----------------------+------------------------+-----------------------+
| Boot partition        | LUKS encrypted root    | Optional free space   |
|                       | partition              | for additional        |
|                       |                        | partitions to be set  |
| /boot                 | /                      | up later              |
|                       |                        |                       |
|                       | /dev/mapper/root       |                       |
|                       |------------------------|                       |
| /dev/sda1             | /dev/sda2              |                       |
+-----------------------+------------------------+-----------------------+

Arch Linux安装镜像启动后即可执行初始步骤。

准备磁盘

在创建任何分区之前,您应该了解有关安全擦除磁盘的重要性和方法,这些内容在dm-crypt/Drive preparation中有描述。

然后创建所需的分区,至少一个用于/(例如/dev/sda2)和一个用于/boot/dev/sda1)。请参阅分区

准备非引导分区

本节和下一节将替换Installation guide#格式化分区中的说明。

以下命令创建并挂载加密的根分区。它们对应于dm-crypt/Device encryption#使用LUKS模式加密设备中详细描述的过程。如果您想使用特定的非默认加密选项(例如,加密算法、密钥长度、扇区大小),请在执行第一个命令之前查看加密选项

# cryptsetup -v luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root

创建文件系统未解锁的LUKS设备。例如,要创建一个Ext4文件系统,请运行

# mkfs.ext4 /dev/mapper/root

将根卷挂载到/mnt

# mount /dev/mapper/root /mnt

检查映射是否按预期工作

# umount /mnt
# cryptsetup close root
# cryptsetup open /dev/sda2 root
# mount /dev/mapper/root /mnt

如果您创建了单独的分区(例如/home),则必须为所有这些分区修改并重复这些步骤,但/boot除外。有关在启动时处理其他分区的说明,请参阅dm-crypt/Encrypting a non-root file system#自动解锁和挂载

请注意,每个块设备都需要自己的密码。这可能不方便,因为它会导致在启动时需要输入单独的密码。另一种方法是使用存储在根分区中的密钥文件通过crypttab解锁单独的分区。有关说明,请参阅dm-crypt/Device encryption#使用LUKS格式化带密钥文件的分区

准备引导分区

您需要设置一个未加密的/boot分区,这对于加密根是必需的。对于UEFI系统上的EFI系统分区,请执行以下命令来格式化新创建的分区

警告: 仅在您于分区步骤中创建了 EFI 系统分区时才进行格式化。如果磁盘上之前已经存在 EFI 系统分区,重新格式化可能会破坏其他已安装操作系统的引导加载程序。
# mkfs.fat -F32 /dev/sda1

或者对于BIOS系统上的普通引导分区

# mkfs.ext4 /dev/sda1

之后,创建挂载点的目录并挂载分区

# mount --mkdir /dev/sda1 /mnt/boot

挂载设备

Installation guide#挂载文件系统步骤中,您应该挂载/dev/mapper/*设备(LUKS的内容),而不是实际的分区。当然,/boot分区(未加密)仍应直接挂载。在安装过程中,它应该挂载到/mnt/boot(假设根文件系统的设备在安装过程中挂载到/mnt)。

配置mkinitcpio

在按照Installation guide#Initramfs进行操作之前,您必须在新系统上执行以下操作

如果使用默认的基于systemd的initramfs,请添加keyboardsd-encrypt钩子。如果您使用非美国控制台键映射或非默认控制台字体,请另外添加sd-vconsole钩子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)

如果使用基于busybox的initramfs,请将keyboardencrypt钩子添加到mkinitcpio.conf。如果您使用非美国控制台键映射或非默认控制台字体,请分别另外添加keymapconsolefont钩子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)

保存更改后重新生成initramfs。有关详细信息以及您可能需要的其他钩子,请参阅dm-crypt/System configuration#mkinitcpio

配置引导加载程序

为了在启动时解锁加密的根分区,引导加载程序需要设置以下内核参数

rd.luks.name=device-UUID=root root=/dev/mapper/root

如果使用encrypt钩子,则需要设置以下参数

cryptdevice=UUID=device-UUID:root root=/dev/mapper/root

device-UUID是指LUKS超级块的UUID。有关详细信息,请参阅持久块设备命名

例如:

rd.luks.name=1082fcb1-9b0a-480f-86b8-fc52c135a563=root root=/dev/mapper/root

另请参阅dm-crypt/System configuration#内核参数以获取更多详细信息。

提示 如果根分区与/boot分区位于同一磁盘上,并且您的UEFI引导加载程序支持GPT分区自动挂载,则可以配置分区类型GUID(类型应为“Root partition”,而不是“LUKS partition”),并依赖systemd-gpt-auto-generator(8)而不是使用内核参数。

带TPM2和安全启动的分区上的LUKS

此示例类似于#分区上的LUKS,但集成了安全启动可信平台模块(TPM)的使用,增强了启动过程的整体安全性。

在此配置中,只有EFI系统分区保持未加密,它包含一个统一内核镜像systemd-boot—两者都已签名以用于安全启动。如果安全启动被禁用或其密钥数据库被篡改,TPM将不会释放密钥来解锁加密分区。这种方法类似于Windows上的BitLocker或macOS上的FileVault。还将创建一个恢复密钥,以确保数据在TPM解锁机制出现问题时(例如,未签名的引导加载程序或内核更新、固件更新等)仍然可访问。可选地,可以设置一个TPM PIN,在启动时需要它来防止完全自动解锁。

请务必仔细阅读Trusted Platform Module#LUKS加密中的讨论和警告。

在本示例中,分区创建遵循systemd#GPT分区自动挂载,无需fstab或crypttab文件。

+-----------------------+---------------------------------+
| EFI system partition  | LUKS encrypted root partition   |
|                       |                                 |
|                       |                                 |
| /boot                 | /                               |
|                       |                                 |
|                       | /dev/mapper/root                |
|                       |---------------------------------|
| /dev/sda1             | /dev/sda2                       |
+-----------------------+---------------------------------+

请按照Installation guide的步骤执行到Installation guide#分区磁盘

准备磁盘

在创建任何分区之前,您应该了解有关安全擦除磁盘的重要性和方法,这些内容在dm-crypt/Drive preparation中有描述。

使用GUID分区表(GPT)对驱动器进行分区

创建一个具有适当大小的EFI系统分区(例如,/dev/sda1)。这将挂载在/boot

在剩余空间中,创建一个根分区(例如,/dev/sda2),该分区将被加密并挂载在/。使用fdisk中的“Linux root (x86-64)”类型,或者gdisk中的类型码8304来设置根分区的分区类型GUID。

检查fdisk -l的输出,确保分区类型设置正确。

准备根分区

以下命令创建并挂载加密的根分区。它们对应于dm-crypt/Device encryption#使用LUKS模式加密设备中详细描述的过程。

如果您想使用特定的非默认加密选项(例如,加密算法、密钥长度),或者如果您不想使用基于TPM的解密,请在执行第一个命令之前查看加密选项

警告 使用足够安全的密码。即使密钥槽稍后将被擦除,SSD的磨损均衡可能会导致其在移除后无限期地保留。请参阅dm-crypt/Device encryption#使用LUKS格式化带密钥文件的分区

创建LUKS卷并挂载它

# cryptsetup luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root

创建文件系统未解锁的LUKS设备。例如,要创建一个Ext4文件系统,请运行

# mkfs.ext4 /dev/mapper/root

将根卷挂载到/mnt

# mount /dev/mapper/root /mnt

准备EFI系统分区

按照EFI system partition#格式化分区中的说明格式化新创建的EFI系统分区,然后挂载它。

# mount --mkdir /dev/sda1 /mnt/boot

继续安装过程直到Installation guide#Initramfs。您可以跳过Installation guide#Fstab

配置mkinitcpio

要构建一个可用的基于systemd的initramfs,请按如下方式修改mkinitcpio.conf中的HOOKS=

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)

接下来,请参阅Unified kernel image#mkinitcpio来配置mkinitcpio以支持统一内核镜像

不要立即重新生成initramfs,因为/boot/EFI/Linux目录需要由引导加载程序安装程序首先创建。

安装引导加载程序

您可以配置系统直接从UEFI镜像启动,无需任何引导加载程序,请参阅Unified kernel image#直接从UEFI启动

如果您需要引导加载程序,请继续安装systemd-boot,使用

# bootctl install

mkinitcpio生成的统一内核镜像将自动识别,无需在/boot/loader/entries/中创建条目。

有关进一步配置,请参阅systemd-boot#更新UEFI引导管理器systemd-boot#引导加载程序配置

完成安装

首先,重新生成initramfs,并确保镜像生成成功。

确保您没有忘记设置root密码,然后重启以完成安装。

安全启动

现在您可以签名引导加载程序可执行文件和EFI二进制文件,以启用安全启动。对于快速简便的方法,请参阅Unified Extensible Firmware Interface/Secure Boot#使用sbctl的辅助过程

注册TPM

在签名引导加载程序可执行文件并启用安全启动后,您现在可以注册TPM以使用它来解锁LUKS卷。以下命令将删除LUKS格式过程中创建的空密码,创建一个绑定到TPMPCR 7安全启动状态和注册证书)的密钥,并创建一个恢复密钥以在出现任何问题时使用。只要启动链未被篡改,TPM就会自动释放密钥。请参阅systemd-cryptenroll#Trusted Platform Modulesystemd-cryptenroll(1)

# systemd-cryptenroll /dev/sda2 --recovery-key
# systemd-cryptenroll /dev/sda2 --wipe-slot=empty --tpm2-device=auto --tpm2-pcrs=7+15:sha256=0000000000000000000000000000000000000000000000000000000000000000
提示 添加--tpm2-with-pin=yes以在启动时要求额外的PIN码解锁。
警告
  • 在绑定到 PCR 7 时,请确保 安全启动已激活且处于用户模式,否则未经授权的启动设备可能会解锁加密卷。
  • PCR 7的状态可能会在固件证书更改时发生变化,这可能会导致用户被锁定。这可能通过fwupd[2]隐式执行,或通过轮换安全启动密钥显式执行。

LUKS上的LVM

最直接的方法是在加密分区之上设置LVM,而不是反过来。从技术上讲,LVM设置在一个大的加密块设备内。因此,在块设备解锁并且底层卷结构在启动期间被扫描和挂载之前,LVM是不可见的。

本示例中的磁盘布局是

+-----------------------------------------------------------------------+ +----------------+
| Logical volume 1      | Logical volume 2      | Logical volume 3      | | Boot partition |
|                       |                       |                       | |                |
| [SWAP]                | /                     | /home                 | | /boot          |
|                       |                       |                       | |                |
| /dev/MyVolGroup/swap  | /dev/MyVolGroup/root  | /dev/MyVolGroup/home  | |                |
|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _| | (may be on     |
|                                                                       | | other device)  |
|                         LUKS encrypted partition                      | |                |
|                           /dev/sda1                                   | | /dev/sdb1      |
+-----------------------------------------------------------------------+ +----------------+
注意 使用encrypt钩子时,此方法不允许您将逻辑卷跨越多个磁盘;请使用sd-encrypt或参阅dm-crypt/Specialties#修改用于多个分区的encrypt钩子
提示 此设置的两种变体

准备磁盘

在创建任何分区之前,您应该了解有关安全擦除磁盘的重要性和方法,这些内容在dm-crypt/Drive preparation中有描述。

提示 当使用GRUB引导加载程序从GPT磁盘进行BIOS引导时,请创建BIOS引导分区

创建一个分区,该分区将用于挂载/boot,大小为1 GiB或更大。

提示 UEFI系统可以使用EFI系统分区作为/boot

创建一个分区,该分区以后将包含加密容器。

在指定的分区上创建LUKS加密容器。输入两次选择的密码。

# cryptsetup luksFormat /dev/sda1

有关可用cryptsetup选项的更多信息,请在执行上述命令之前参阅LUKS加密选项

打开容器

# cryptsetup open /dev/sda1 cryptlvm

解密后的容器现在位于/dev/mapper/cryptlvm

准备逻辑卷

在打开的LUKS容器之上创建一个物理卷

# pvcreate /dev/mapper/cryptlvm

创建一个卷组(在本例中名为MyVolGroup,但您可以随意命名),并将之前创建的物理卷添加到其中

# vgcreate MyVolGroup /dev/mapper/cryptlvm

在卷组上创建所有逻辑卷

提示 如果逻辑卷将使用ext4格式化,请在卷组中至少留出256 MiB的可用空间,以便使用e2scrub(8)。在用-l 100%FREE创建最后一个卷后,可以通过使用lvreduce -L -256M MyVolGroup/home减小其大小来完成。
# lvcreate -L 4G -n swap MyVolGroup
# lvcreate -L 32G -n root MyVolGroup
# lvcreate -l 100%FREE -n home MyVolGroup

在每个逻辑卷上格式化您的文件系统。例如,为根和home卷使用Ext4

# mkfs.ext4 /dev/MyVolGroup/root
# mkfs.ext4 /dev/MyVolGroup/home
# mkswap /dev/MyVolGroup/swap

挂载您的文件系统

# mount /dev/MyVolGroup/root /mnt
# mount --mkdir /dev/MyVolGroup/home /mnt/home
# swapon /dev/MyVolGroup/swap

准备引导分区

引导加载程序从/boot目录加载内核、initramfs和其自身的配置文件。磁盘上任何可以被引导加载程序读取的文件系统都可以。

在用于/boot的分区上创建一个文件系统。对于UEFI系统上的EFI系统分区,请执行以下命令来格式化新创建的分区

警告: 仅在您于分区步骤中创建了 EFI 系统分区时才进行格式化。如果磁盘上之前已经存在 EFI 系统分区,重新格式化可能会破坏其他已安装操作系统的引导加载程序。
# mkfs.fat -F32 /dev/sdb1

或者对于BIOS系统上的普通引导分区

# mkfs.ext4 /dev/sdb1

将分区挂载到/mnt/boot

# mount --mkdir /dev/sdb1 /mnt/boot

此时恢复通用的 安装指南#安装 步骤。返回此页面以自定义 Initramfs引导加载程序 步骤。

配置mkinitcpio

确保已安装 lvm2 软件包。

如果使用默认的基于 systemd 的 initramfs,请添加 keyboardsd-encryptlvm2 钩子。如果您使用的是非美国英语的控制台键盘布局或非默认控制台字体,请另外添加 sd-vconsole 钩子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)

如果使用基于 busybox 的 initramfs,请在 mkinitcpio.conf 中添加 keyboardencryptlvm2 钩子。如果您使用的是非美国英语的控制台键盘布局或非默认控制台字体,请另外分别添加 keymapconsolefont 钩子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)

保存更改后重新生成initramfs。有关详细信息以及您可能需要的其他钩子,请参阅dm-crypt/System configuration#mkinitcpio

注意:使用 dracut 时,无需进行额外设置,因为所需的模块已包含在内。

配置引导加载程序

为了在启动时解锁加密的根分区,引导加载程序需要设置以下内核参数

rd.luks.name=device-UUID=cryptlvm root=/dev/MyVolGroup/root

如果使用 encrypt 钩子,则需要进行以下设置

cryptdevice=UUID=device-UUID:cryptlvm root=/dev/MyVolGroup/root

device-UUID 指的是 LUKS 超级块的 UUID,在本例中,它是 /dev/sda1 的 UUID,例如 a144e931-7580-40bf-ae8c-6beff4c1ac45。有关详细信息,请参阅 持久性块设备命名

如果使用 dracut,这些参数已知可以正常工作

rd.luks.uuid=device-UUID root=/dev/MyVolGroup/root

您可能需要更广泛的参数列表,请尝试

rd.luks.uuid=luks-deviceUUID rd.lvm.lv=MyVolGroup/root  rd.lvm.lv=MyVolGroup/swap  root=/dev/mapper/MyVolGroup-root rootfstype=ext4 rootflags=rw,relatime

有关详细信息,请参阅 dm-crypt/系统配置#内核参数

LVM 上的 LUKS

要在 LVM 之上使用加密,需要先设置 LVM 卷,然后将其用作加密分区的基础。这样,就可以混合使用加密和非加密的卷/分区。

提示#LVM on LUKS 不同,此方法允许逻辑卷正常跨越多张磁盘。

以下简短示例创建了一个 LVM 上的 LUKS 设置,并混合使用了 /home 分区的密钥文件和一个临时的加密交换分区。从安全角度来看,这是可取的,因为重启后,当加密重新初始化时,没有可能包含敏感的临时数据。如果您熟悉 LVM,您可以根据您的计划忽略/替换 LVM 和其他特定设置。

如果您想跨越多张已设置的磁盘来扩展逻辑卷,或者扩展 /home(或其他任何卷)的逻辑卷,相关过程将在 dm-crypt/特殊情况#扩展 LVM 到多张磁盘 中描述。重要的是要注意,LUKS 加密容器也必须调整大小。

本文章或章节需要扩充。

原因:#概述 中添加了比较后,此场景的介绍需要进行一些调整。建议的结构是使其类似于 #LUKS on a partition 的介绍。(在 Talk:Dm-crypt/Encrypting an entire system 中讨论)

准备磁盘

分区方案

+----------------+-------------------------------------------------------------------------------------------------+
| Boot partition | dm-crypt plain encrypted volume | LUKS encrypted volume         | LUKS encrypted volume         |
|                |                                 |                               |                               |
| /boot          | [SWAP]                          | /                             | /home                         |
|                |                                 |                               |                               |
|                | /dev/mapper/swap                | /dev/mapper/root              | /dev/mapper/home              |
|                |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|
|                | Logical volume 1                | Logical volume 2              | Logical volume 3              |
|                | /dev/MyVolGroup/cryptswap       | /dev/MyVolGroup/cryptroot     | /dev/MyVolGroup/crypthome     |
|                |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|
|                |                                                                                                 |
|   /dev/sda1    |                                   /dev/sda2                                                     |
+----------------+-------------------------------------------------------------------------------------------------+

根据 dm-crypt/磁盘准备#在空设备或分区上擦除 dm-crypt,随机化 /dev/sda2

准备逻辑卷

# pvcreate /dev/sda2
# vgcreate MyVolGroup /dev/sda2
# lvcreate -L 4G -n cryptswap MyVolGroup
# lvcreate -L 32G -n cryptroot MyVolGroup
# lvcreate -l 100%FREE -n crypthome MyVolGroup
# cryptsetup luksFormat /dev/MyVolGroup/cryptroot
# cryptsetup open /dev/MyVolGroup/cryptroot root

在解锁的 LUKS 设备上 创建文件系统 并挂载。例如,要创建一个 Ext4 文件系统,请运行

# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

有关加密选项的更多信息,请参阅 dm-crypt/设备加密#LUKS 模式的加密选项。请注意,/home 将在 #加密逻辑卷 /home 中被加密。

提示 如果您需要从 Arch-ISO 访问加密的根目录,上述 open 操作将在 LVM 显示后 允许您这样做。

准备引导分区

在用于/boot的分区上创建一个文件系统。对于UEFI系统上的EFI系统分区,请执行以下命令来格式化新创建的分区

警告: 仅在您于分区步骤中创建了 EFI 系统分区时才进行格式化。如果磁盘上之前已经存在 EFI 系统分区,重新格式化可能会破坏其他已安装操作系统的引导加载程序。
# mkfs.fat -F32 /dev/sda1

或者对于BIOS系统上的普通引导分区

# mkfs.ext4 /dev/sda1

之后,创建挂载点的目录并挂载分区

# mount --mkdir /dev/sda1 /mnt/boot

配置mkinitcpio

确保已安装 lvm2 软件包。

如果使用默认的基于 systemd 的 initramfs,请添加 keyboardsd-encryptlvm2 钩子。如果您使用的是非美国英语的控制台键盘布局或非默认控制台字体,请另外添加 sd-vconsole 钩子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)

如果使用基于 busybox 的 initramfs,请在 mkinitcpio.conf 中添加 keyboardencryptlvm2 钩子。如果您使用的是非美国英语的控制台键盘布局或非默认控制台字体,请另外分别添加 keymapconsolefont 钩子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block lvm2 encrypt filesystems fsck)

保存更改后重新生成initramfs。有关详细信息以及您可能需要的其他钩子,请参阅dm-crypt/System configuration#mkinitcpio

配置引导加载程序

为了在启动时解锁加密的根分区,引导加载程序需要设置以下内核参数

rd.luks.name=device-UUID=root root=/dev/mapper/root

如果使用encrypt钩子,则需要设置以下参数

cryptdevice=UUID=device-UUID:root root=/dev/mapper/root

device-UUID 指的是 LUKS 超级块的 UUID,在本例中,它是 /dev/MyVolGroup/cryptroot 的 UUID,例如 a144e931-7580-40bf-ae8c-6beff4c1ac45。有关详细信息,请参阅 持久性块设备命名

有关详细信息,请参阅 dm-crypt/系统配置#内核参数

配置 fstab 和 crypttab

需要 crypttab 和 fstab 条目才能分别解锁设备和挂载文件系统。以下行将在每次重启时重新加密交换分区

/etc/crypttab
swap	/dev/MyVolGroup/cryptswap	/dev/urandom	swap,cipher=aes-xts-plain64,size=256,sector-size=4096
/etc/fstab
/dev/mapper/root                          /     ext4   defaults  0 1
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /boot ext4   defaults  0 2
/dev/mapper/swap                          none  swap   defaults  0 0

加密逻辑卷 /home

由于此场景使用 LVM 作为主映射器,dm-crypt 作为次映射器,每个加密的逻辑卷都需要单独加密。然而,与上面配置的具有临时加密的临时文件系统不同,/home 的逻辑卷当然应该是持久的。以下内容假定您已重启到已安装的系统,否则您需要调整路径。为了避免在启动时输入第二个密码,会创建一个 密钥文件

# dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/home.key

逻辑卷将使用此密钥进行加密

# cryptsetup luksFormat -v /dev/MyVolGroup/crypthome /etc/cryptsetup-keys.d/home.key
# cryptsetup -d /etc/cryptsetup-keys.d/home.key open /dev/MyVolGroup/crypthome home

在解锁的 LUKS 设备上 创建文件系统 并挂载。例如,要创建一个 Ext4 文件系统,请运行

# mkfs.ext4 /dev/mapper/home
# mount /dev/mapper/home /home

加密挂载配置在 crypttab 和 fstab 中

/etc/crypttab
home	/dev/MyVolGroup/crypthome   none
/etc/fstab
/dev/mapper/home        /home   ext4        defaults        0       2

软件 RAID 上的 LUKS

本示例基于一台配备两块相同大小 SSD 和一块用于大容量存储的额外 HDD 的工作站级笔记本电脑的实际设置。最终结果是所有驱动器的基于 LUKS 的全盘加密(包括 /boot),SSD 组成 RAID0 阵列,并使用密钥文件在 GRUB 接受正确的密码后解锁所有加密。

此设置采用非常简单的分区方案,所有可用的 RAID 存储都挂载在 / (没有单独的 /boot 分区),解密后的 HDD 挂载在 /data。

请注意,在此设置中,常规 备份 非常重要。如果其中任何一块 SSD 发生故障,RAID 阵列中的数据将几乎无法恢复。如果您重视容错能力,可以考虑选择不同的 RAID 级别

此设置中的加密是不可否认的。

为了方便下面的说明,将使用以下块设备

/dev/sda = first SSD
/dev/sdb = second SSD
/dev/sdc = HDD
+---------------------+---------------------------+---------------------------+ +---------------------+---------------------------+---------------------------+ +---------------------------+
| BIOS boot partition | EFI system partition      | LUKS encrypted volume     | | BIOS boot partition | EFI system partition      | LUKS encrypted volume     | | LUKS encrypted volume     |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     | /efi                      | /                         | |                     | /efi                      | /                         | | /data                     |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     |                           | /dev/mapper/root          | |                     |                           | /dev/mapper/root          | |                           |
|                     +---------------------------+---------------------------+ |                     +---------------------------+---------------------------+ |                           |
|                     | RAID1 array (part 1 of 2) | RAID0 array (part 1 of 2) | |                     | RAID1 array (part 2 of 2) | RAID0 array (part 2 of 2) | |                           |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     | /dev/md/ESP               | /dev/md/root              | |                     | /dev/md/ESP               | /dev/md/root              | | /dev/mapper/data          |
|                     +---------------------------+---------------------------+ |                     +---------------------------+---------------------------+ +---------------------------+
| /dev/sda1           | /dev/sda2                 | /dev/sda3                 | | /dev/sdb1           | /dev/sdb2                 | /dev/sdb3                 | | /dev/sdc1                 |
+---------------------+---------------------------+---------------------------+ +---------------------+---------------------------+---------------------------+ +---------------------------+

请确保用您设置的相应设备标识符替换它们,因为它们可能不同。

准备磁盘

在创建任何分区之前,您应该了解有关安全擦除磁盘的重要性和方法,这些内容在dm-crypt/Drive preparation中有描述。

对于带有 GPT 的 BIOS 系统,请创建一个大小为 1 MiB 的 BIOS 引导分区,以便 GRUB 存储 BIOS 引导加载程序的第二阶段。请勿挂载该分区。

对于 UEFI 系统,请创建一个大小合适的 EFI 系统分区,它将在之后挂载到 /efi。

在驱动器上的剩余空间中,为“Linux RAID”创建一个分区(本例中为 /dev/sda3)。对于 MBR,选择分区类型 ID fd;对于 GPT,选择分区类型 GUID A19D880F-05FC-4D3B-A006-743F0F84911E

在 /dev/sda 上创建分区后,可以使用以下命令将它们克隆到 /dev/sdb。

# sfdisk -d /dev/sda > sda.dump
# sfdisk /dev/sdb < sda.dump

HDD 已准备好,其整个驱动器都被一个 Linux 分区覆盖,位于 /dev/sdc1。

构建 RAID 阵列

为 SSD 创建 RAID 阵列。

  • EFI 系统分区的每个部分都必须单独可用,这意味着 ESP 只能放置在 RAID1 阵列中。
  • RAID 超级块必须放置在 EFI 系统分区的末尾,使用 --metadata=1.0,否则固件将无法访问该分区。
# mdadm --create --verbose --level=1 --metadata=1.0 --raid-devices=2 /dev/md/ESP /dev/sda2 /dev/sdb2

本示例对根目录使用了 RAID0,您可以根据自己的偏好或需求选择不同的级别。

# mdadm --create --verbose --level=0 --metadata=1.2 --raid-devices=2 /dev/md/root /dev/sda3 /dev/sdb3

准备块设备

dm-crypt/磁盘准备 中所述,使用 /dev/zero 和带有随机密钥的 crypt 设备用随机数据擦除设备。或者,您也可以使用 dd/dev/random/dev/urandom,但这会慢得多。

# cryptsetup open --type plain --sector-size 4096 --key-file /dev/urandom /dev/md/root to_be_wiped
# dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=1M status=progress
# cryptsetup close to_be_wiped

然后重复以上操作处理 HDD(本例中为 /dev/sdc1)。

设置 /dev/md/root 的加密

警告 GRUB 对 LUKS2 的支持有限;详情请参阅 GRUB#加密 /boot。对于 GRUB 需要解锁的分区,请使用 PBKDF2(cryptsetup luksFormat --pbkdf pbkdf2)来使用 LUKS2。
# cryptsetup -v luksFormat --pbkdf pbkdf2 /dev/md/root
# cryptsetup open /dev/md/root root

创建文件系统未解锁的LUKS设备。例如,要创建一个Ext4文件系统,请运行

# mkfs.ext4 /dev/mapper/root

将根卷挂载到/mnt

# mount /dev/mapper/root /mnt

并为 HDD 重复

# cryptsetup -v luksFormat /dev/sdc1
# cryptsetup open /dev/sdc1 data
# mkfs.ext4 /dev/mapper/data
# mount --mkdir /dev/mapper/data /mnt/data

对于 UEFI 系统,格式化新创建的 EFI 系统分区并挂载它

警告: 仅在您于分区步骤中创建了 EFI 系统分区时才进行格式化。如果磁盘上之前已经存在 EFI 系统分区,重新格式化可能会破坏其他已安装操作系统的引导加载程序。
# mkfs.fat -F32 /dev/md/ESP
# mount --mkdir /dev/md/ESP /mnt/efi

配置 GRUB

通过编辑 /etc/default/grub 来配置 GRUB 以支持 LUKS 加密系统,使用以下内容:

GRUB_CMDLINE_LINUX="cryptdevice=/dev/md/root:root"
GRUB_ENABLE_CRYPTODISK=y

如果您有一个较新系统的 USB 键盘,请在固件中启用传统 USB 支持,或将以下内容添加到 /etc/default/grub

GRUB_TERMINAL_INPUT="usb_keyboard"
GRUB_PRELOAD_MODULES="usb usb_keyboard ohci uhci ehci"

否则,您可能无法在 LUKS 提示符下使用键盘。

有关详细信息,请参阅 dm-crypt/系统配置#内核参数GRUB#加密 /boot

完成 GRUB 在两个 SSD 上的安装(实际上,仅安装到 /dev/sda 即可)。

# grub-install --target=i386-pc /dev/sda
# grub-install --target=i386-pc /dev/sdb
# grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB
# grub-mkconfig -o /boot/grub/grub.cfg

创建密钥文件

接下来的步骤将使您不必在启动系统时输入两次密码(一次是 GRUB 解锁 LUKS 设备,一次是 initramfs 接管系统)。这是通过创建一个 密钥文件 并将其添加到 initramfs 映像来完成的,以便 encrypt 钩子可以解锁根设备。详情请参阅 dm-crypt/设备加密#嵌入 initramfs 的密钥文件

  • 创建 密钥文件 并将密钥添加到 /dev/md/root
  • 为 HDD(本例中为 /dev/sdc1)创建另一个密钥文件,以便它也可以在启动时解锁。为了方便起见,请保留上面创建的密码,这样如果您需要恢复,会更容易。编辑 /etc/crypttab 以在启动时解密 HDD。请参阅 dm-crypt/系统配置#使用密钥文件解锁

配置系统

编辑 fstab 以挂载根目录和数据块设备以及 ESP

/dev/mapper/root  /	  ext4	rw,noatime 	   0 1
/dev/mapper/data  /data   ext4	defaults           0 2
/dev/md/ESP       /efi     vfat	rw,relatime,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,tz=UTC,errors=remount-ro  	0 2

保存 RAID 配置

# mdadm --detail --scan >> /etc/mdadm.conf

编辑 mkinitcpio.conf 以包含您的密钥文件并添加正确的钩子

FILES=(/crypto_keyfile.bin)
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block mdadm_udev encrypt filesystems fsck)

有关详细信息,请参阅 dm-crypt/系统配置#mkinitcpio

纯 dm-crypt

与 LUKS 不同,dm-crypt 的 *纯* 模式不需要在加密设备上有一个头:此场景利用此功能在未分区的加密磁盘上设置系统,该系统将与充满随机数据的磁盘无法区分,这可能允许 可否认加密。另请参阅 wikipedia:磁盘加密#全盘加密

请注意,如果不需要全盘加密,上面各节中 LUKS 的方法是系统加密和加密分区的更好选择。*纯* 模式无法使用 LUKS 功能,例如多密码/密钥文件管理、主密钥备份或原地重新加密设备。

*纯* dm-crypt 加密可能比 LUKS 更能抵抗损坏,因为它不依赖于加密主密钥,如果损坏或被强制销毁,加密主密钥可能成为单点故障。然而,使用*纯*模式还需要更多手动配置加密选项才能达到相同的加密强度。另请参阅 数据加密#加密元数据。如果您担心 dm-crypt/特殊情况#固态硬盘 (SSD) 的 Discard/TRIM 支持 中解释的问题,也可以考虑使用*纯*模式。

提示 如果您的目标是无头加密,但又不确定*纯*模式缺乏密钥派生,那么有两种替代方案:

该场景使用两个 USB 驱动器

  • 一个用于启动设备,它还可以存储在引导加载程序配置中打开/解锁纯加密设备所需的选项,因为每次启动时输入这些选项可能会出错;
  • 另一个用于加密密钥文件,假设它存储为原始位,以便对可能获得 U 盘的不知情攻击者来说,加密密钥将显示为随机数据而不是作为普通文件可见。另请参阅 Wikipedia:安全即是 the obscurity,按照 dm-crypt/设备加密#密钥文件 准备密钥文件。

磁盘布局是

+----------------------+----------------------+----------------------+ +----------------+ +----------------+
| Logical volume 1     | Logical volume 2     | Logical volume 3     | | Boot device    | | Encryption key |
|                      |                      |                      | |                | | file storage   |
| /                    | [SWAP]               | /home                | | /boot          | | (unpartitioned |
|                      |                      |                      | |                | | in example)    |
| /dev/MyVolGroup/root | /dev/MyVolGroup/swap | /dev/MyVolGroup/home | | /dev/sdb1      | | /dev/sdc       |
|----------------------+----------------------+----------------------| |----------------| |----------------|
| disk drive /dev/sda encrypted using plain mode and LVM             | | USB stick 1    | | USB stick 2    |
+--------------------------------------------------------------------+ +----------------+ +----------------+
提示
  • 也可以使用单个 USB 密钥物理设备
    • 将密钥放在 USB 存储设备(/dev/sdb)的另一个分区(/dev/sdb2)上。
    • 将密钥文件直接复制到 initramfs。通过在 /etc/mkinitcpio.conf 中设置 FILES=(/etc/cryptsetup-keys.d/root.key),可以将示例密钥文件 /etc/cryptsetup-keys.d/root.key 复制到 initramfs 映像。指示 encrypt 钩子读取 initramfs 映像中的密钥文件的方法是在文件名之前使用 rootfs: 前缀,例如 cryptkey=rootfs:/etc/cryptsetup-keys.d/root.key
  • 另一个选项是使用具有良好 的密码。

准备磁盘

映射设备必须用随机数据填充,这一点至关重要。特别是这适用于我们在此处应用的场景。

请参阅 dm-crypt/磁盘准备dm-crypt/磁盘准备#dm-crypt 特定方法

准备非启动分区

有关详细信息,请参阅 dm-crypt/设备加密#纯模式的加密选项

使用设备 /dev/sda,具有 aes-xts 密码、512 位密钥大小并使用密钥文件,我们为本场景提供了以下选项:

# cryptsetup open --type plain --cipher=aes-xts-plain64 --offset=0 --key-file=/dev/sdc --key-size=512 --sector-size 4096 /dev/sda cryptlvm

与 LUKS 加密不同,上述命令必须在需要重新建立映射时*完整*执行,因此请务必记住密码和密钥文件详情。

我们现在可以检查是否为 /dev/mapper/cryptlvm 创建了映射条目

# fdisk -l
提示
  • 对于不需要 LVM 的情况,cryptsetup FAQ 推荐了一种更简单的替代方法:直接在整个映射的 dm-crypt 设备上创建文件系统。
  • 如果逻辑卷将被格式化为 ext4,请在卷组中至少留出 256 MiB 的可用空间,以便使用 e2scrub(8)。在创建最后一个卷并使用 -l 100%FREE 后,可以通过使用 lvreduce -L -256M MyVolGroup/home 减小其大小来实现。

接下来,我们在映射设备上设置 LVM 逻辑卷。有关更多详细信息,请参阅 在 LVM 上安装 Arch Linux

# pvcreate /dev/mapper/cryptlvm
# vgcreate MyVolGroup /dev/mapper/cryptlvm
# lvcreate -L 32G MyVolGroup -n root
# lvcreate -L 4G MyVolGroup -n swap
# lvcreate -l 100%FREE MyVolGroup -n home

我们格式化并挂载它们,然后激活交换分区。有关更多详细信息,请参阅 文件系统#创建文件系统

# mkfs.ext4 /dev/MyVolGroup/root
# mkfs.ext4 /dev/MyVolGroup/home
# mount /dev/MyVolGroup/root /mnt
# mount --mkdir /dev/MyVolGroup/home /mnt/home
# mkswap /dev/MyVolGroup/swap
# swapon /dev/MyVolGroup/swap

准备引导分区

/boot 分区可以是 USB 驱动器上的典型 FAT32 格式分区,如果需要的话。但如果需要手动分区,则只需一个 1 GiB 的小分区。使用您选择的 分区工具 创建该分区。

在新建的分区上创建用于 /boot文件系统

警告: 仅在您于分区步骤中创建了 EFI 系统分区时才进行格式化。如果磁盘上之前已经存在 EFI 系统分区,重新格式化可能会破坏其他已安装操作系统的引导加载程序。
# mkfs.fat -F32 /dev/sdb1
# mount --mkdir /dev/sdb1 /mnt/boot

配置mkinitcpio

确保已安装 lvm2 软件包。

如果使用默认的基于 busybox 的 initramfs,请在 mkinitcpio.conf 中添加 keyboardencryptlvm2 钩子。如果您使用的是非美国英语的控制台键盘布局或非默认控制台字体,请另外分别添加 keymapconsolefont 钩子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)

保存更改后重新生成initramfs。有关详细信息以及您可能需要的其他钩子,请参阅dm-crypt/System configuration#mkinitcpio

配置引导加载程序

为了启动加密的根分区,引导加载程序需要设置以下 内核参数(请注意,64 是 512 位字节数)

cryptdevice=/dev/disk/by-id/disk-ID-of-sda:cryptlvm:sector-size=4096 cryptkey=/dev/disk/by-id/disk-ID-of-sdc:0:64 crypto=:aes-xts-plain64:512:0:

disk-ID-of-disk 指的是引用磁盘的 ID。有关详细信息,请参阅 持久性块设备命名

有关详细信息和其他可能需要的参数,请参阅 dm-crypt/系统配置#内核参数

提示 如果使用 GRUB,您可以将其安装在与 /boot 分区相同的 USB 上。

对于 BIOS

# grub-install --target=i386-pc --recheck /dev/sdb

对于 UEFI

# grub-install --target=x86_64-efi --efi-directory=/boot --removable

安装后的后续步骤

您可能希望在启动后移除 USB 驱动器。由于通常不需要 /boot 分区,因此可以将 noauto 选项添加到 /etc/fstab 的相关行中。

/etc/fstab
# /dev/sdb1
UUID=XXXX-XXXX /boot vfat noauto,rw,noatime 0 2

但是,当需要更新 initramfs 中的任何内容、内核或引导加载程序时,必须存在并挂载 /boot 分区。由于 fstab 中已存在条目,只需使用以下命令即可挂载:

# mount /boot

加密的启动分区(GRUB)

此设置使用与前一个 #LVM on LUKS 部分相同的分区布局和配置,区别在于使用了 GRUB 引导加载程序,因为它能够从 LVM 逻辑卷和 LUKS 加密的 /boot 启动。另请参阅 GRUB#加密 /boot

本示例中的磁盘布局是

+---------------------+----------------------+----------------------+----------------------+----------------------+
| BIOS boot partition | EFI system partition | Logical volume 1     | Logical volume 2     | Logical volume 3     |
|                     |                      |                      |                      |                      |
|                     | /efi                 | /                    | [SWAP]               | /home                |
|                     |                      |                      |                      |                      |
|                     |                      | /dev/MyVolGroup/root | /dev/MyVolGroup/swap | /dev/MyVolGroup/home |
| /dev/sda1           | /dev/sda2            |----------------------+----------------------+----------------------+
| unencrypted         | unencrypted          | /dev/sda3 encrypted using LVM on LUKS                              |
+---------------------+----------------------+--------------------------------------------------------------------+
提示
  • 所有场景都仅作为示例。当然,也可以将以上两个不同的安装步骤与其它场景结合使用。另请参阅 #LVM on LUKS 中链接的变体。
  • 您可以使用 cryptbootAUR 包中的 cryptboot 脚本来简化加密启动管理(挂载、卸载、升级软件包),并作为 UEFI 安全启动Evil Maid 攻击的防御手段。有关更多信息和限制,请参阅 cryptboot 项目 页面。

准备磁盘

在创建任何分区之前,您应该了解有关安全擦除磁盘的重要性和方法,这些内容在dm-crypt/Drive preparation中有描述。

对于 UEFI 系统,请创建一个大小合适的 EFI 系统分区,它将在之后挂载到 /efi。

对于 BIOS/GPT 设置,请创建一个大小为 1 MiB 的 BIOS 引导分区,以便 GRUB 存储 BIOS 引导加载程序的第二阶段。请勿挂载该分区。对于 BIOS/MBR 设置,这不是必需的。

创建一个类型为 8309 的分区,该分区将包含 LVM 的加密容器。

创建 LUKS 加密容器

警告 GRUB 对 LUKS2 的支持有限;详情请参阅 GRUB#加密 /boot。对于 GRUB 需要解锁的分区,请使用 PBKDF2(cryptsetup luksFormat --pbkdf pbkdf2)来使用 LUKS2。
# cryptsetup luksFormat --pbkdf pbkdf2 /dev/sda3

有关可用cryptsetup选项的更多信息,请在执行上述命令之前参阅LUKS加密选项

您的分区布局应该类似于这样

# gdisk -l /dev/sda
...
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            4095   1024.0 KiB  EF02  BIOS boot partition
   2            4096         2101247   1024.0 MiB  EF00  EFI system partition
   3         2101248        69210111   32.0 GiB    8309  Linux LUKS

打开容器

# cryptsetup open /dev/sda3 cryptlvm

解密后的容器现在位于/dev/mapper/cryptlvm

准备逻辑卷

本示例中的 LVM 逻辑卷遵循与 #LVM on LUKS 场景完全相同的布局。因此,请遵循 #准备逻辑卷 并根据需要进行调整。

对于 UEFI 系统,为 EFI 系统分区 创建一个挂载点 /efi,以兼容 grub-install 并挂载它。

# mount --mkdir /dev/sda2 /mnt/efi

此时,您应该在 /mnt 下拥有以下分区和逻辑卷:

$ lsblk
NAME                  MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                   8:0      0   200G  0 disk
├─sda1                8:1      0     1M  0 part
├─sda2                8:2      0   550M  0 part  /mnt/efi
└─sda3                8:3      0   100G  0 part
  └─cryptlvm          254:0    0   100G  0 crypt
    ├─MyVolGroup-swap 254:1    0     4G  0 lvm   [SWAP]
    ├─MyVolGroup-root 254:2    0    32G  0 lvm   /mnt
    └─MyVolGroup-home 254:3    0    60G  0 lvm   /mnt/home

此时,恢复通用的 安装指南#安装 步骤。返回此页面以自定义 Initramfs引导加载程序 步骤。

配置mkinitcpio

确保已安装 lvm2 软件包。

如果使用默认的基于 systemd 的 initramfs,请添加 keyboardsd-encryptlvm2 钩子。如果您使用的是非美国英语的控制台键盘布局或非默认控制台字体,请另外添加 sd-vconsole 钩子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)

如果使用基于 busybox 的 initramfs,请在 mkinitcpio.conf 中添加 keyboardencryptlvm2 钩子。如果您使用的是非美国英语的控制台键盘布局或非默认控制台字体,请另外分别添加 keymapconsolefont 钩子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)

保存更改后重新生成initramfs。有关详细信息以及您可能需要的其他钩子,请参阅dm-crypt/System configuration#mkinitcpio

配置 GRUB

配置 GRUB 以允许从 LUKS 加密的 /boot 分区启动

/etc/default/grub
GRUB_ENABLE_CRYPTODISK=y

设置内核参数,以便 initramfs 可以解锁加密的根分区。使用 encrypt 钩子

/etc/default/grub
GRUB_CMDLINE_LINUX="... rd.luks.name=device-UUID=cryptlvm ..."

如果使用encrypt钩子,则需要设置以下参数

/etc/default/grub
GRUB_CMDLINE_LINUX="... cryptdevice=UUID=device-UUID:cryptlvm ..."

有关详细信息,请参阅 dm-crypt/系统配置#内核参数GRUB#加密 /bootdevice-UUID 指的是 LUKS 超级块的 UUID,在本例中,它是 /dev/sda3(包含 LVM 并包含根文件系统的分区)的 UUID,例如 a144e931-7580-40bf-ae8c-6beff4c1ac45。有关详细信息,请参阅 持久性块设备命名

对于 UEFI 启动,将 GRUB 安装到挂载的 ESP。

# grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB --recheck

对于 BIOS 启动,将 GRUB 安装到磁盘。

# grub-install --target=i386-pc --recheck /dev/sda

生成 GRUB 的 配置文件

# grub-mkconfig -o /boot/grub/grub.cfg

如果所有命令都成功完成,下次重启后 GRUB 应该会提示输入密码以解锁 /dev/sda3 分区。

避免输入两次密码

本文档或章节候选合并到 Dm-crypt/设备加密#嵌入 initramfs 的密钥文件

注意: 内容重复过多,此概览页面的内容过多。(在 Talk:Dm-crypt/Encrypting an entire system#GRUB 密钥文件的安全问题 中讨论)

按照上述说明,GRUB 会要求输入密码以解锁 LUKS 加密分区,但分区解锁不会传递给 initramfs。因此,您必须在启动时输入两次密码:一次给 GRUB,一次给 initramfs。

本节介绍如何进行额外配置,以便仅在 GRUB 中输入一次密码即可启动系统。这是通过 嵌入 initramfs 的密钥文件 来实现的。

首先创建密钥文件并将其添加为 LUKS 密钥

# dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/cryptlvm.key
# cryptsetup -v luksAddKey /dev/sda3 /etc/cryptsetup-keys.d/cryptlvm.key

将密钥文件添加到 initramfs 映像

/etc/mkinitcpio.conf
FILES=(/etc/cryptsetup-keys.d/cryptlvm.key)

重新生成 initramfs.

使用默认的 sd-encrypt 钩子时,默认会使用 /etc/cryptsetup-keys.d/name.key,因此无需设置额外的内核参数。

使用 encrypt 钩子时,请设置以下内核参数以使用密钥文件解锁 LUKS 分区:

GRUB_CMDLINE_LINUX="... cryptkey=rootfs:/etc/cryptsetup-keys.d/cryptlvm.key"

如果由于某种原因密钥文件未能解锁启动分区,systemd 将回退到要求输入密码,如果密码正确,则继续启动。

提示 如果您想加密 /boot 分区以防止离线篡改威胁,已贡献了 mkinitcpio-chkcryptoboot 钩子来提供帮助。

使用 USB 驱动器解锁 /boot

为避免记住复杂的密码或使用容易被猜中的简单密码,可以使用存储在外部 USB 驱动器上的密钥文件来解锁 LUKS 卷。为了安全起见,在使用此 USB 驱动器时,必须将其远离计算机并妥善保管。

首先,以与 #避免输入两次密码 相同的方式生成密钥文件。不要使用相同的密钥文件,因为如果 USB 驱动器丢失或泄露,您将需要替换 initramfs 中嵌入的密钥文件。

将此密钥文件复制到您的 USB 驱动器并创建一个新的 GRUB 配置文件

/boot/grub/grub-pre.cfg
set crypto_uuid=UUID-of-the-luks-volume
set key_disk=UUID-of-the-volume-with-the-key
cryptomount -u $crypto_uuid -k ($key_disk)/the-location-of-the-key-on-your-usb
set root=UUID-of-the-unlocked-volume-as-in-grub.cfg
set prefix=($root)/boot/grub
insmod normal
normal

创建 GRUB 映像并安装它(所需的模块数量取决于您的文件系统)

# grub-mkimage -p /boot/grub -O x86_64-efi -c /boot/grub/grub-pre.cfg -o /tmp/grubx64.efi  part_gpt  part_msdos cryptodisk  luks  gcry_rijndael gcry_sha512 lvm ext2 ntfs fat exfat
# install -v /tmp/grubx64.efi /efi/EFI/GRUB/grubx64.efi

ZFS 上的根目录

本文或本节正考虑移除。

原因: ZFS 上的 LUKS 或纯 dm-crypt 与其他文件系统上的 LUKS 或纯 dm-crypt 在加密设置上没有本质区别。ZFS 原生加密不在本文档的讨论范围之内。(在 Talk:Dm-crypt/Encrypting an entire system 中讨论)

要将 dm-crypt 与 ZFS 结合使用,请参阅 ZFS#使用 dm-crypt 在 ZFS 中进行加密

此外,ZFS 还提供 原生加密,也可以用来加密系统根目录,但不包括引导加载程序和文件系统元数据。请参阅

安装完成后,可以在基于 UEFI 的系统上使用 安全启动 来验证引导加载程序。