dm-crypt/系统配置
- 如果需要远程解锁 root 文件系统或其他早期启动的文件系统(无头机器,远程服务器...),请遵循 dm-crypt/Specialties#远程解锁 root (或其他) 分区 中的特定说明。
- 为了方便在配置文件中输入 UUID、PARTUUID 等,您可以安装并使用支持插入命令输出的文本编辑器(例如,nano,使用
Ctrl+t
;Vim 或 Neovim,使用:read
;或 mcedit,使用Alt+u
),并将其传递给适当的 lsblk 或 blkid 命令。或者,您可以安装终端复用器并使用其复制和粘贴功能。
在早期用户空间解锁
启动加密的根卷需要 initramfs 包含必要的工具,以便早期用户空间解锁卷。通常通过内核参数传递关于要解锁的内容的说明。
以下章节描述了如何配置 mkinitcpio,并列出了所需的内核参数。
mkinitcpio
根据具体情况,需要启用以下 mkinitcpio 钩子 的子集
busybox | systemd | 用例 |
---|---|---|
encrypt
|
sd-encrypt
|
当根分区被加密或当需要在根分区之前挂载加密分区时需要。在其他情况下不需要,因为系统初始化脚本(如 /etc/crypttab )已经处理了其他非根分区的解锁。此钩子必须放置在 udev 或 systemd 钩子之后。 |
keyboard
|
使键盘在早期用户空间中工作所必需。 提示: 对于使用不同硬件配置启动的系统(例如,带有外接键盘与内置键盘的笔记本电脑或无头系统),将此钩子放置在
autodetect 之前有助于始终包含所有键盘驱动程序。否则,只有在外接键盘在创建镜像时连接,外接键盘才能在早期用户空间中工作。 | |
keymap
|
sd-vconsole
|
为输入加密密码提供非美国键盘布局支持;它必须在 encrypt 钩子之前,否则您将需要使用默认的美国键盘布局输入加密密码。在 /etc/vconsole.conf 中设置您的键盘布局,请参阅 控制台键盘配置#持久配置。 |
consolefont
|
在早期用户空间中加载备用控制台字体。在 /etc/vconsole.conf 中设置您的字体,请参阅 Linux 控制台#持久配置。 |
所需的其他钩子 应该从系统安装过程中遵循的其他手动步骤中清楚地了解。
/etc/mkinitcpio.conf
进行任何更改后,请记住重新生成 initramfs。示例
使用 encrypt
钩子的典型 /etc/mkinitcpio.conf
配置
/etc/mkinitcpio.conf
... HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck) ...
使用基于 systemd 的 initramfs 和 sd-encrypt
钩子的配置
/etc/mkinitcpio.conf
... HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck) ...
内核参数
您需要指定的内核参数取决于正在使用 encrypt
钩子还是 sd-encrypt
钩子。root
和 resume
对于两者以相同的方式指定。
root
root=
参数指定实际(解密)根文件系统的 device
root=device
- 如果文件系统直接在解密设备文件上格式化,则这将是
/dev/mapper/dmname
。 - 如果 LVM 首先被激活并包含加密的逻辑根卷,则上述形式也适用。
- 如果根文件系统包含在完全加密的 LVM 的逻辑卷中,则其设备映射器将采用
root=/dev/volumegroup/logicalvolume
的通用形式。
- 当使用
sd-encrypt
钩子和 GPT 分区自动挂载 时,可以省略root=
参数的规范。请参阅 LUKS 在分区上。 - 当使用 GRUB 并使用 grub-mkconfig 生成
grub.cfg
时,不需要手动指定root=
参数。grub-mkconfig 将确定解密的根文件系统的正确 UUID 并自动将其添加到grub.cfg
中。
resume
resume=device
device
是用于休眠到磁盘的解密(交换)文件系统的设备文件。如果交换分区位于单独的分区上,则它将采用/dev/mapper/swap
的形式。另请参阅 dm-crypt/交换分区加密。
使用 encrypt hook
encrypt
钩子不支持- 解锁多个加密磁盘 (archlinux/mkinitcpio/mkinitcpio#231)。在 initramfs 中只能解锁一个设备。
- 使用分离的 LUKS 标头 (archlinux/mkinitcpio/mkinitcpio#234)。
- 设置 crypttab 支持的其他选项。
cryptdevice
这指定了冷启动时包含加密根的设备。它由 encrypt
钩子解析,以识别哪个设备包含加密系统
cryptdevice=device:dmname:options
device
是支持加密设备的设备路径。强烈建议使用持久块设备命名。dmname
是解密后赋予设备的设备映射器名称,它将作为/dev/mapper/dmname
可用。options
(可选)是以逗号分隔的选项,例如用于 TRIM 支持。如果不需要任何选项,请省略此参数(使用cryptdevice=device:dmname
)。- 如果 LVM 包含加密的根,则 LVM 首先被激活,并且包含加密根的逻辑卷的卷组充当 device。然后是要映射到根的相应卷组。该参数遵循
cryptdevice=/dev/vgname/lvname:dmname
的形式。
cryptkey
cryptkey=
参数。然后,系统将在启动时提示您输入密码。此参数指定密钥文件的位置,并且 encrypt
钩子需要此参数来读取此类密钥文件以解锁 cryptdevice
(除非密钥位于默认位置,请参见下文)。它可以有三组参数,具体取决于密钥文件是作为特定设备中的文件、特定位置开始的位流还是 initramfs 中的文件存在。
对于设备中的文件,格式为
cryptkey=device:fstype:path
device
是密钥存在的原始块设备。强烈建议使用持久块设备命名。fstype
是device
的文件系统类型(或 auto)。path
是设备中密钥文件的绝对路径。
示例:cryptkey=LABEL=usbstick:vfat:/secretkey
对于设备上的位流,密钥的位置通过以下方式指定
cryptkey=device:offset:size
其中偏移量和大小以字节为单位。例如,cryptkey=UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ:0:512
读取从设备开头开始的 512 字节密钥文件。
:
,则必须使用反斜杠 \
对其进行转义。在这种情况下,cryptkey 参数将如下所示:cryptkey=/dev/disk/by-id/usb-123456-0\:0:0:512
,用于 ID 为 usb-123456-0:0
的 USB 密钥。cryptkey=rootfs:path
示例:cryptkey=rootfs:/secretkey
另请注意,如果未指定 cryptkey
,则默认值为 /crypto_keyfile.bin
(在 initramfs 中)。[2]
另请参阅 dm-crypt/设备加密#密钥文件。
crypto
此参数专门用于将 dm-crypt plain 模式选项传递给 encrypt 钩子。
它采用以下形式
crypto=hash:cipher:keysize:offset:skip
这些参数直接关联到 cryptsetup 选项。请参阅 dm-crypt/设备加密#Plain 模式的加密选项。
对于仅使用 plain 默认选项加密的磁盘,必须指定 crypto
参数,但每个条目都可以留空
crypto=::::
参数的一个具体示例是
crypto=sha512:twofish-xts-plain64:512:0:
使用 systemd-cryptsetup-generator
systemd-cryptsetup-generator 是一个 systemd 单元生成器,它读取 内核参数 和 /etc/crypttab
的子集,用于解锁加密设备。有关其详细信息和所有支持的选项,请参阅 systemd-cryptsetup-generator(8) 手册页。
当使用 sd-encrypt
mkinitcpio 钩子 或 systemd
dracut 模块 时,systemd-cryptsetup-generator 在 initramfs 阶段 运行。
在下文中,我们将描述 systemd-cryptsetup-generator 解释的一些 内核参数。
- 如果文件
/etc/crypttab.initramfs
存在,它将被添加到 initramfs 中作为/etc/crypttab
,您可以在其中指定需要在 initramfs 阶段解锁的设备。有关语法,请参阅 #crypttab。如果/etc/crypttab.initramfs
不存在,则 initramfs 中将没有/etc/crypttab
,并且需要通过下面列出的内核参数指定可解锁的设备。 /etc/crypttab.initramfs
不仅限于使用像rd.luks
这样的 UUID。您可以使用任何 持久性块设备命名方法。- 如果满足 systemd#GPT 分区自动挂载 的所有先决条件,您可以通过使用
/dev/gpt-auto-root-luks
来避免在/etc/crypttab.initramfs
中硬编码根块设备标识符(例如 UUID、PARTUUID 等)。 - 启动期间输入的密码由 systemd-cryptsetup(8) 缓存在内核密钥环中,因此如果多个设备可以使用相同的密码解锁(包括 crypttab 中在启动后解锁的设备),那么您只需输入每个密码一次。
- 可以多次指定所有的
rd.luks
参数来解锁多个 LUKS 加密卷。 rd.luks
参数仅支持解锁 LUKS 设备。要解锁 plain dm-crypt 设备,您必须在/etc/crypttab.initramfs
中指定它。有关语法,请参阅 #crypttab。
/etc/crypttab
或 /etc/crypttab.initramfs
与 luks.*
或 rd.luks.*
参数一起使用,则只有内核命令行上指定的那些设备将被激活,您将看到 Not creating device 'devicename' because it was not specified on the kernel command line.
。这是因为 luks.*
或 rd.luks.*
参数控制从 crypttab 激活哪些设备。要激活 /etc/crypttab
中的所有设备,请不要指定任何 luks.*
参数,并使用 rd.luks.*
。要激活 /etc/crypttab.initramfs
中的所有设备,请不要指定任何 luks.*
或 rd.luks.*
参数。rd.luks.uuid
rd.luks.name
时,可以省略 rd.luks.uuid
。rd.luks.uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
使用此标志指定要在启动时解密的设备的 UUID。
默认情况下,映射的设备将位于 /dev/mapper/luks-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
,其中 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 是 LUKS 分区的 UUID。
rd.luks.name
rd.luks.uuid
。rd.luks.name=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=name
指定 LUKS 分区打开后映射设备的名称,其中 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 是 LUKS 分区的 UUID。这等同于 encrypt
的 cryptdevice
的第二个参数。
例如,指定 rd.luks.name=12345678-9abc-def0-1234-56789abcdef0=root
会使 UUID 为 12345678-9ABC-DEF0-1234-56789ABCDEF0
的已解锁 LUKS 设备位于 /dev/mapper/root
。
rd.luks.key
指定用于解密由其 UUID 指定的设备的密码文件的位置。与 encrypt
钩子参数 cryptkey
不同,没有默认位置。
如果密钥文件 包含在 initramfs 中
rd.luks.key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=/path/to/keyfile
或
rd.luks.key=/path/to/keyfile
/etc/cryptsetup-keys.d/name.key
的形式包含,则可以省略整个 rd.luks.key
参数。如果密钥文件位于另一个设备上
rd.luks.key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=/path/to/keyfile:UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ
将 UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ
替换为密钥文件所在的设备的标识符。
- 如果文件系统的类型与您的根文件系统不同,您必须 在 initramfs 中包含其内核模块。
- 默认情况下,具有另一个设备上的密钥文件的
rd.luks.key
在设备不可用时不会回退到询问密码。要回退到密码提示,请在rd.luks.options
中指定keyfile-timeout=
选项。例如,对于 10 秒超时rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=keyfile-timeout=10s
rd.luks.options
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=options
或
rd.luks.options=options
为由其 UUID 指定的设备设置选项,或者,如果未指定,则为所有在其他地方(例如,crypttab)未指定的 UUID 设置选项。
此参数类似于 crypttab 的 options 字段。格式相同——选项用逗号分隔,带有值的选项使用 option=value
指定。这大致等同于 encrypt
的 cryptdevice
的第三个参数。
例如
rd.luks.options=timeout=10s,discard,password-echo=no,tries=1
超时
有两个选项会影响启动期间输入密码的超时时间
rd.luks.options=timeout=mytimeout
指定查询密码的超时时间rootflags=x-systemd.device-timeout=mytimeout
指定 systemd 在放弃之前应等待 rootfs 设备出现多长时间(默认为 90 秒)
如果要完全禁用超时,请将两个超时时间都设置为零
rd.luks.options=timeout=0 rootflags=x-systemd.device-timeout=0
密码回显
当用户输入密码时,systemd-cryptsetup 默认情况下为每个输入的字符输出星号 (*
)。这与 encrypt
钩子不同,后者不输出任何内容。要静默输出,请设置 password-echo=no
选项
rd.luks.options=password-echo=no
可信平台模块和 FIDO2 密钥
如果您的系统中有一个可用的 TPM2 芯片,或者您使用 FIDO2 兼容的安全密钥,您可以使用它来自动解锁您的卷,而无需使用密码或密钥文件。
设置
- 对于 TPM2 芯片:
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=tpm2-device=auto
- 对于 FIDO2 密钥:
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=fido2-device=auto
除了 rd.luks.uuid
或 rd.luks.name
之外
或者,可以使用 /etc/crypttab.initramfs
,这样可以避免需要指定任何内核选项。
/etc/crypttab.initramfs
root UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX none tpm2-device=auto
/etc/crypttab.initramfs
进行任何更改后,请记住重新生成 initramfs。在这里,加密卷以名称 root
(出现在 /dev/mapper/root
中)挂载,通过存储设备的 UUID 挂载,没有密码,并从 TPM2 设备检索密钥。
请注意,必须在密码字段顺序中提供 none
才能使用 TPM2 设备,否则,给定的值将用作密码或密钥,如果它不起作用,它会要求您在启动期间键入密码,而不会尝试从 TPM2 设备加载密钥。
如果如上所示通过 UUID 指定设备,请确保它是底层(加密的)存储设备的 UUID,而不是在其他地方指定为根文件系统的已解密卷的 UUID。
rd.luks.data
当使用分离的 LUKS 标头时,指定带有加密数据的块设备。必须与 rd.luks.options
一起使用以指定标头文件位置。
有关详细信息和说明,请参阅 dm-crypt/Specialties#使用分离的 LUKS 标头的加密系统。
在后期用户空间中解锁
crypttab
/etc/crypttab
(加密设备表)文件类似于 fstab 文件,包含系统启动期间要解锁的加密设备列表。此文件可用于自动挂载加密的交换设备或辅助文件系统。
crypttab
在 fstab
之前读取,以便可以在挂载内部文件系统之前解锁 dm-crypt 容器。请注意,crypttab
在系统启动后读取,因此它不能替代使用 mkinitcpio 钩子和 使用内核参数配置它们来解锁加密分区,就像 加密根分区 的情况一样。启动时 crypttab
的处理由 systemd-cryptsetup-generator(8) 自动完成。
有关详细信息,请参阅 crypttab(5),请阅读以下示例,并参阅 #启动时挂载 部分,了解如何使用 UUID 挂载加密设备。
- 如果指定了
nofail
选项,则在输入密码时,密码输入屏幕可能会消失。因此,nofail
应该只与密钥文件一起使用。 - 对于 dm-crypt plain 模式 设备,必须显式设置
plain
选项,以强制 systemd-cryptsetup(8) 识别它们。请参阅 systemd issue 442。
/etc/crypttab
# Example crypttab file. Fields are: name, underlying device, passphrase, cryptsetup options. # Mount /dev/lvm/swap re-encrypting it with a fresh key each reboot swap /dev/lvm/swap /dev/urandom swap,cipher=aes-xts-plain64,size=256,sector-size=4096 # Mount /dev/lvm/tmp as /dev/mapper/tmp using plain dm-crypt with a random passphrase, making its contents unrecoverable after it is dismounted. tmp /dev/lvm/tmp /dev/urandom tmp,cipher=aes-xts-plain64,size=256 # Mount /dev/lvm/home as /dev/mapper/home using LUKS, and prompt for the passphrase at boot time. home /dev/lvm/home # Mount /dev/sdb1 as /dev/mapper/backup using LUKS, with a passphrase stored in a file. backup /dev/sdb1 /home/alice/backup.key # Unlock /dev/sdX using the only available TPM, naming it myvolume myvolume /dev/sdX none tpm2-device=auto
要在编辑 crypttab 后立即测试它,请使用 daemon-reload 重新加载 systemd 管理器配置,并 启动 新生成的 systemd-cryptsetup@name.service
。
# cryptsetup status name
/dev/mapper/name is active. type: ... cipher: ... keysize: ... bits key location: ... device: /dev/sdxN sector size: ... offset: ... sectors size: ... sectors mode: ... flags: ...
有关 systemd-cryptsetup@name.service
的更多信息,请参阅 #按需挂载。
启动时挂载
如果您想在启动时挂载加密驱动器,请在 /etc/crypttab
中输入设备的 UUID。您可以使用命令 lsblk -f
获取 UUID(分区),并以以下形式将其添加到 crypttab
中
/etc/crypttab
externaldrive UUID=2f9a8428-ac69-478a-88a2-4aa458565431 none timeout=180
第一个参数是您首选的加密驱动器的设备映射器名称。 none
选项将触发启动期间的提示,以键入用于解锁分区的密码。 timeout
选项定义了在启动期间输入解密密码的超时时间(以秒为单位)。
crypttab
中的设备使用先前输入的密码,则可以将第三个参数设置为 none
,并且将自动使用缓存的密码。crypttab
中的 timeout
选项仅确定输入加密设备密码的允许时间。此外,systemd 还有一个默认超时时间,它确定设备可用的允许时间(默认为 90 秒),这与密码计时器无关。因此,即使 crypttab
中的 timeout
选项设置为大于 90 秒的值(或者它的默认值为 0,表示无限时间),systemd 仍然只会等待最多 90 秒以解锁设备。为了更改 systemd 等待设备可用的时间,可以在 fstab 中为所述设备设置 x-systemd.device-timeout
选项(请参阅 systemd.mount(5))。因此,可能需要使 crypttab
中 timeout
选项的时间量等于 fstab 中每个启动时挂载的设备的 x-systemd.device-timeout
选项的时间量。使用密钥文件解锁
如果辅助文件系统的 密钥文件 本身存储在加密的根目录中,则在系统断电时它是安全的,并且可以在启动期间通过 crypttab 获取源以自动解锁挂载。例如,解锁由 UUID 指定的 crypt
/etc/crypttab
home-crypt UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /etc/cryptsetup-keys.d/home-crypt.key
- 如果未指定密钥文件,systemd-cryptsetup(8) 将自动尝试从
/etc/cryptsetup-keys.d/name.key
和/run/cryptsetup-keys.d/name.key
加载它。[3] - 如果您更喜欢使用
--plain
模式的块设备,则解锁它所需的加密选项在/etc/crypttab
中指定。在这种情况下,请注意应用 crypttab 中提到的 systemd 解决方法。
然后使用设备映射器的名称(在 /etc/crypttab
中定义)在 /etc/fstab
中创建一个条目
/etc/fstab
/dev/mapper/home-crypt /home ext4 defaults 0 2
由于 /dev/mapper/home-crypt
已经是唯一分区映射的结果,因此无需为其指定 UUID。在任何情况下,带有文件系统的映射器都将具有与加密它的分区不同的 UUID。
挂载堆叠块设备
systemd 生成器还在启动时自动处理堆叠块设备。
例如,您可以创建一个 RAID 设置,在其上使用 cryptsetup,并在加密的块设备内部创建一个带有相应文件系统的 LVM 逻辑卷。结果是
$ lsblk -f
─sdXX linux_raid_member │ └─md0 crypto_LUKS │ └─cryptedbackup LVM2_member │ └─vgraid-lvraid ext4 /mnt/backup └─sdYY linux_raid_member └─md0 crypto_LUKS └─cryptedbackup LVM2_member └─vgraid-lvraid ext4 /mnt/backup
将询问密码并在启动时自动挂载。
如果您指定了正确的 crypttab (例如 crypto_LUKS
设备的 UUID) 和 fstab (/dev/vgraid/lvraid
) 条目,则无需添加额外的 mkinitcpio 钩子/配置,因为 /etc/crypttab
处理仅适用于非 root 挂载。一个例外是当已经使用了 mdadm_udev
钩子时(例如,对于 root 设备)。在这种情况下,需要更新 /etc/madadm.conf
和 initramfs 以实现首先选择正确的 root raid。
按需挂载
代替使用
# cryptsetup open UUID=... externaldrive
您可以启动 systemd-cryptsetup@externaldrive.service
,当您的 /etc/crypttab
中有如下条目时
/etc/crypttab
externaldrive UUID=... none noauto
这样您就不需要记住确切的 crypttab 选项。如果需要,它会提示您输入密码。
相应的单元文件由 systemd-cryptsetup-generator(8) 自动生成。您可以使用以下命令列出所有生成的单元文件
$ systemctl list-unit-files | grep systemd-cryptsetup
故障排除
系统卡在启动/密码提示不显示
如果您正在使用 Plymouth,请确保使用正确的模块(参见 Plymouth#mkinitcpio)或禁用它。否则,Plymouth 将吞噬密码提示,导致系统无法启动。
如果您使用键盘或位于 initramfs 生成时不存在的文件系统上的密钥文件解锁 LUKS 设备,您可能需要将相应的模块添加到 mkinitcpio 的 MODULES
数组中。当键盘通过 USB 集线器连接时,也可能需要这样做。有关此问题的更多信息,请参见 mkinitcpio#MODULES,有关要添加的潜在键盘和文件系统模块名称的起点,请参见 Minimal initramfs#Sorting out modules。
通常,对于在 initramfs 生成时未连接到 PC 的键盘,您需要将 keyboard
钩子放在 autodetect
钩子之前,否则只会保留当前连接硬件所需的部分,请参见 mkinitcpio#Common hooks。