dm-crypt/加密整个系统 - Arch Linux 中文维基

跳转到内容

# dm-crypt/加密整个系统

来自 Arch Linux 中文维基
< Dm-crypt

翻译状态：

- 本文（或部分内容）译自 dm-crypt/Encrypting an entire system，最近一次同步于 2025-07-10，若英文版本有所更改，则您可以帮助同步与翻译更改的内容。
- 您可以在 ArchWiki 的对应页面找到本文翻译的原始修订历史。
- 本文可能与英文原文存在出入。

本文介绍了几种常见的使用“dm-crypt”加密整个系统的方式，以及相比正常安装过程所需的改动。官方安装镜像已经包含了加密所需的工具。

若要加密的是已有的未加密的文件系统，见 dm-crypt/设备加密#加密现有的未加密文件系统。

## 概览

“dm-crypt”能为为根文件系统提供安全保护，且相比其它方案具更优的性能。相比仅仅加密部分非根文件系统，加密根文件系统可以隐藏许多敏感信息（如已安装应用列表、用户名等），并能避免通过locate、`/var/log/`等常见方式泄露数据。此外，由于除了引导加载程序和内核（通常情况下），所有数据都被加密，更难对系统进行未授权的改动。

除了上面提到的共同优点以外，各种加密方案还有如下特有的优缺点：

方案 | 优点 | 缺点
--- | --- | ---
#在单一分区上配置LUKS 展示了使用LUKS完全加密的根文件系统的基本方式，最直接。 | 分区与配置简单。 在使用GPT的磁盘上，systemd可自动挂载根分区。 | 不灵活；用于加密的整个磁盘空间需要预先分配。
#使用TPM2和安全启动在单一分区上配置 与上例相似，并通过使用安全启动、TPM2提高了安全性。 | 相比上例，本方法还有如下优点： 安全启动可抵御邪恶女佣攻击。 在安全启动被关闭或配置被修改时，TPM2将阻止解密。 | 与上例缺点相似。
#在LUKS上配置LVM 在LUKS加密的单一分区上配置LVM，实现了分区灵活性。 | 通过LVM，可简单地在加密设备上配置多个分区。 只需单一密码即可解密所有分区。 在未解密时系统的分区结构不可见。 若要使用休眠功能，这是最简单的方式。 | LVM增加了系统设备映射结构的复杂性，且需要单独添加钩子。 难以对某个分区单独指定密码。 若需要配置的LVM卷组包含多个物理卷，则所有物理卷必须分别进行LUKS加密。在系统启动时，必须分别解锁所有物理卷后，才能激活并使用卷组。
#在LVM上配置LUKS 在LVM上层使用LUKS。 | 可通过LVM将（单个）加密分区拓展到多个磁盘上。 可方便地同时配置加密与未加密分区。 | 若更改了LVM逻辑卷的结构，需要同时更改加密设备与逻辑卷的对应关系，配置复杂。 每个逻辑卷需要单独设置密码。 LVM中逻辑卷的结构在未解密时也是可见的。 由于每个加密的逻辑卷都需要单独解密，系统启动较慢。
#在软RAID上配置LUKS 在软RAID上层使用LUKS。 | 与在LVM上配置LUKS相似。 | 与在LVM上配置LUKS，并使用加密引导分区类似。
#Plain dm-crypt 使用dm-crypt的plain模式（不使用LUKS头及LUKS的多密钥选项）。 此方案还将`/boot`配置到USB设备上，并通过USB设备储存密钥。该思路也适用于其它方案。 | 在面临可能损坏LUKS头的意外情况时，仍能保证数据完整性。 能够实现可抵赖加密。 有助于解决在SSD上应用加密的一些问题。 | 需要尤其关注所有使用的加密参数。 只能使用单个密码且不能更换密码。 即使对于常规系统，配置也非常复杂。
#加密boot分区（GRUB） 展示了如何在使用GRUB时加密boot分区。 该方案还使用了EFI系统分区，这也适用于其它方案。 | 与选择的加密配置方式相同的优点。（在本例中采用在LUKS上配置LVM） 未加密的数据更少，只有引导加载程序和EFI系统分区（若有）未加密。 | 与选择的加密配置方式相同的缺点。（在本例中采用在LUKS上配置LVM） 配置更复杂。 其它引导加载程序不支持此方案。 GRUB解密LUKS卷所需的时间较长，将减慢启动速度。
#Root on ZFS | 若将`zpool`加密，则其中的所有数据集（dataset）都将使用相同的ZFS加密设置加密。同时，由于加密在ZFS层面进行，支持ZFS的系统都可解密，便于配置双系统或在不同系统间共享数据。 可将加密的文件系统安全地备份到未加密的ZFS中。产生的文件系统快照将保持原生加密状态。 | ZFS 不会加密有关存储池结构的文件系统元数据（例如，数据集/快照名称，数据集结构/属性/文件大小/文件空洞，deduplication tables(though the deduplicated data itself is encrypted)）。 若要追求最佳性能，需要根据磁盘物理属性创建存储池时（甚至需要考虑物理块大小`ashift`）。 ZFS的`aes`实现存在一些问题；此外，某些加密算法的实现可能存在性能问题。 使用`zvol`作为交换分区或者使用数据集中的文件作为交换文件存在问题。只能通过关闭休眠并设置交换分区到其它分区（详见下）解决。

