dm-crypt/系统配置
- 如果需要远程解锁 root 或其他早期启动的文件系统(无头机器,远程服务器...),请遵循 dm-crypt/Specialties#远程解锁 root 分区(或其他分区) 中的特定说明。
- 为了方便在配置文件中输入 UUID、PARTUUID 等,您可以安装并使用支持插入命令输出的文本编辑器(例如 nano 与
Ctrl+t
,Vim 或 Neovim 与:read
或 mcedit 与Alt+u
),并传递给它适当的 lsblk 或 blkid 命令。 或者,您可以安装终端复用器并使用其复制和粘贴功能。
在早期用户空间解锁
启动加密的 root 卷需要 initramfs 包含必要的工具,以便早期用户空间解锁卷。关于解锁内容的指令通常通过 内核参数 传递。
以下章节描述了如何配置 mkinitcpio,并列出了所需的内核参数。
mkinitcpio
根据具体情况,需要启用以下 mkinitcpio 钩子 的子集
busybox | systemd | 用例 |
---|---|---|
encrypt
|
sd-encrypt
|
当 root 分区被加密,或者当一个加密分区需要在 root 分区之前挂载时需要。在其他情况下不需要,因为系统初始化脚本(如 /etc/crypttab )已经负责解锁其他非 root 分区。此钩子必须放置在 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=
参数指定实际(解密)的 root 文件系统的 device
root=device
- 如果文件系统直接格式化在解密设备文件上,这将是
/dev/mapper/dmname
。 - 如果首先激活 LVM 并且包含一个 加密的逻辑 root 卷,则上述形式也适用。
- 如果 root 文件系统包含在完全 加密的 LVM 的逻辑卷中,则它的设备映射器将是
root=/dev/卷组/逻辑卷
的通用形式。
- 当使用
sd-encrypt
钩子和 GPT 分区自动挂载 时,可以省略root=
参数的指定。 请参阅 LUKS on a partition。 - 当使用 GRUB 并使用 grub-mkconfig 生成
grub.cfg
时,不需要手动指定root=
参数。 grub-mkconfig 将确定解密的 root 文件系统的正确 UUID,并将其自动添加到grub.cfg
中。
resume
resume=device
device
是用于休眠到磁盘的解密(交换)文件系统的设备文件。 如果交换分区位于单独的分区上,则它将是/dev/mapper/swap
的形式。 另请参阅 dm-crypt/Swap 加密。
使用 encrypt hook
encrypt
钩子不支持- 解锁 多个加密磁盘 (archlinux/mkinitcpio/mkinitcpio#231)。 在 initramfs 中只能解锁一个设备。
- 使用 分离的 LUKS 标头 (archlinux/mkinitcpio/mkinitcpio#234)。
- 设置 crypttab 支持的其他选项。
cryptdevice
这指定了冷启动时包含加密 root 的设备。 它由 encrypt
钩子解析,以识别哪个设备包含加密系统
cryptdevice=device:dmname:options
device
是备份加密设备的设备的路径。 强烈建议使用持久块设备命名。dmname
是解密后赋予设备的device-mapper 名称,它将作为/dev/mapper/dmname
可用。options
(可选) 是逗号分隔的选项,例如,用于 TRIM 支持。 如果不需要选项,请省略此参数(使用cryptdevice=device:dmname
)。- 如果 LVM 包含 加密的 root,则首先激活 LVM,并且包含加密 root 的逻辑卷的卷组充当 device。 然后是要映射到 root 的相应卷组。 该参数遵循
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
中硬编码 root 块设备标识符(例如 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
替换为密钥文件所在的设备的标识符。
- 如果文件系统的类型与您的 root 文件系统不同,则必须在 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,而不是在其他地方指定为 root 文件系统的解密卷的 UUID。
rd.luks.data
当使用分离的 LUKS 标头时,指定带有加密数据的块设备。 必须与 rd.luks.options
一起使用以指定标头文件位置。
有关详细信息和说明,请参阅 dm-crypt/Specialties#使用分离的 LUKS 标头的加密系统。
在后期用户空间解锁
crypttab
/etc/crypttab
(加密设备表)文件类似于 fstab 文件,包含启动期间要解锁的加密设备列表。 此文件可用于自动挂载加密的交换设备或辅助文件系统。
crypttab
在 fstab
之前读取,以便可以在挂载内部文件系统之前解锁 dm-crypt 容器。 请注意,crypttab
在系统启动后读取,因此它不能替代使用 mkinitcpio 钩子和 通过使用内核参数配置它们 来解锁加密分区,就像 加密 root 分区 的情况一样。 启动时 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
选项的时间量。使用密钥文件解锁
如果辅助文件系统的密钥文件本身存储在加密的 root 中,则在系统断电时它是安全的,并且可以作为源,以便在启动期间通过 crypttab 自动解锁挂载。 例如,解锁由 UUID 指定的加密
/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
当您的 /etc/crypttab
中有如下条目时,您可以 启动 systemd-cryptsetup@externaldrive.service
。
/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。