dm-crypt/加密整个系统

来自 Arch Linux 中文维基

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

若要加密现存的未加密的文件系统,见 dm-crypt/设备加密#加密现有的未加密文件系统

概览[编辑 | 编辑源代码]

为根文件系统提供安全保护是“dm-crypt”的特色功能,且相比其它方案“dm-crypt”的性能更加优秀。与仅仅加密部分非根文件系统不同,加密根文件系统可以隐藏如已安装的程序列表、用户名等信息,并能避免通过mlocate/var/log/等常见方式泄露数据。此外,由于除了引导加载程序和内核(通常情况下),所有数据都被加密,对系统进行未授权的改动将更加困难。

下面所述的所有方案都有上述优点。此外,各种方案的优缺点总结如下:

方案 优点 缺点
#在单一分区上配置LUKS 展示了设置使用LUKS完全加密的根文件系统的基本方式,最直接。
  • 不灵活;用于加密的整个磁盘空间需要预先分配。
#在LUKS上配置LVM

通过在LUKS加密的单一分区上配置LVM来达到分区灵活性。

  • 通过LVM可简单地在加密设备上配置多个分区。
  • 只需一个密码即可解密所有分区。
  • 在未解密时系统的分区结构不可见。
  • 若要使用休眠到硬盘功能,这是最简单的方式。
  • LVM增加了系统设备mapping结构的复杂性,且需要单独添加钩子。
  • 难以对某个分区单独指定密码。
#在LVM上配置LUKS

只在LVM上层使用LUKS。

  • 可通过LVM将加密分区拓展到多个磁盘上。
  • 可方便地同时配置加密与未加密分区。
  • 复杂;若更改了LVM逻辑卷的结构,可能需要同时更改encryption mappers。
  • 每个分区需要单独配置密码。
  • 即使未加密时,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)
  • 配置更复杂。
  • 其它引导加载程序不支持此方案。
#Root on ZFS

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

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

此外,还需考虑是否设置加密的swap分区及设置方式。详见dm-crypt/Swap encryption

加密整个系统可在设备失窃时保护数据,若还要针对logical tampering提供额外的保护,在完成选择的方案后,还应参见dm-crypt/Specialties#Securing the unencrypted boot partition

若使用固态硬盘,或许需要启用TRIM支持。然而,这可能影响安全性,详见dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD)

警告:
  • 无论选择何种方案,绝对不能直接在未解密的分区上运行文件系统修复软件(如fsck),否则解密数据所用的密钥将永久丢失!相关软件只能用于解密后的分区。
  • 对于LUKS2格式:
    • GRUB对LUKS2的支持并不完善,详见GRUB#加密的/boot。对于需要由GRUB解密的分区,建议使用LUKS1(cryptsetup luksFormat --type luks1)。
    • LUKS2采用了占用内存较多的设计方式,默认情况下每个encrypted mapper将占用1GB内存。若设备的内存容量较少或要同时解密较多的LUKS2分区,可能导致系统启动失败。可通过--pbkdf-memory选择控制内存用量,详见[1]

在单一分区上配置LUKS[编辑 | 编辑源代码]

本例说明了通过“dm-crypt”与LUKS在单一分区上进行配置以加密整个系统。

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

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

准备磁盘[编辑 | 编辑源代码]

在创建任何分区前,应先查看dm-crypt/准备磁盘,明确安全地擦除整个磁盘的重要性及相关方法。