虽然对于外界威胁，相比文件系统层面的加密，上述方案提供了好得多的保护。但也有一个共同的缺点：任何拥有密码的用户都能解密整个设备，进而访问其它用户的数据。若要防范上述风险，可以结合使用块设备加密和文件系统加密。可参见静态数据加密进行提前规划。

对于本文中所有方案的分区策略的概述，参见dm-crypt/准备磁盘#分区。

此外，还需考虑是否设置加密的swap分区及设置方式。详见Dm-crypt/交换分区加密。

加密整个系统可在设备失窃时保护数据，但不能抵御逻辑层面的非法修改（例如，系统上运行的恶意软件修改未加密的boot分区）。若有相关需求，还应参见dm-crypt/特殊应用#保护未加密的boot分区。

在使用固态硬盘时，可能需要启用TRIM支持。但这可能影响安全性，详见dm-crypt/特殊应用#固态硬盘的Discard/TRIM支持。

警告：

- 在任何情况下都不要直接在加密卷上运行文件系统修复工具（例如，fsck），否则，加密密钥将永久丢失，使得所有加密内容无法被解密。只应当在解密后的设备上运行文件系统修复工具。
- Argon2 密钥派生函数的设计方式使得其在运行时将占用大量内存（在默认设置下，每个加密卷将占用1GiB内存）。在设备内存较少或启动时并行解密多个LUKS2分区的情况下，可能导致错误。可使用`--pbkdf-memory`选项控制内存使用。[1]
- GRUB对LUKS2的支持并不完善，详见GRUB#加密的/boot。对于需要由GRUB解密的分区，建议使用PBKDF2密钥派生函数（`cryptsetup luksFormat --pbkdf pbkdf2`）。
- 对于ZFS，即使交换分区并没有放置在zvol上，从休眠中唤醒时也有可能损坏存储池。因此在配置休眠时需要额外注意。参考

## 在单一分区上配置LUKS

本例说明了如何通过“dm-crypt”与LUKS，将安装在单一分区上的系统进行加密。

    +-----------------------+------------------------+-----------------------+
    | boot分区              | LUKS加密的根分区      | 可选的用于其它分区的  |
    |                       | partition              | 空闲空间              |
    |                       |                        |                       |
    | /boot                 | /                      |                       |
    |                       |                        |                       |
    |                       | /dev/mapper/root       |                       |
    |                       |------------------------|                       |
    | /dev/sda1             | /dev/sda2              |                       |
    +-----------------------+------------------------+-----------------------+

本例的前几步可在启动到Arch Linux安装镜像后直接进行。

### 准备磁盘

在创建分区前，应先查看dm-crypt/准备磁盘，了解安全地擦除整个磁盘的重要性，并掌握相关方法。

接下来，创建本例中的分区（至少需要`/`（`/dev/sda2`）和`/boot`（`/dev/sda1`），详见分区。

### 准备非boot分区

在格式化分区时，不要使用安装指南中的步骤，而是使用本节及下一节的步骤。

使用如下命令创建并挂载加密的根分区，dm-crypt/设备加密#使用 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/加密非root文件系统#自动解锁并挂载。

注意，对于每个要加密并挂载的块设备，都需要单独设置密钥，这将导致在启动时需要多次输入密钥，造成不便。可通过在根分区中存储密钥文件，并通过修改`crypttab`设置，自动使用密钥文件解锁其它设备。详见dm-crypt/设备加密#使用LUKS来格式化带有密钥文件的分区。

### 准备boot分区

对于加密根分区的配置，需要设置非加密的`/boot`分区。

对于UEFI启动的系统，使用如下命令格式化新创建的EFI 系统分区：

警告：只有在EFI系统分区是在安装Arch Linux的分区步骤中创建的情况下，才应当格式化该分区。否则，若EFI系统分区是由其它系统创建的，则重新格式化将导致其它系统的引导程序丢失。

    # mkfs.fat -F32 /dev/sda1

对于传统BIOS启动的系统：

    # mkfs.ext4 /dev/sda1

之后，创建boot分区的挂载点并挂载分区：

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

### 挂载分区

在安装指南#挂载分区步骤时，应当挂载`/dev/mapper/*`中的相应设备（包含LUKS加密的设备的解密后的版本），而不是LUKS加密的设备自身对应的分区。不过，对于未加密的`/boot`分区，仍应当直接挂载到`/mnt/boot`（假设在安装过程中，根分区被挂载到`/mnt`）。

### 配置mkinitcpio

在安装指南#关于_initramfs步骤前，需要在新安装的系统中完成如下操作：

若使用基于busybox的initramfs，在mkinitcpio.conf中添加`keyboard`和`encrypt`钩子。此外，若要使用非标准键盘布局，添加`keymap`钩子；若要自定义控制台字体，添加`consolefont`钩子。

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

