systemd-cryptenroll
- systemd-cryptenroll 是一个用于将硬件安全令牌和设备注册到 LUKS2 加密卷中的工具,随后这些令牌可用于在启动期间解锁该卷。
systemd-cryptenroll 允许将 智能卡、FIDO2 令牌和 可信平台模块 (TPM) 安全芯片以及普通密码注册到 LUKS 设备中。这些设备随后由 systemd-cryptsetup@.service(8) 使用已注册的令牌来解锁。
安装
systemd-cryptenroll 是 systemd 的一部分并随其一起打包。但是,要使用硬件设备作为密钥,需要安装额外的软件包。
- 要使用 PKCS#11 令牌,请 安装 libp11-kit,您可能还需要 opensc 和 opensc-p11-kit-moduleAUR[断开的链接: 未找到软件包]。
- 要使用 FIDO2 令牌,请安装 libfido2。
- 要使用 TPM2 设备,请安装 tpm2-tss。
列出密钥槽
systemd-cryptenroll 可以列出 LUKS 设备中的密钥槽,类似于 cryptsetup 的 luksDump,但采用了更用户友好的格式。
# systemd-cryptenroll /dev/disk
SLOT TYPE 0 password 1 recovery 2 tpm2
擦除密钥槽
# systemd-cryptenroll /dev/disk --wipe-slot=SLOT
其中 SLOT 可以是:
- 单个密钥槽索引,如 #列出密钥槽 中所示
- 一种密钥槽类型,将擦除该类型的所有密钥槽。有效类型包括
empty,password,recovery,pkcs11,fido2,tpm2 - 上述所有项的组合,用逗号分隔
- 字符串
all,擦除设备上的所有密钥槽。此选项仅在同时注册另一个设备或密码时才能使用。
--wipe-slot 操作可与所有注册选项结合使用,这对于更新现有的设备注册非常有用。
# systemd-cryptenroll /dev/disk --wipe-slot=fido2 --fido2-device=auto
注册密码
普通密码
这等同于 cryptsetup luksAddKey。
# systemd-cryptenroll /dev/disk --password
恢复密钥
- 恢复密钥与密码基本相同,但是由计算机生成的而非由人类选择,因此具有保证的高熵值。该密钥使用易于输入的字符集,并且可以通过二维码从屏幕上扫描。
恢复密钥旨在作为硬件令牌不可用时的备用方案,并且可以在任何需要普通密码的地方代替使用。
# systemd-cryptenroll /dev/disk --recovery-key
注册硬件设备
--type-device 选项必须指向其相应类型的有效设备路径。可以通过向此选项传递 list 参数来获取可用设备列表。或者,如果您仅连接了单个所需类型的设备,可以使用 auto 选项自动选择它。
PKCS#11 令牌或智能卡
令牌或智能卡必须包含一对 RSA 密钥,用于加密生成的将用于解锁卷的密钥。
# systemd-cryptenroll /dev/disk --pkcs11-token-uri=device
FIDO2 令牌
任何支持 "hmac-secret" 扩展的 FIDO2 令牌都可以与 systemd-cryptenroll 配合使用。以下示例将 FIDO2 令牌注册到加密的 LUKS2 块设备中,仅需要用户存在 (user presence) 作为身份验证。
# systemd-cryptenroll /dev/disk --fido2-device=device --fido2-with-client-pin=no
此外,systemd-cryptenroll 支持使用令牌内置的用户验证方法。
--fido2-with-user-presence定义在解锁前是否验证用户存在(例如,通过触摸令牌),默认值为 yes。--fido2-with-user-verification定义在解锁前是否需要用户验证,默认值为 no。
- 如果令牌不支持这些功能,则这些选项将没有效果。
- 有关两者之间区别的更多信息,请参阅 用户存在 vs 用户验证 (User Presence vs User Verification)。
默认情况下,生成 FIDO2 凭据时使用的加密算法是 es256,表示基于 NIST P-256 和 SHA-256 的椭圆曲线数字签名算法 (ECDSA)。如果 FIDO2 令牌提供且需要,可以在注册期间指定不同的加密算法。
假设之前已经注册了一个 FIDO2 令牌,用户希望注册另一个,以下命令将生成一个 eddsa 凭据(表示基于 Curve25519 和 SHA-512 的 EdDSA),并使用之前注册的令牌而不是密码来验证设备。
# systemd-cryptenroll /dev/disk --fido2-device=device --fido2-credential-algorithm=eddsa --unlock-fido2-device=auto
可信平台模块 (TPM)
systemd-cryptenroll 原生支持将 LUKS 密钥注册到 TPM 中。它需要以下条件:
- 必须 安装 tpm2-tss,
- 一个 LUKS2 设备(目前是 cryptsetup 使用的默认类型),
- 如果您打算在根分区上使用此方法,需要对 initramfs 进行一些调整(高级配置请参阅 dm-crypt/系统配置#使用 systemd-cryptsetup-generator)。
- mkinitcpio 用户:启用
systemd和sd-encrypt钩子 (hooks)。注意 钩子中条目的顺序非常重要。非标准顺序 可能会导致系统无法启动(您将需要从 arch-chroot 中 重新生成 initramfs 来恢复)。正确顺序的示例请参阅 dm-crypt/系统配置#示例。 - dracut 用户:启用
tpm2-tss模块。
- mkinitcpio 用户:启用
首先,运行以下命令来列出已安装的 TPM 及其使用的驱动程序:
$ systemd-cryptenroll --tpm2-device=list
- 如果您的计算机安装了多个 TPM,请在后续步骤中使用
--tpm2-device=/path/to/tpm2_device指定您想要使用的一个。 - 考虑使用 PCR 策略 (PCR policies) 而不是将机密绑定到原始 PCR 值。
可以使用单个命令同时将密钥注册到 TPM 和 LUKS 卷中。以下示例生成一个新的随机密钥,将其添加到卷中(以便在现有密钥之外也可以使用它来解锁),并将此新密钥绑定到 PCR 7(安全启动 Secure Boot 状态):
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sdX
其中 /dev/sdX 是加密 LUKS 卷的完整路径。如果 LUKS 卷由密钥文件而非密码解锁,请使用 --unlock-key-file=/path/to/keyfile。
有关 Linux 中常见的 PCR 测量值,请参考 systemd-cryptenroll(1) 和 可信平台模块#访问 PCR 寄存器。根据需要调整 --tpm2-pcrs=7(参数由 + 符号分隔)。
- 在绑定到 PCR 7 时,请确保 安全启动已激活且处于用户模式,否则未经授权的启动设备可能会解锁加密卷。
- 如果固件证书发生变化,PCR 7 的状态可能会改变,这可能会导致用户被锁定。这可能会由 fwupd 隐式完成[1],或者通过显式轮换安全启动密钥来完成。
- 仅绑定到启动前测量的 PCR (PCR 0-7) 会给恶意操作系统留下漏洞。一个从真实根文件系统复制了元数据(如分区 UUID)的恶意分区可以模拟原始分区。然后,initramfs 将尝试将该恶意分区挂载为根文件系统(解密失败将回退到密码输入),而启动前 PCR 保持不变。由攻击者控制文件的恶意根文件系统仍然能够接收真实根分区的解密密钥。更多信息请参阅 Brave New Trusted Boot World 和 BitLocker 文档。
- 针对根卷的一种解决方案是使用
--tpm2-pcrs=other_pcrs+15:sha256=0000000000000000000000000000000000000000000000000000000000000000绑定到一个空的 PCR 15。如果您设置了任何rd.luks内核参数或使用/etc/crypttab.initramfs,请在rd.luks.options=或/etc/crypttab.initramfs的第四个字段中额外添加tpm2-measure-pcr=yes选项;当依赖 GPT 分区自动挂载 时则不需要此操作。在早期用户空间解锁根卷后,PCR 15 将发生变化,注册的密钥将不再可检索。 - 另一种更简洁的解决方案在 dm-crypt/系统配置#钉住 LUKS 卷 (Pinning a LUKS volume) 中有描述。
绑定 PCR 的组合取决于具体情况,以平衡易用性和锁定强度。例如,您可能希望在无需手动干预 安全启动 状态的情况下更新 UEFI 固件,或者支持不同的启动设备。另一个例子是,微软的 Bitlocker 倾向于使用 PCR 7+11,但也可能使用其他 PCR 组合。
- 除了 TPM 状态正确外,还可以要求输入 PIN 码。只需在上述命令中添加选项
--tpm2-with-pin=yes并在提示时输入 PIN 码即可。 - systemd-cryptenroll 在请求 PIN 码之前不会检查 TPM 测量值,因此请考虑使用唯一的 PIN 码,因为此时的环境可能不可信。
要检查新密钥是否已注册,请转储 LUKS 配置并查找 systemd-tpm2 令牌条目,以及 Keyslots 部分中的一个额外条目。
# cryptsetup luksDump /dev/sdX
要测试密钥是否有效,请在 LUKS 卷关闭时运行以下命令:
# systemd-cryptsetup attach mapping_name /dev/sdX none tpm2-device=auto
其中 mapping_name 是您为打开后的卷选择的名称。
请参阅 dm-crypt/系统配置#crypttab 和 dm-crypt/系统配置#可信平台模块和 FIDO2 密钥 以在启动时解锁卷。
/etc/crypttab 中使用 LUKS 卷的 UUID 代替路径名,但 systemd-cryptenroll 命令本身目前仅支持路径名。更多信息和示例请参阅 systemd-cryptenroll(1) 和 crypttab(5)。