dm-crypt/系统配置

出自 ArchWiki
(重定向自 Crypttab

此条目或章节需要扩充。

原因:dm-crypt 的其他子条目中关于系统配置的所有通用信息汇总到此处。(在 Talk:Dm-crypt/System configuration 中讨论)
提示

在早期用户空间解锁

启动加密的 root 卷需要 initramfs 包含必要的工具,以便早期用户空间解锁卷。关于解锁内容的指令通常通过 内核参数 传递。

以下章节描述了如何配置 mkinitcpio,并列出了所需的内核参数。

mkinitcpio

根据具体情况,需要启用以下 mkinitcpio 钩子 的子集

busybox systemd 用例
encrypt sd-encrypt 当 root 分区被加密,或者当一个加密分区需要在 root 分区之前挂载时需要。在其他情况下不需要,因为系统初始化脚本(如 /etc/crypttab)已经负责解锁其他非 root 分区。此钩子必须放置在 udevsystemd 钩子之后
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 钩子。 rootresume 的指定方式对于两者都是相同的。

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

注意:sd-encrypt 钩子相比,encrypt 钩子不支持
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 的形式。
提示: 您可能想要为固态硬盘 (SSD) 启用 Discard/TRIM 支持
cryptkey
提示: 如果要使用密码短语,则不需要手动指定 cryptkey= 参数。 然后将在启动时提示您输入密码短语。

此参数指定密钥文件的位置,并且 encrypt 钩子需要它来读取此类密钥文件以解锁 cryptdevice(除非密钥位于默认位置,请参阅下文)。 它可以有三组参数,具体取决于密钥文件是作为特定设备中的文件、特定位置开始的位流还是 initramfs 中的文件存在。

对于设备中的文件,格式为

cryptkey=device:fstype:path
  • device 是密钥存在的原始块设备。 强烈建议使用持久块设备命名
  • fstypedevice 的文件系统类型(或 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 密钥。

对于 包含 在 initramfs 中的文件,格式为[1]

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-generatorinitramfs 阶段 运行。

在下文中,我们描述了 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.initramfsluks.*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。 这等效于 encryptcryptdevice 的第二个参数。

例如,指定 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
注意: 包含密钥文件的卷在启动期间不会被卸载。 请参阅 systemd issue 28021
rd.luks.options
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=options

rd.luks.options=options

为 UUID 指定的设备设置选项,或者,如果未指定,则为所有未在其他地方(例如,crypttab)指定的 UUID 设置选项。

此参数类似于 crypttab 的 options 字段。 格式相同——选项用逗号分隔,带值的选项使用 option=value 指定。 这大致等效于 encryptcryptdevice 的第三个参数。

例如

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.uuidrd.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 文件,包含启动期间要解锁的加密设备列表。 此文件可用于自动挂载加密的交换设备或辅助文件系统。

crypttabfstab 之前读取,以便可以在挂载内部文件系统之前解锁 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 的更多信息,请参阅 #按需挂载

提示: 如果您使用 GPT 和特定的分区类型 UUID,则可以使用 systemd 避免为某些挂载点使用 crypttab 和 fstab。 有关更多信息,请参阅 systemd#GPT 分区自动挂载

启动时挂载

此条目或章节是与 #crypttab 合并的候选对象。

注意: 没有必要用两个章节来解释一个文件的用法。(在 Talk:Dm-crypt/System configuration 中讨论)

如果您想在启动时挂载加密驱动器,请在 /etc/crypttab 中输入设备的 UUID。 您可以使用命令 lsblk -f 获取 UUID(分区),并以以下形式将其添加到 crypttab

/etc/crypttab
externaldrive         UUID=2f9a8428-ac69-478a-88a2-4aa458565431        none    timeout=180

第一个参数是您首选的加密驱动器的设备映射器名称。 选项 none 将在启动期间触发提示,以键入用于解锁分区的密码短语。 timeout 选项定义了在启动期间输入解密密码的超时时间(以秒为单位)。

提示: 在密码提示中输入的密码由 systemd-cryptsetup(8) 缓存在内核密钥环中(当使用 sd-encrypt 钩子时,这也包括在 initramfs 阶段输入的密码)。 如果 crypttab 中的设备使用先前输入的密码,则可以将第三个参数设置为 none,并且将自动使用缓存的密码。
注意: 请记住,crypttab 中的 timeout 选项仅确定允许输入加密设备密码的时间量。 此外,systemd 还有一个默认超时,它确定允许设备可用的时间量(默认为 90 秒),这与密码计时器无关。 因此,即使 crypttab 中的 timeout 选项设置为大于 90 秒的值(或者它的默认值为 0,表示无限时间),systemd 仍然只会最多等待 90 秒以解锁设备。 为了更改 systemd 等待设备可用的时间,可以在 fstab 中为所述设备设置选项 x-systemd.device-timeout(请参阅 systemd.mount(5))。 因此,可能期望 crypttabtimeout 选项的时间量等于 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