若使用基于systemd的initramfs，在mkinitcpio.conf中添加`keyboard`和`sd-encrypt`钩子。此外，若要使用非标准键盘布局，或要自定义控制台字体，添加`sd-vconsole`钩子。

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

保存上述修改后，重新生成initramfs。其它可能需要用到的钩子以及配置细节参见Dm-crypt/系统配置#mkinitcpio。

### 配置引导加载程序

要在启动时解密已加密的根分区，需配置引导加载程序，设置如下内核参数：

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

若使用的是sd-encrypt，则应该添加如下内核参数：

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

`device-UUID`指的是LUKS超级块的UUID，在本例中为`/dev/sda2`对应的UUID。详见块设备持久化命名。

另见Dm-crypt/系统配置#内核参数。

提示：若根分区与boot分区在同一硬盘上，并且使用的引导加载程序支持GPT分区自动挂载，则可以修改根分区的分区类型GUID为“Root partition”并通过systemd-gpt-auto-generator(8)自动挂载，而不必设置上述内核参数。

## 使用TPM2和安全启动在单一分区上配置

本例与#在单一分区上配置LUKS相似，但通过使用安全启动和可信平台模块，使启动过程更安全。

在本配置方案中，只有EFI 系统分区是未加密的，存储经过签名以用于安全启动的统一内核映像和systemd-boot。在本配置中，若安全启动功能被关闭，或者安全启动的密钥数据库被修改，则TPM将不会释放用于解密分区的密钥。此时，仍可以使用配置过程中创建的恢复密钥解密数据。此外，还可要求在解密数据前必须输入设置的TPM PIN码。本配置方案类似Windows中的BitLocker和macOS中的FileVault。

在继续之前，确保已经详细阅读了可信平台模块#LUKS_数据加密，并着重留意其中的警告。

本例中的分区按照符合Systemd#GPT分区自动挂载的方式创建，因此无需fstab、crypttab文件。

    +-----------------------+---------------------------------+
    | EFI系统分区             | LUKS加密的根分区                  |
    |                       |                                 |
    |                       |                                 |
    | /boot                 | /                               |
    |                       |                                 |
    |                       | /dev/mapper/root                |
    |                       |---------------------------------|
    | /dev/sda1             | /dev/sda2                       |
    +-----------------------+---------------------------------+

按照安装指南#创建硬盘分区前的步骤进行基本配置。之后，按本文下一节的内容进行磁盘分区。

### 准备磁盘

在创建分区前，应先查看dm-crypt/准备磁盘，了解安全地擦除整个磁盘的重要性，并掌握相关方法。

使用GUID分区表 (GPT)，并创建需要的分区。

创建大小合适的EFI 系统分区（在本例中，使用`/dev/sda1`）。该分区将被挂载到`/boot`。

在磁盘的剩余空间上创建根分区（在本例中，使用`/dev/sda2`）。根分区将被加密，并挂载到`/`。将根分区的分区类型GUID设置为`4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709`（在fdisk中，设置为"Linux root (x86-64)"类型；在gdisk中，设置为`8304`类型）。

### 准备根分区

使用如下命令创建并挂载加密的根分区，dm-crypt/设备加密#使用 LUKS 模式加密设备中详细介绍了进行的操作。

若要使用非默认的加密选项（例如，修改加密算法，密钥长度，扇区大小），或者不想使用TPM解密，在执行如下第一条指令前参见相关加密选项。

创建并挂载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系统分区，并挂载：

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

继续执行安装指南#关于_initramfs前的步骤。注意无需执行安装指南#生成_fstab_文件步骤。

### 配置mkinitcpio

修改mkinitcpio.conf中的`HOOKS=`为如下内容，以构建可用的基于systemd的initramfs：

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

按照统一内核映像#mkinitcpio中的步骤配置统一内核映像。

由于`/boot/EFI/Linux`目录暂未由启动加载程序创建，暂时不要重新生成initramfs。

### 配置引导加载程序

可以直接通过UEFI启动内核，而无需引导加载程序。

若仍需使用引导加载程序，可以安装systemd-boot：

    # bootctl install

systemd-boot可自动识别mkinitcpio生成的统一内核映像，无需在`/boot/loader/entries/`手动添加条目。

其它配置参见systemd-boot#更新 EFI 启动管理器、Systemd-boot#配置。

### 完成安装

重新生成initramfs，并确保相关镜像成功生成。

不要忘记设置 root 密码，重启以完成安装。

### 安全启动

为了启用安全启动，需要为引导加载程序、EFI镜像签名。可使用sbctl简单、快速地实现。

### 注册TPM

在签名引导加载程序并启用安全启动后，可以向TPM注册密钥用以解锁LUKS卷。如下命令将移创建LUKS卷时设置的空密码，创建绑定到TPM PCR 7（安全启动状态和已注册证书）寄存器的密钥，并创建恢复密钥，用于在TPM出现问题时解密卷。若安全启动链完好，TPM将自动释放密钥。详见systemd-cryptenroll#Trusted Platform Module、systemd-cryptenroll(1)。

    # systemd-cryptenroll /dev/sda2 --recovery-key
    # systemd-cryptenroll /dev/sda2 --wipe-slot=empty --tpm2-device=auto --tpm2-pcrs=7