接下来创建本例中的相关分区(至少需要//dev/sda2)和/boot/dev/sda1),详见分区

准备非boot分区[编辑 | 编辑源代码]

下列命令创建并挂载加密的根分区。dm-crypt/加密非root文件系统#分区中对相关命令有详细解释(只要正确配置了mkinitcpio引导加载程序,其中的内容同样适用于根分区。)

若要使用自定义的加密选项(如cipher、key length),在执行第一条命令前参看 加密选项。若要改变默认扇区大小,参见dm-crypt/设备加密#扇区大小

# cryptsetup -y -v luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root
# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

确保设备mapper已正确设置:

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

若为不同目录(如/home)创建了单独的分区,则需要对除了boot分区的所有要加密的分区重复上述步骤。为了在启动时挂载上述分区,见dm-crypt/加密非root文件系统#自动解锁并挂载

注意对于每个加密分区都需要单独设置密码,并且导致启动时需要依次输入每个分区密码的不便。可通过在根分区存储一个keyfile并配置crypttab来自动解密其它分区,详见dm-crypt/设备加密#使用LUKS来格式化带有密钥文件的分区

准备boot分区[编辑 | 编辑源代码]

对于加密根分区的方案,需创建一个未加密的boot分区。对于传统BIOS启动的系统上,执行:

# mkfs.ext4 /dev/sda1

或者,在UEFI启动的系统上可将EFI 系统分区用作/boot

# mkfs.fat -F32 /dev/sda1

之后创建挂载用的目录并挂载boot分区:

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

挂载分区[编辑 | 编辑源代码]

在执行安装指南#挂载分区中的步骤时,注意需要挂载解密后创建的设备mapper而非硬盘上的实际分区。当然,未加密的boot分区需要直接挂载。

配置mkinitcpio[编辑 | 编辑源代码]

mkinitcpio.conf中添加keyboardencrypt钩子。若要使用非标准的键盘布局,还需添加keymap钩子;若要修改控制台字体,还需添加consolefont钩子:

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

若使用基于sysyemd的initramfs,需添加的应为keyboardsd-encrypt钩子。若要使用非标准键盘布局或修改控制台字体,还需添加sd-vconsole钩子:

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

在保存上述修改后,重新生成initramfs。对于可能需要的其它钩子,详见dm-crypt/System configuration#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。详见块设备持久化命名

另见dm-crypt/System configuration#Kernel parameters

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

在LUKS上配置LVM[编辑 | 编辑源代码]

在加密的单个分区上配置LVM是一种较为直接的方案。该方案将LVM设置在一个大的加密的块设备中。因此,在该块设备解密、卷结构被扫描、分区在启动时被挂载前,整个LVM都是不可见的。

以下为示例磁盘结构:

+-----------------------------------------------------------------------+ +----------------+
| 逻辑卷 1              | 逻辑卷 2              | 逻辑卷 3              | | boot分区       |
|                       |                       |                       | |                |
| [SWAP]                | /                     | /home                 | | /boot          |
|                       |                       |                       | |                |
| /dev/MyVolGroup/swap  | /dev/MyVolGroup/root  | /dev/MyVolGroup/home  | |                |
|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _| | (可能在其他    |
|                                                                       | | 设备上)        |
|                         使用LUKS2加密的分区                           | |                |
|                           /dev/sda1                                   | | /dev/sdb1      |
+-----------------------------------------------------------------------+ +----------------+
注意: 若使用默认的encrypt钩子,则不能将逻辑卷分配到多个磁盘上。可使用sd-encrypt钩子或参见dm-crypt/Specialties#Modifying the encrypt hook for multiple partitions
提示:该配置方案有两个变体:

准备磁盘[编辑 | 编辑源代码]

在创建任何分区前,应先查看dm-crypt/Drive preparation,明确安全地擦除整个磁盘的重要性及相关方法。

提示:若要在BIOS启动的设备上使用GPT磁盘,并使用GRUB引导加载程序,则需创建BIOS boot partition

创建一个大于200MiB的分区用于/boot

提示:对于UEFI启动的设备,可将EFI 系统分区用于/boot

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

在上述创建的分区上配置LUKS作为LVM的容器:

# 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格式,应在卷组中预留至少256MiB的空闲空间以便能正常使用e2scrub(8)。要达到这一点,在使用-l 100%FREE创建占满所有剩余空间最后一个逻辑卷后,使用类似lvreduce -L -256M MyVolGroup/home的命令减少该逻辑卷的大小。}

# lvcreate -L 8G MyVolGroup -n swap
# lvcreate -L 32G MyVolGroup -n root
# lvcreate -l 100%FREE MyVolGroup -n home

格式化逻辑卷:

# 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的分区上创建文件系统

# mkfs.ext4 /dev/sdb1
提示:若要将EFI 系统分区用于/boot},则推荐使用Fat32格式:
# mkfs.fat -F32 /dev/sdb1

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

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

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

配置mkinitcpio[编辑 | 编辑源代码]

确保安装了lvm2,之后在mkinitcpio.conf中添加keyboardencryptlvm2钩子。若要使用非标准的键盘布局,还需添加keymap钩子;若要修改控制台字体,还需添加consolefont钩子:

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

若使用基于sysyemd的initramfs,需添加的应为keyboardlvm2sd-encrypt钩子。若要使用非标准键盘布局或修改控制台字体,还需添加sd-vconsole钩子:

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

在保存上述修改后,重新生成initramfs。对于可能需要的其它钩子,详见dm-crypt/System configuration#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。详见块设备持久化命名

若使用的是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/System configuration#Kernel parameters

在LVM上配置LUKS[编辑 | 编辑源代码]

为了在LVM上层设置加密,首先要设置LVM卷,将它们用作加密分区的基础。在这种配置方案下,可同时创建加密及未加密的分区。