提示：若要求在启动时需要输入PIN码解密卷，可添加`--tpm2-with-pin=yes`参数。
警告：

- 在绑定密钥到PCR7寄存器时，需要确保安全启动已启用且处于用户模式。否则，未授权的启动设备也可能解锁加密卷。
- 若固件证书状态改变，则PCR7寄存器状态也可能改变，导致解锁失败。例如，使用fwupd[2]可能在不经意间改变固件证书状态；此外，轮转安全启动密钥也将改变固件证书状态。

## 在LUKS上配置LVM

在加密的单个分区上配置LVM是一种较为直接的方案。该方案将LVM设置在一个大的加密块设备中，LVM结构只在块设备解密，扫描并挂载LVM物理卷后才可见。

示例磁盘结构如下：

    +-----------------------------------------------------------------------+ +----------------+
    | 逻辑卷 1              | 逻辑卷 2              | 逻辑卷 3              | | boot分区       |
    |                       |                       |                       | |                |
    | [SWAP]                | /                     | /home                 | | /boot          |
    |                       |                       |                       | |                |
    | /dev/MyVolGroup/swap  | /dev/MyVolGroup/root  | /dev/MyVolGroup/home  | |                |
    |_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _| | (可能在其他    |
    |                                                                       | | 设备上)        |
    |                         使用LUKS加密的分区                           | |                |
    |                           /dev/sda1                                   | | /dev/sdb1      |
    +-----------------------------------------------------------------------+ +----------------+

注意：使用默认的`encrypt`钩子时，不能将逻辑卷分配到多个磁盘上。可使用sd-encrypt钩子或参见dm-crypt/特殊应用#修改encrypt钩子以用于多个分区。
提示：该配置方案有两种变形：

- dm-crypt/特殊应用#在加密系统时使用分离的LUKS头介绍了如何将LUKS头单独存放于USB设备上，实现两步验证。
- dm-crypt/Specialties#Encrypted /boot and a detached LUKS header on USB则将LUKS头、加密的boot分区、加密的密钥文件都存放在USB设备上。

### 准备磁盘

在创建分区前，应先查看dm-crypt/准备磁盘，了解安全地擦除整个磁盘的重要性，并掌握相关方法。

提示：若要在BIOS启动的设备上使用GPT磁盘，且使用GRUB引导加载程序，需创建BIOS boot partition。

创建一个大于1GiB的分区用于`/boot`。

提示：对于UEFI启动的设备，可将EFI 系统分区用于`/boot`。

创建一个分区，用于存储整个加密的LVM。

在上述创建的分区上配置LUKS作为LVM的容器（若要修改加密选项，参见dm-crypt/设备加密#LUKS 模式的加密选项）：

    # cryptsetup luksFormat /dev/sda1

打开创建的容器：

    # cryptsetup open /dev/sda1 cryptlvm

现在可通过`/dev/mapper/cryptlvm`访问解密的容器。

### 准备逻辑卷

在解密的LUKS容器上创建物理卷：

    # pvcreate /dev/mapper/cryptlvm

创建卷组（本例中使用`MyVolGroup`，也可使用其它名称），并加入先前创建的物理卷：

    # vgcreate MyVolGroup /dev/mapper/cryptlvm

在卷组中创建逻辑卷：

提示：若需要使用ext4格式的逻辑卷，应在卷组中预留至少256MiB的空闲空间，以便能正常使用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分区

引导加载程序从`/boot`目录加载内核、initramfs和自身的配置文件。可使用任何引导加载程序支持的文件系统。

为`/boot`分区创建文件系统。对于UEFI启动的系统，使用如下命令格式化新创建的EFI 系统分区：

警告：只有在EFI系统分区是在安装Arch Linux的分区步骤中创建的情况下，才应当格式化该分区。否则，若EFI系统分区是由其它系统创建的，则重新格式化将导致其它系统的引导程序丢失。

    # mkfs.fat -F32 /dev/sdb1

对于传统BIOS启动的系统：

    # mkfs.ext4 /dev/sdb1

将上述分区挂载到`/mnt/boot`：

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

继续执行安装指南#开始安装系统中的步骤。之后回到本页，执行修改后的关于 initramfs、安装引导程序步骤。

### 配置mkinitcpio

确保已安装lvm2包。

若使用基于busybox的initramfs，在mkinitcpio.conf中添加`keyboard`、`encrypt`、`lvm2`钩子。此外，若要使用非标准键盘布局，添加`keymap`钩子；若要自定义控制台字体，添加`consolefont`钩子。

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

若使用基于systemd的initramfs，在mkinitcpio.conf中添加`keyboard`、`sd-encrypt`、`lvm2`钩子。此外，若要使用非标准键盘布局，或要自定义控制台字体，添加`sd-vconsole`钩子。

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

保存上述修改后，重新生成initramfs。其它可能需要用到的钩子以及配置细节参见Dm-crypt/系统配置#mkinitcpio。

注意：若使用dracut生成mkinitcpio，则其已经包含必要的模块，无需额外配置。

### 配置引导加载程序

要在启动时解密已加密的根分区，需配置引导加载程序设置如下内核参数：

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

若使用的是sd-encrypt，则应该添加如下内核参数：

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

`device-UUID`指的是LUKS超级块的UUID，在本例中为`/dev/sda1`对应的UUID。详见块设备持久化命名。

若使用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卷，用作加密分区的基础。在本方案中，可同时创建加密及未加密的分区。

提示：与#在LUKS上配置LVM不同，可以使用常规方式将逻辑卷分配到多个磁盘上。

下例展示了在LVM上配置LUKS加密卷，并使用密钥文件解锁home分区。对于swap分区，使用临时加密卷，以确保在每次重启后，都重新配置swap分区的加密，防止敏感信息泄露，提升安全性。若熟悉LVM配置，可自行修改LVM分区方案。

若要创建横跨多个磁盘的逻辑卷，或要将已有逻辑卷扩展到其它已配置好的磁盘上，详见dm-crypt/特殊应用#将LVM拓展到多个磁盘上。注意调整逻辑卷的大小后，LUKS加密容器的大小也需要调整。

### 准备磁盘

分区方案如下：

    +----------------+-------------------------------------------------------------------------------------------------+
    | boot分区       | dm-crypt plain加密的分区        | LUKS加密的分区               | LUKS加密的分区               |
    |                |                                 |                               |                               |
    | /boot          | [SWAP]                          | /                             | /home                         |
    |                |                                 |                               |                               |
    |                | /dev/mapper/swap                | /dev/mapper/root              | /dev/mapper/home              |
    |                |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|
    |                | 逻辑卷 1                        | 逻辑卷 2                      | 逻辑卷 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

在解密后的设备上创建文件系统，并挂载到对应挂载点。例如，要创建Ext4文件系统：

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

关于加密选项的更多信息，详见dm-crypt/设备加密#LUKS 模式的加密选项。

注意`/home`的加密会在#加密/home逻辑卷步骤中进行。

提示：若要在Arch ISO中访问加密的根文件系统，可在LVM逻辑卷出现后执行上述`open`操作。

### 准备boot分区

为`/boot`分区创建文件系统。对于UEFI启动的系统，使用如下命令格式化新创建的EFI 系统分区：

警告：只有在EFI系统分区是在安装Arch Linux的分区步骤中创建的情况下，才应当格式化该分区。否则，若EFI系统分区是由其它系统创建的，则重新格式化将导致其它系统的引导程序丢失。

    # mkfs.fat -F32 /dev/sda1

对于传统BIOS启动的系统：

    # mkfs.ext4 /dev/sda1

之后，创建boot分区的挂载点并挂在分区：

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

### 配置mkinitcpio

确保已安装lvm2包。

若使用基于busybox的initramfs，在mkinitcpio.conf中添加`keyboard`、`encrypt`、`lvm2`钩子。此外，若要使用非标准键盘布局，添加`keymap`钩子；若要自定义控制台字体，添加`consolefont`钩子。

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

若使用基于systemd的initramfs，在mkinitcpio.conf中添加`keyboard`、`sd-encrypt`、`lvm2`钩子。此外，若要使用非标准键盘布局，或要自定义控制台字体，添加`sd-vconsole`钩子。

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

保存上述修改后，重新生成initramfs。其它可能需要用到的钩子以及配置细节参见Dm-crypt/系统配置#mkinitcpio。

### 配置引导加载程序

要在启动时解密已加密的根分区，需配置引导加载程序设置如下内核参数：

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

若使用的是sd-encrypt，则应该添加如下内核参数：

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

`device-UUID`指的是LUKS超级块的UUID，在本例中为`/dev/MyVolGroup/cryptroot`对应的UUID。详见块设备持久化命名。

若使用的是dracut，需要一系列更复杂的参数：

    kernel_cmdline="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/系统配置#内核参数。

### 配置fstab和crypttab

crypttab用于解密设备，fstab用于挂载文件系统。如下配置将在每次重启时用不同的密钥重新加密swap分区：

    /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

/home逻辑卷将采用上述密钥文件加密：

    # 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

在解密后的设备上创建文件系统，并挂载到对应挂载点。例如，要创建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及一块大容量机械硬盘。在本配置中，对所有磁盘采用LUKS加密（包括`/boot`）,并将两块SSD组成了RAID0阵列。系统启动时，在GRUB中输入正确的密码后，将用解密出的密钥文件解密所有分区。

本方案采用的分区配置非常简单，组成的RAID阵列挂载在`/`（没有单独的`/boot` 分区），解密后的机械硬盘挂载在`/data`。

注意对于本方案，定期的备份非常重要。若两块SSD中的任何一块损坏，整个RAID阵列中的数据都将丢失。若要求较高的容错能力，应选择其它RAID级别。

本配置中的加密方式不是可抵赖加密。