提示:#在LUKS上配置LVM不同,本方案允许以普通的方式将逻辑卷分配到多个磁盘上。

下例展示了在LVM上配置LUKS的方法,并且对不同逻辑卷采用了不同的加密方式:/home卷采用keyfile,/tmp/swap则采用临时随机密钥。采用临时随机密钥是基于安全性考虑,每次重启后加密都将重新配置,使得临时数据不会在重启后保留。若你熟悉LVM,可根据自己的方案修改下述案例。

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

准备磁盘[编辑 | 编辑源代码]

分区方案如下:

+----------------+-------------------------------------------------------------------------------------------------+
| boot分区       | dm-crypt plain加密的分区        | LUKS2加密的分区               | LUKS2加密的分区               |
|                |                                 |                               |                               |
| /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/Drive preparation#dm-crypt wipe on an empty disk or partition]]随机擦除/dev/sda2

准备逻辑卷[编辑 | 编辑源代码]

# pvcreate /dev/sda2
# vgcreate MyVolGroup /dev/sda2
# lvcreate -L 32G -n cryptroot MyVolGroup
# lvcreate -L 500M -n cryptswap MyVolGroup
# lvcreate -L 500M -n crypttmp MyVolGroup
# lvcreate -l 100%FREE -n crypthome MyVolGroup
# cryptsetup luksFormat /dev/MyVolGroup/cryptroot
# cryptsetup open /dev/MyVolGroup/cryptroot root
# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

关于加密选项的更多信息,详见dm-crypt/Device encryption#Encryption options for LUKS mode

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

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

准备boot分区[编辑 | 编辑源代码]

# dd if=/dev/zero of=/dev/sda1 bs=1M status=progress
# mkfs.ext4 /dev/sda1
# mount --mkdir /dev/sda1 /mnt/boot

配置mkinitcpio[编辑 | 编辑源代码]

确保安装了lvm2,之后在mkinitcpio.conf中添加keyboardencryptlvm2钩子。若要使用非标准的键盘布局,还需添加keymap钩子;若要修改控制台字体,还需添加consolefont钩子:

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

若使用基于sysyemd的initramfs,需添加的应为keyboardsd-encrypt钩子。若要使用非标准键盘布局或修改控制台字体,还需添加sd-vconsole钩子:

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

在保存上述修改后,重新生成initramfs。对于可能需要的其它钩子,详见dm-crypt/System configuration#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。详见块设备持久化命名

若使用的是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/System configuration#Kernel parameters

配置fstab和crypttab[编辑 | 编辑源代码]

解密设备和挂载其上的文件系统分别需要编辑crypttabfstab。下列配置将在每次重启时重新加密临时文件系统:

/etc/crypttab
swap	/dev/MyVolGroup/cryptswap	/dev/urandom	swap,cipher=aes-xts-plain64,size=256
tmp	/dev/MyVolGroup/crypttmp	/dev/urandom	tmp,cipher=aes-xts-plain64,size=256
/etc/fstab
/dev/mapper/root        /       ext4            defaults        0       1
/dev/sda1               /boot   ext4            defaults        0       2
/dev/mapper/tmp         /tmp    tmpfs           defaults        0       0
/dev/mapper/swap        none    swap            sw              0       0

加密/home逻辑卷[编辑 | 编辑源代码]

由于本方案使用LVM作为第一层,em-crypt作为第二层,每个加密的逻辑卷都需要单独设置加密。此外,和临时文件系统采用的临时随机密钥加密不同,/home对应的逻辑卷显然应该采用持久不变的密钥。下列命令假定你已经重启进入了安装好的系统。若没有,需要调整相应路径。

为了在系统启动时无需输入两次密码,创建了keyfile

# mkdir -m 700 /etc/luks-keys
# dd if=/dev/random of=/etc/luks-keys/home bs=1 count=256 status=progress

该逻辑卷将采用上述keyfile加密:

# cryptsetup luksFormat -v /dev/MyVolGroup/crypthome /etc/luks-keys/home
# cryptsetup -d /etc/luks-keys/home open /dev/MyVolGroup/crypthome home
# mkfs.ext4 /dev/mapper/home
# mount /dev/mapper/home /home

解密并挂载该文件系统需要配置crypttabfstab

/etc/crypttab
home	/dev/MyVolGroup/crypthome   /etc/luks-keys/home
/etc/fstab
/dev/mapper/home        /home   ext4        defaults        0       2

在软RAID上配置LUKS[编辑 | 编辑源代码]