在之后的命令中，假定采用如下块设备设置：

    /dev/sda = 第一块SSD
    /dev/sdb = 第二块SSD
    /dev/sdc = 机械硬盘

    +---------------------+---------------------------+---------------------------+ +---------------------+---------------------------+---------------------------+ +---------------------------+
    | BIOS boot分区       | EFI系统分区               | LUKS加密的分区           | | BIOS 启动分区       | EFI系统分区               | LUKS加密的分区           | | LUKS加密的分区           |
    |                     |                           |                           | |                     |                           |                           | |                           |
    |                     | /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/准备磁盘，了解安全地擦除整个磁盘的重要性，并掌握相关方法。

对于使用GPT分区表的BIOS启动的系统，需创建一个大小为1MiB的BIOS启动分区，GRUB将在此存储第二阶段的BIOS引导加载程序。不要挂载该分区。

对于UEFI启动的系统，需创建大小适当的EFI 系统分区，并挂载到`/efi`。

对于设备上的剩余空间，创建一个用于"Linux RAID"的分区（本例中为`/dev/sda3`）。对于MBR分区表，选择`fd`分区类型ID；对于GPT分区表，选择`A19D880F-05FC-4D3B-A006-743F0F84911E`分区类型GUID。

一旦在`/dev/sda`上创建好了分区，可使用下列命令将它们的配置克隆到`/dev/sdb`上：

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

对于机械硬盘，创建单个占据整个磁盘的Linux分区（`/dev/sdc1`）。

### 构建RAID阵列

创建用于两块SSD的RAID阵列：

注意：

- 对于两块SSD，EFI系统分区必须能在每块SSD上单独访问，因此只能存放在RAID1上。
- 必须通过`--metadata=1.0`选项将RAID superblock放置在EFI系统分区的后部，否则固件将不能访问EFI系统分区。

    # mdadm --create --verbose --level=1 --metadata=1.0 --raid-devices=2 /dev/md/ESP /dev/sda2 /dev/sdb2

对于根分区，本例采用了RAID0。可根据实际偏好与需要选择其它RAID级别。

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

### 准备块设备

dm-crypt/准备磁盘中介绍了通过使用随机密钥创建加密卷，并向加密卷中写入`/dev/zero`产生的全零数据来随机擦除设备的方法。此外，也可使用`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

对本例中的机械硬盘（`/dev/sdc1`）也需重复上述操作。

为`/dev/md/root`设置加密：

警告：GRUB对LUKS2的支持并不完善，详见GRUB#加密的/boot。对于需要由GRUB解密的分区，建议使用PBKDF2密钥派生函数（`cryptsetup luksFormat --pbkdf pbkdf2`）。

    # cryptsetup -v luksFormat --pbkdf pbkdf2 /dev/md/root
    # cryptsetup open /dev/md/root root

在解密后的设备上创建文件系统。例如，要创建Ext4文件系统：

    # mkfs.ext4 /dev/mapper/root

将根分区挂载到`/mnt`：

    # mount /dev/mapper/root /mnt

对机械硬盘，类似的：

    # 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系统分区是在安装Arch Linux的分区步骤中创建的情况下，才应当格式化该分区。否则，若EFI系统分区是由其它系统创建的，则重新格式化将导致其它系统的引导程序丢失。

    # mkfs.fat -F32 /dev/md/ESP
    # mount --mkdir /dev/md/ESP /mnt/efi

### 配置GRUB

对于本例中通过LUKS加密的系统，编辑`/etc/default/grub`以配置GRUB：

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

对于较新的设备，可能需要使用USB键盘在GRUB中输入密码。这需要启用固件中的”legacy USB support“，或在`/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`的密码。
- 创建另一个密钥文件以便于在启动时解密机械硬盘（`/dev/sdc1`）。为了便于以后可能的需要恢复的情况，不要移动/删除上述密钥文件。接下来编辑`/etc/crypttab`以在启动时解密机械硬盘。详见Dm-crypt/系统配置#使用密钥文件解密。

### 配置系统

配置fstab以挂载根分区、data分区、EFI系统分区：

    /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。

## Plain dm-crypt

与LUKS不同，dm-crypt的plain模式无需在加密设备前附加LUKS头，本方案利用该特点在未分区的硬盘上设置加密的系统。对于他人，将无法区分用该方式加密的硬盘与与用随机数据填充的硬盘，即所谓可抵赖加密。详见wikipedia:Disk encryption#Full disk encryption。

注意，除非需要将整个硬盘全部加密，否则，无论是加密整个系统还是部分分区，使用之前小节中介绍的基于LUKS的方法都是更好的选择。因为在plain模式中，无法使用LUKS特有的功能，例如支持多个密码、密钥文件的密钥管理，主密钥备份，原位重新加密。

由于不依赖主密钥，可避免主密钥损坏或被销毁导致的单点故障，plain模式对数据损坏的承受能力更强。此外，若尤为在意对SSD的TRIM支持，也可以使用plain模式。然而，在plain模式下，要到达与LUKS模式相同的加密强度，需要手动配置加密选项。详见静态数据加密#加密的元数据。

提示：若需要使用无LUKS头的加密但仍想使用KDF的相关功能，可尝试如下两种替代方案：

- 通过cryptsetup的`--header`选项使用分离的LUKS头。注意若使用该方案则不能使用标准的"encrypt"钩子，不过可对该钩子进行修改。
- tcplay 在无LUKS头加密模式下提供了PBKDF2函数。

本方案使用了两个U盘：

- 一个用于引导设备，同时存储用于解密plain加密设备的配置选项；
- 一个用于密钥文件，将按原始比特位存储，故不了解加密方案的攻击者只能看到一串仿佛随机的数据，而非可见的普通文件。详见Wikipedia:Security through obscurity。要准备密钥文件，参见dm-crypt/Device encryption#Keyfiles。

磁盘布局如下：

    +----------------------+----------------------+----------------------+ +----------------+ +----------------+
    | 逻辑卷 1     | 逻辑卷 2     | 逻辑卷 3     | | 启动设备    | | 密钥 |
    |                      |                      |                      | |                | | 存储设备   |
    | /                    | [SWAP]               | /home                | | /boot          | | (在本例中 |
    |                      |                      |                      | |                | | 未分区)    |
    | /dev/MyVolGroup/root | /dev/MyVolGroup/swap | /dev/MyVolGroup/home | | /dev/sdb1      | | /dev/sdc       |
    |----------------------+----------------------+----------------------| |----------------| |----------------|
    | /dev/sda 使用plain模式加密并配置LVM             | | U盘 1    | | U盘 2    |
    +--------------------------------------------------------------------+ +----------------+ +----------------+

提示：

- 也可以只使用一个U盘，如下为两种方式：
  - 在U盘（/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_专用方案

### 准备分区（除boot）

详见dm-crypt/设备加密#plain模式的加密选项。

在本例中，使用`/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提倡直接在解密后的设备上创建文件系统，而不创建LVM。
- 若LVM卷组中包含ext4文件系统的逻辑卷，为了便于使用e2scrub(8)工具，至少在卷组中保留256MiB的空闲空间。若使用`-l 100%FREE`参数创建了最后一个逻辑卷，可以使用`lvreduce -L -256M MyVolGroup/home`留出256MiB的空闲空间。