下例基于真实的工作站笔记本设置,该工作站有两块大小相同的SSD及一块大容量机械硬盘。该配置对所有磁盘采用LUKS1加密(包括/boot),并将两块SSD组成了RAID0阵列。系统启动时,在GRUB中输入正确的密码后,将用解密出的keyfile解密所有分区。

该方案采用的分区配置非常简单,组成的RAID阵列挂载在/(没有单独的/boot 分区),解密后的机械硬盘挂载在/data

注意对于该方案,定期的备份非常重要。若两块SSD中的任何一块损坏,整个RAID阵列中的数据将在实践上不可能被恢复。若对硬件错误的容忍能力对你来说非常重要,应选择其它的RAID级别

The encryption is not deniable in this setup.

在之后的命令中,采用了如下块设备设置:

/dev/sda = 第一块SSD
/dev/sdb = 第二块SSD
/dev/sdc = 机械硬盘
+---------------------+---------------------------+---------------------------+ +---------------------+---------------------------+---------------------------+ +---------------------------+
| BIOS boot分区       | EFI系统分区               | LUKS1加密的分区           | | BIOS 启动分区       | EFI系统分区               | LUKS1加密的分区           | | LUKS2加密的分区           |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     | /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启动的系统,需创建一个大小为1MiB的BIOS启动分区,GRUB将在此存储第二阶段的BIOS引导加载程序。不要挂载创建的该分区。


对于UEFI启动的系统,需创建大小适当的EFI 系统分区,之后该分区将被挂载到/efi

对于设备上的剩余空间,创建一个用于"Linux RAID"的分区(本例中为/dev/sda3)。对于MBR分区表,选择fd分区type ID;对于GPT分区表,选择A19D880F-05FC-4D3B-A006-743F0F84911E分区type 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上单独访问,因此ESP只能被存放在RAID1上。
  • RAID superblock必须通过--metadata=1.0选项放置在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/Drive preparation中介绍了如何使用/dev/zero与随机密钥加密来用随机数据擦除设备。此外,也可使用dd/dev/random/dev/urandom,不过比前者慢得多。

# cryptsetup open --type plain /dev/md/root container --key-file /dev/random
# dd if=/dev/zero of=/dev/mapper/container bs=1M status=progress
# cryptsetup close container

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

/dev/md/root设置加密:

警告: GRUB对LUKS2的支持并不完善,详见[GRUB#加密的/boot]]。对于需要由GRUB解密的分区,建议使用LUKS1(cryptsetup luksFormat --type luks1)。
# cryptsetup -y -v luksFormat --type luks1 /dev/md/root
# cryptsetup open /dev/md/root root
# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

对机械硬盘,相似的:

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

对于UEFI启动的系统,需设置EFI系统分区:

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

配置GRUB[编辑 | 编辑源代码]

对于本例中通过LUKS1加密的系统,编辑/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/System configuration#Kernel parametersGRUB#Encrypted /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

配置keyfile[编辑 | 编辑源代码]

下面进行的步骤可避免在启动时需输入两次密码的情况(第一次发生在GRUB解密LUKS1设备,第二次发生在initramfs接管系统时)。首先要创建一个keyfile,然后将该keyfile加入到initramfs镜像中以便encrypt钩子解密根分区。详见dm-crypt/Device encryption#With a keyfile embedded in the initramfs

  • 创建keyfile并向其中添加/dev/md/root的密码。
  • 创建另一个keyfile以便于在启动时解密机械硬盘(/dev/sdc1)。为了便于以后可能的需要恢复的情况,不要移动/删除上述keyfile。接下来编辑/etc/crypttab以在启动时解密机械硬盘。详见dm-crypt/System configuration#Unlocking with a keyfile

配置系统[编辑 | 编辑源代码]

配置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以包含keyfile,并添加所需的钩子:

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

详见dm-crypt/System configuration#mkinitcpio

Plain dm-crypt[编辑 | 编辑源代码]

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

注意若不需要全盘(可抵赖)加密,无论对于加密整个系统还是加密某个分区,之前介绍的使用LUKS的方法都更好。在plain 模式下将无法使用多密码/keyfile的密钥管理、就地重新加密一个设备等LUKS的特色功能。

因为无需依赖单个加密的master-key,可避免因master-key损坏造成单点故障,plain dm-crypt加密对数据错误的容忍性较LUKS强。然而,使用plain模式也需要更多的手动配置以达到与LUKS相同的加密强度(详见Data-at-rest encryption#Cryptographic metadata)。此外,若担心dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD)中提到的问题,也可使用plain模式。

提示:若需要使用headerless加密但仍想使用KDF的相关功能,可尝试如下两种替代方案:
  • 通过cryptsetup--header选项使用分离的LUKS头。注意若使用该方案则不能使用标准的"encrypt"钩子,不过可对该钩子进行修改。
  • tcplay 在headerless加密模式下提供了PBKDF2函数。

本方案使用了两个U盘:

  • 一个用于引导设备,同时存储用于解密plain加密设备的配置选项;
  • 一个用于keyfile,将存储为raw bits,故对于不不知道配置方案的攻击者而言,只能看到一串仿佛随机的数据而非可见的普通文件。详见Wikipedia:Security through obscurity。要准备keyfile,见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盘:
    • 可以将keyfile放到U盘(/dev/sdb)的另一个分区(/dev/sdb2)上。
    • 或直接将keyfile复制到initramfs上例如,对于keyfile /etc/keyfile,可在/etc/mkinitcpio.conf中设置FILES=(/etc/keyfile)。要使encrypt钩子读取initramfs镜像中的keyfile,在文件名前指定rootfs:前缀,如cryptkey=rootfs:/etc/keyfile
  • 另一种配置方法是结合密码与良好的熵源

准备磁盘[编辑 | 编辑源代码]

向解密后的映射(mapped)设备中填充随机数据是非常重要的。尤其是在本例中。


详见dm-crypt/准备磁盘、[dm-crypt/准备磁盘#dm-crypt 专用方案]]

准备分区(除boot)[编辑 | 编辑源代码]

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

在本例中,使用/dev/sda,并使用aes-xts cipher,512位的key size,使用keyfile加密:

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

与使用LUKS不同,每次要解密设备时必须使用上述“完整”的命令,故一定要牢记cipher、key file相关信息。

检查有关/dev/mapper/cryptlvm的映射条目已建立:

# fdisk -l
提示:与使用LVM相比,一个简单的方法是直接在解密的设备上创建单独一个文件系统。这也是cryptsetup FAQ中对于无需使用LVM时推荐的方法。

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

# pvcreate /dev/mapper/cryptlvm
# vgcreate MyVolGroup /dev/mapper/cryptlvm
# lvcreate -L 32G MyVolGroup -n root
# lvcreate -L 10G 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盘默认的vfat分区用作/boot分区。但若要手动分区,仅需配置一个200MiB的分区用于/boot。通过分区工具进行分区。

/boot创建文件系统

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

配置mkinitcpio[编辑 | 编辑源代码]

确保安装了lvm2,之后在mkinitcpio.conf中添加keyboardencryptlvm2钩子。若要使用非标准的键盘布局,还需添加keymap钩子;若要修改控制台字体,还需添加consolefont钩子:

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

在保存上述修改后,重新生成initramfs。对于可能需要的其它钩子,详见dm-crypt/System configuration#mkinitcpio

配置引导加载程序[编辑 | 编辑源代码]

要在加密的根分区上启动,需通过引导加载程序设置如下内核参数(注意512位对应64字节):

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

disk-ID-of-disk表示相应磁盘的id,详见[[ 块设备持久化命名]]。

对于其它可能需要的内核参数,详见dm-crypt/System configuration#Kernel parameters

提示:若使用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
/dev/sdb1 /boot vfat noauto,rw,noatime 0 2

然而,若需要更新initramfs、内核、引导加载程序使用的相关文件时,必须挂载/boot分区。由于fstab中存在相关条目,只需:

# mount /boot

加密的boot分区(GRUB)[编辑 | 编辑源代码]

本配置使用与#在LUKS上配置LVM相同的分区结构和配置,除了使用了GRUB引导加载程序,其能够从LVM逻辑卷和LUKS1加密的/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 使用LUKS1加密并配置LVM                                   |
+---------------------+----------------------+--------------------------------------------------------------------+
提示:
  • 所有案例仅用作示例。当然也可以与其它案例结合使用。此外,可参见#在LUKS上配置LVM中介绍的两种变体。
  • 可以使用cryptbootAUR中的cryptboot脚本简化加密boot分区的管理(包括挂载、卸载、软件包更新)。此外,该脚本与UEFI安全启动配合还可抵御Evil Maid攻击。更多信息及缺陷见cryptboot project

准备磁盘[编辑 | 编辑源代码]

在创建任何分区前,应先查看dm-crypt/Drive preparation,明确安全地擦除整个磁盘的重要性及相关方法。

对于BIOS启动,GUID分区表的系统,需创建大小1MiB的BIOS启动,GUID分区表的系统|BIOS boot分区用于GRUB存储第二阶段引导加载程序。不要挂载该分区。BIOS启动,MBR分区表的系统无须上述操作。

对于UEFI启动的系统,创建大小合适的[EFI 系统分区]],其会被挂载到/efi

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

创建LUKS加密容器:

警告: GRUB对LUKS2的支持并不完善,详见[GRUB#加密的/boot]]。对于需要由GRUB解密的分区,建议使用LUKS1(cryptsetup luksFormat --type luks1)。
# cryptsetup luksFormat --type luks1 /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         1130495   550.0 MiB   EF00  EFI System
   3         1130496        68239360   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     8G  0 lvm   [SWAP]
    ├─MyVolGroup-root 254:2    0    32G  0 lvm   /mnt
    └─MyVolGroup-home 254:3    0    60G  0 lvm   /mnt/home

配置mkinitcpio[编辑 | 编辑源代码]

确保安装了lvm2,之后在mkinitcpio.conf中添加keyboardencryptlvm2钩子。若要使用非标准的键盘布局,还需添加keymap钩子;若要修改控制台字体,还需添加consolefont钩子:

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

若使用基于sysyemd的initramfs,需添加的应为keyboardsd-encrypt钩子。若要使用非标准键盘布局或修改控制台字体,还需添加sd-vconsole钩子:

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

在保存上述修改后,重新生成initramfs。对于可能需要的其它钩子,详见dm-crypt/System configuration#mkinitcpio

配置GRUB[编辑 | 编辑源代码]

配置GRUB以从LUKS1加密的/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/System configuration#Kernel parametersGRUB#加密的/bootdevice-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会要求输入密码解密LUKS1加密的分区,该信息并未传递到initramfs。因此,需要在启动时输入两次密码:一次用于GRUB,一次用于initramfs。

本节介绍了配置启动过程仅需输入一次密码(在GRUB中)的额外操作。可通过在initramfs中嵌入密钥文件达成。

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

# dd bs=512 count=4 if=/dev/random of=/root/cryptlvm.keyfile iflag=fullblock
# chmod 000 /root/cryptlvm.keyfile
# cryptsetup -v luksAddKey /dev/sda3 /root/cryptlvm.keyfile

将keyfile添加到initramfs镜像:

/etc/mkinitcpio.conf
FILES=(/root/cryptlvm.keyfile)

重新生成initramfs镜像。 之后,对keyfile进行安全保护:

# chmod 600 /boot/initramfs-linux*

设置如下内核参数以通过keyfile解密LUKS分区。 若使用encrypt钩子:

GRUB_CMDLINE_LINUX="... cryptkey=rootfs:/root/cryptlvm.keyfile"

若使用sd-encrypt钩子:

GRUB_CMDLINE_LINUX="... rd.luks.key=device-UUID=/root/cryptlvm.keyfile"

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

提示:若想加密/boot分区以抵御离线攻击/boot分区的威胁,可使用mkinitcpio-chkcryptoboot钩子。

Btrfs子卷,带swap[编辑 | 编辑源代码]

译注:原文采用的部分方法已过时,从内核版本5.0开始,btrfs已支持swapfile。

本例通过在LUKS1上使用Btrfs来加密整个系统,并使用Btrfs子卷来模拟分区

对于UEFI启动的设备,需要EFI 系统分区(ESP),不能加密该分区。/boot则可以与/为同一个子卷并配置加密。在本例中,/dev/sda1作为ESP并被挂载到/efi/boot/在同一个分区(/dev/sda2)上。

由于/boot位于LUKS1加密的/上,引导加载程序必须使用GRUB,因为只有GRUB可加载相应的模块(如crypto.mod,cryptodisk.mod和luks.mod)以解密/boot

此外, 本例还展示了一个可选的,以plain模式加密的swap分区:

+----------------------+----------------------+----------------------+
| EFI系统分区          | 根分区               | Swap分区             |
| 未加密               | LUKS1模式加密        | plain模式加密        |
|                      |                      |                      |
| /efi                 | /                    | [SWAP]               |
| /dev/sda1            | /dev/sda2            | /dev/sda3            |
+----------------------+----------------------+----------------------+

准备磁盘[编辑 | 编辑源代码]

注意: 在使用LUKS时,不能使用Btrfs#无分区 Btrfs 磁盘中介绍的方法。即使只打算创建一个分区,也要使用传统的分区方式。

在创建任何分区前,应先查看dm-crypt/Drive preparation,明确安全地擦除整个磁盘的重要性及相关方法。若使用UEFI,需创建大小合适的EFI 系统分区。若要创建加密的swap分区,可以先建立分区结构,但因为将使用plain模式加密该分区,不要将其直接标记为swap分区。

创建需要的分区,至少要创建根分区(本例中为/dev/sda2)。详见分区

准备根分区[编辑 | 编辑源代码]

创建LUKS容器[编辑 | 编辑源代码]

警告: GRUB对LUKS2的支持并不完善,详见[GRUB#加密的/boot]]。对于需要由GRUB解密的分区,建议使用LUKS1(cryptsetup luksFormat --type luks1)。

按照dm-crypt/设备加密#使用 LUKS 模式加密设备中的步骤对/dev/sda2设置LUKS。在设置之前,可以在dm-crypt/设备加密#LUKS 模式的加密选项查看可用的加密选择。

解锁LUKS容器[编辑 | 编辑源代码]

按照dm-crypt/设备加密#使用设备映射器解锁/映射 LUKS分区中的步骤解密并映射LUKS容器。

格式化映射后的设备[编辑 | 编辑源代码]

按照Btrfs#单一设备上的文件系统中的步骤格式化映射后的设备。在格式化时,注意/dev/分区名应为映射后的设备(在本例中,即/dev/mapper/root),而非/dev/sda2

挂载映射后的设备[编辑 | 编辑源代码]

最后,挂载已格式化的映射后的设备(在本例中,即/dev/mapper/root)到/mnt

创建btrfs子卷[编辑 | 编辑源代码]

布局[编辑 | 编辑源代码]

子卷将用于模拟分区,但除此之外还将创建嵌套子卷。如下是本例配置的部分展示:

subvolid=5
  |
  ├── @ -|
  |     包含如下目录:
  |       ├── /usr
  |       ├── /bin
  |       ├── /.snapshots
  |       ├── ...
  |
  ├── @home
  ├── @snapshots
  ├── @var_log
  └── @...

本例遵循了Snapper#Suggested filesystem layout的配置,有助于与Snapper配合使用。有关子卷布局,还可参考Btrfs Wiki SysadminGuide#Layout

为第一次挂载准备子卷[编辑 | 编辑源代码]

依据惯例,对于用作挂载点的子卷,本例在子卷名称前加上@@对应于挂载到/的子卷。

按照Btrfs#创建子卷,在/mnt/@/mnt/@snapshots/mnt/@home创建子卷。

此外,根据你的配置,现在还应创建用作挂载点的其它子卷。

创建例外子卷[编辑 | 编辑源代码]

对于在为/制作快照时欲排除的目录,可创建相应子卷。例如,可能需要排除/var/cache/pacman/pkg目录。这些子卷会嵌套在@子卷下,但根据不同的设置,也可能已在上一步创建,并与@同级。

常见的需创建例外子卷的有:/var/abs/var/tmp/srv

挂载顶层子卷[编辑 | 编辑源代码]

卸载已挂载到{{ic|/mnt}的根文件系统。

之后,通过subvol=挂载选项将创建的用于/@子卷挂载到/mnt。假设解密产生的映射设备为root,执行的命令与与如下的相似:

# mount -o compress=zstd,subvol=@ /dev/mapper/root /mnt

详见Btrfs#挂载子卷

此外,将其它子卷挂载到相应的位置:@home挂载到/mnt/home@snapshots挂载到/mnt/.snapshots

挂载ESP[编辑 | 编辑源代码]

若之前准备了EFI系统分区,创建相应挂载点并挂载。

注意: 由于/efi不是btrfs文件系统的一部分,btrfs快照将忽略它。

在执行pacstrap安装步骤时,除base元软件包外,还必须安装btrfs-progs

配置mkinitcpio[编辑 | 编辑源代码]

创建keyfile[编辑 | 编辑源代码]

为了允许GRUB解密LUKS分区,同时无需输入两次密码,本例将keyfile嵌入initramfs中。执行dm-crypt/设备加密#在 initramfs 中嵌入密钥文件中的步骤。在luksAddKey步骤时,确保目标为/dev/sda2

编辑mkinitcpio.conf[编辑 | 编辑源代码]

按上述步骤创建、添加并嵌入keyfile后,将encrypt连同其它需要的钩子一同加入mkinitcpio.conf

在保存上述修改后,重新生成initramfs。对于可能需要的其它钩子,详见dm-crypt/System configuration#mkinitcpio

提示:可能还需向/etc/mkinitcpio.conf中加入BINARIES=(btrfs)。详见Btrfs#损坏恢复

配置引导加载程序[编辑 | 编辑源代码]

安装GRUB,并按GRUB#额外的参数GRUB#加密的/bootdm-crypt/System configuration#Using encrypt hook中的步骤编辑/etc/default/grub,注意要遵循有关加密的根分区、加密的boot分区两方面的内容。最后,生成GRUB配置文件。注意还需按照Btrfs#挂载子卷为根挂载点中的要求设定内核参数。

配置swap[编辑 | 编辑源代码]

若创建了用于加密的swap的分区,按照dm-crypt/Swap encryption中的步骤进行配置。

Root on ZFS[编辑 | 编辑源代码]

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

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

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

使用TPM2和安全启动的简单根分区加密[编辑 | 编辑源代码]

本例介绍了通过dm-crypt + LUKS以及TPM2、安全启动配置的全系统加密。

仅有包含Unified kernel imagesystemd-boot的ESP是未加密的。可将Unified kernel imagesystemd-boot签名并与安全启动一同使用,TPM会检测安全启动状态,所以若安全启动被关闭或其密钥数据库被修改,加密的分区将不会被自动解密。这提供了合理的安全启动链(与Windows的BitLocker,macOS的FileVault相似)。

本例中,分区按照systemd#GPT分区自动挂载的要求创建,故无需配置fstab或crypttab。

+-----------------------+------------------------+-----------------------+
| ESP                   | 根分区                                         |
| 未加密                | 加密                                           |
|                       |                                                |
| /efi                  | /                                              |
|                       |                                                |
|                       | /dev/mapper/root                               |
|                       |------------------------------------------------|
| /dev/sda1             | /dev/sda2                                      |
+-----------------------+------------------------+-----------------------+

遵循安装指南中的步骤直到创建硬盘分区

对硬盘分区[编辑 | 编辑源代码]

在创建任何分区前,应先查看dm-crypt/Drive preparation,明确安全地擦除整个磁盘的重要性及相关方法。

此外,确保硬盘报告的扇区大小是正确的,详见sector size

确保分区表类型为GPT。之后创建相关分区(如/dev/sda2用于//dev/sda1用于/efi)。详见分区

格式化分区[编辑 | 编辑源代码]

根分区[编辑 | 编辑源代码]

下列命令创建并挂载加密的根分区,并通过TPM存储密钥。详见dm-crypt/加密非root文件系统(只要正确配置了mkinitcpio引导加载程序其中的内容也可用于加密根分区)、Trusted Platform Module#systemd-cryptenroll

若要使用非默认的加密选项(如cipher、key length),或要求不使用基于TPM的解密,在执行下列命令前参见encryption options

创建所需的LUKS卷(创建时可使用空密码,之后该密码将被擦除):

# cryptsetup luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root
# mkfs.ext4 /dev/mapper/root

ESP[编辑 | 编辑源代码]

详见EFI 系统分区#格式化分区

挂载文件系统[编辑 | 编辑源代码]

安装指南#挂载分区步骤时,注意应挂载解密后产生的映射设备,而不是对应的物理分区,即:

# mount /dev/mapper/root /mnt
# mount --mkdir /dev/sda1 /mnt/efi

继续按照指南进行安装,直到安装指南#关于 initramfs。可以跳过安装指南#生成 fstab 文件步骤。

Initramfs[编辑 | 编辑源代码]

要构建可用的基于systemd的initramfs,修改mkinitcpio.conf中的HOOKS=行:

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

接下来配置需Unified kernel image,详见Unified kernel image#mkinitcpio

由于/efi/EFI/Linux文件夹需在引导加载程序的安装过程中创建,此时不要重新生成initramfs。

引导加载程序[编辑 | 编辑源代码]

通过以下命令安装systemd-boot

# bootctl install

由mkinitcpio创建的Unified kernel image会被自动识别,故无需手动配置/efi/loader/entries

详见systemd-boot#更新 EFI 启动管理器systemd-boot#启动选单配置

完成安装[编辑 | 编辑源代码]

首先,[[mkinitcpio#创建和启用镜像|重新生成initramfs],确保镜像成功生成。

确保设置了root密码重启以完成安装。

安全启动[编辑 | 编辑源代码]

若要启用安全启动,应对引导加载程序和EFI二进制文件进行签名。Unified Extensible Firmware Interface/Secure Boot#Assisted process with sbctl提供了一种简单快捷的方法。

使用TPM[编辑 | 编辑源代码]

在对引导加载程序进行签名并启用安全启动后,可使用TPM来解密LUKS卷。下列命令将移除在格式化LUKS卷时使用的空密码,并创建绑定到TPM PCR 7(默认,UEFI/安全启动#安全启动状态)的密钥。此外,还将创建恢复密钥以在需要时使用。只要启动链未被非法修改,TPM将自动释放密钥。详见Trusted Platform Module#systemd-cryptenrollsystemd-cryptenroll(1)

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