接下来，在解密后产生的映射设备上设置LVM逻辑卷，详见Install Arch Linux on LVM：

    # 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

格式化并挂载上述分区并激活swap，详见文件系统#创建文件系统。

    # 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分区

可直接将单独的U盘（通常使用FAT32文件系统）作为`/boot`分区。或者，若要手动分区，使用分区工具创建大小为1GiB的小分区，并建立文件系统。

警告：只有在EFI系统分区是在安装Arch Linux的分区步骤中创建的情况下，才应当格式化该分区。否则，若EFI系统分区是由其它系统创建的，则重新格式化将导致其它系统的引导程序丢失。

    # mkfs.fat -F32 /dev/sdb1
    # mount --mkdir /dev/sdb1 /mnt/boot

### 配置mkinitcpio

确保已安装lvm2包。

若使用基于busybox的initramfs，在mkinitcpio.conf中添加`keyboard`、`encrypt`、`lvm2`钩子。此外，若要使用非标准键盘布局，添加`keymap`钩子；若要自定义控制台字体，添加`consolefont`钩子。

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

保存上述修改后，重新生成initramfs。其它可能需要用到的钩子以及配置细节参见Dm-crypt/系统配置#mkinitcpio。

### 配置引导加载程序

要从加密的根分区启动，需通过引导加载程序设置如下内核参数（注意512位对应64字节）：

    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`分区所在的U盘上。

对于BIOS启动的系统：

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

对于UEFI启动的系统：

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

### 安装完成后的操作

或许希望在系统启动后移除启动用的U盘。由于`/boot`分区并不常用，可在`/etc/fstab`的相应行中添加`noauto`选项：

    /etc/fstab

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

然而，若需要更新initramfs、内核、引导加载程序使用的相关文件时，则必须挂载`/boot`分区。由于`fstab`中存在相关条目，只需执行如下命令即可挂载：

    # mount /boot

## 加密的boot分区(GRUB)

本配置使用与#在LUKS上配置LVM相同的分区结构和配置。但使用了GRUB引导加载程序，其能从LVM逻辑卷和LUKS加密的`/boot`上启动系统。详见GRUB#加密的/boot

本例中的磁盘结构如下：

    +---------------------+----------------------+----------------------+----------------------+----------------------+
    | BIOS boot分区       | EFI系统分区          | 逻辑卷 1             | 逻辑卷 2             | 逻辑卷 3             |
    |                     |                      |                      |                      |                      |
    |                     | /efi                 | /                    | [SWAP]               | /home                |
    |                     |                      |                      |                      |                      |
    |                     |                      | /dev/MyVolGroup/root | /dev/MyVolGroup/swap | /dev/MyVolGroup/home |
    | /dev/sda1           | /dev/sda2            |----------------------+----------------------+----------------------+
    | 未加密              | 未加密               | /dev/sda3 使用LUKS加密并配置LVM                                   |
    +---------------------+----------------------+--------------------------------------------------------------------+

提示：

- 所有提供的案例仅用作示例。可按需与其它方案结合使用。此外，可参见#在LUKS上配置LVM中介绍的两种变形。
- 可以使用cryptbootAUR中的`cryptboot`脚本简化加密boot分区的管理（包括挂载、卸载、软件包更新）。此外，该脚本与UEFI安全启动配合还可抵御邪恶女佣攻击。更多信息及存在的问题见cryptboot project。

### 准备磁盘

在创建分区前，应先查看dm-crypt/准备磁盘，了解安全地擦除整个磁盘的重要性，并掌握相关方法。

对于UEFI启动的系统，创建大小合适的EFI 系统分区，将挂载该分区到`/efi`。

对于BIOS + GPT启动的系统，创建大小为1MiB的BIOS启动分区，GRUB将在该分区中存储第二阶段引导加载程序，不要手动挂载该分区。

对于BIOS + MBR启动的系统，无需创建BIOS启动分区。

创建一个类型为`8309`的分区用于加密的LVM。

创建LUKS加密容器：

警告：GRUB对LUKS2的支持并不完善，详见GRUB#加密的/boot。对于需要由GRUB解密的分区，建议使用PBKDF2密钥派生函数（`cryptsetup luksFormat --pbkdf pbkdf2`）。

     # cryptsetup luksFormat --pbkdf pbkdf2 /dev/sda3

关于加密选项的更多信息，在执行上述命令前参见dm-crypt/设备加密#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

打开LUKS加密容器：

    # cryptsetup open /dev/sda3 cryptlvm

解密后的容器将在`/dev/mapper/cryptlvm`。

### 准备逻辑卷

本例中逻辑卷的结构与#在LUKS上配置LVM中的相同。因此，只需遵循#准备逻辑卷中的步骤并按需调整。

对于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包。

若使用基于busybox的initramfs，在mkinitcpio.conf中添加`keyboard`、`encrypt`、`lvm2`钩子。此外，若要使用非标准键盘布局，添加`keymap`钩子；若要自定义控制台字体，添加`consolefont`钩子。

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

若使用基于systemd的initramfs，在mkinitcpio.conf中添加`keyboard`、`sd-encrypt`、`lvm2`钩子。此外，若要使用非标准键盘布局，或要自定义控制台字体，添加`sd-vconsole`钩子。

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

保存上述修改后，重新生成initramfs。其它可能需要用到的钩子以及配置细节参见Dm-crypt/系统配置#mkinitcpio。

### 配置GRUB

配置GRUB以从LUKS加密的`/boot`启动：

    /etc/default/grub

    GRUB_ENABLE_CRYPTODISK=y

设置内核参数以便initramfs解密加密的根分区。 若使用`encrypt`钩子：

    /etc/default/grub

    GRUB_CMDLINE_LINUX="... cryptdevice=UUID=device-UUID:cryptlvm ..."

若使用sd-encrypt钩子：

    /etc/default/grub

    GRUB_CMDLINE_LINUX="... rd.luks.name=device-UUID=cryptlvm ..."

详见Dm-crypt/系统配置#内核参数、GRUB#加密的/boot。`device-UUID`应为LUKS superblock的UUID（在本例中为`/dev/sda3`，该分区包含了含有根分区的LVM）。详见块设备持久化命名。

对于UEFI启动的系统，安装GRUB到挂载的EFI系统分区：

    # 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`。

### 避免需输入两次密码

尽管在上述操作后，GRUB会要求输入密码解密LUKS加密的分区，但密码并不会传递到initramfs中。因此，需要在启动时输入两次密码：一次用于GRUB，一次用于initramfs。

可通过在initramfs中嵌入密钥文件避免输入两次密码。

首先，创建一个密钥文件，将其添加到LUKS key中：

    # 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镜像。

设置如下内核参数以通过密钥文件解密LUKS分区。 若使用`encrypt`钩子：

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

若使用sd-encrypt钩子，将默认使用`/etc/cryptsetup-keys.d/name.key`密钥文件，因此无需手动设置内核参数。

若由于某些原因密钥文件解密boot分区失败，systemd会要求手动输入密码。输入正确的密码后，系统启动将正常进行。

提示：若想加密`/boot`分区以抵御离线攻击`/boot`分区的威胁，可使用dm-crypt/特殊应用#mkinitcpio-chkcryptoboot钩子。

### 使用USB设备解锁 /boot

使用存储在单独USB设备上的密钥文件可避免使用密码（若密码太复杂，则难以记忆；若太简单，则容易被猜中）。从安全性角度考虑，在未使用时，存储有密钥文件的USB设备必须与需解密的设备分开保存。

首先，按照#避免需输入两次密码中的步骤创建新的密钥文件。不要复用initramfs中使用的密钥文件，否则，若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

## Root on ZFS

要将dm-crypt与ZFS一同使用，参见ZFS#Encryption in ZFS using dm-crypt。

此外，ZFS具有原生加密支持，可用于加密根分区（不包含引导加载程序和文件系统元数据）。详见：

- OpenZFS上的Arch Linux Root on ZFS指南。
- Install Arch Linux on ZFS#Installation.

对于UEFI启动的系统，在安装后可通过安全启动验证引导加载程序。

分类：​

- 静态数据加密
- 安装过程

dm-crypt/加密整个系统
添加话题