背景

背景

背景

我正在尝试在 CentOS 8 Stream 上配置自动 LUKS 解锁。我想在未加密的引导分区上放置一个密钥文件,并使用它来解锁受 LUKS 保护的 LVM PV(其中包含根文件系统)。 我知道这是一件奇怪的事情,并且破坏了磁盘加密的大部分价值 - 但请幽默我。

以下是当前布局的概述:

$ lsblk
NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
nvme0n1                                       259:0    0 931.5G  0 disk  
├─nvme0n1p1                                   259:1    0   256M  0 part  /boot/efi
├─nvme0n1p2                                   259:2    0     1G  0 part  /boot
└─nvme0n1p3                                   259:3    0 930.3G  0 part  
  └─luks-3d33d226-9640-4343-ba5a-b9812dda1465 253:0    0 930.3G  0 crypt 
    └─cs-root                                 253:1    0    20G  0 lvm   /
$ sudo e2label /dev/nvme0n1p2
boot

今天,它/etc/crypttab包含以下内容,用于使用手动输入的密码(为了可读性而编辑的 UUID)启动,效果很好:

luks-blah UUID=blah none discard

为了实现自动解锁,我生成了一个密钥文件/boot/keys/keyfile,并将其作为密钥添加到 LUKS 分区上,使用luksAddKey.

尝试1

在我的第一次尝试中,我将 crypttab 行更改为:

luks-blah UUID=blah /keys/keyfile:LABEL=boot discard,keyfile-timeout=10s

这确实会导致自动解锁和安装根文件系统,但引导过程失败并将我转储到救援模式,因为系统无法安装/boot。原因是引导分区已经被安装(到一个随机位置以获得密钥文件:)/run/systemd/cryptsetup/keydev-luks-blah

尝试2

我尝试将 crypttab 更改为:

luks-blah UUID=blah /boot/keys/keyfile discard,keyfile-timeout=10s

我想也许引导脚本足够聪明,可以弄清楚如何/boot/keys/keyfile在尚未/boot安装的情况下进行访问。但这不起作用,我只是收到手动输入密码的提示。

问题

有没有办法使用存储在需要用于正常安装的分区上的密钥文件来解锁根文件系统?

答案1

这是一个基于 Nikita 建议的解决方案,尝试将密钥文件放入 initramfs 中,并进行调整以与 CentOS 8 配合使用。

请注意,使用此方法无需将原始密钥文件放置在未加密的文件系统上。在 initramfs 生成期间,它将被复制到未加密(但已压缩)的 initramfs。这可能会增加一点混乱。

1.更新crypttab

更新crypttab以指定我们将放置在 initramfs 中的密钥文件的路径:

luks-blah UUID=blah /boot/keys/keyfile discard,keyfile-timeout=10s

2.配置dracut

在该文件下创建一个文件/etc/dracut.conf.d,配置将密钥文件复制到 initramfs 中(请参阅 参考资料man 5 dracut.conf)。密钥文件在 initramfs 中的位置相同。

$ cat /etc/dracut.conf.d/copy-keyfile.conf 
install_items+=/boot/keys/keyfile

现在更新 initramfs:dracut -f

3. 确认

选修的:确认lsinitrd该文件现在存在于 initramfs 中。这向我展示了:

-r-------- 1 root root 32 Aug 9 20:09 boot/keys/keyfile

答案2

将密钥文件放入初始化文件系统然后启动脚本就可以在那里找到它。

不过我从来没有在 CentOS 中这样做过。我不使用 LUKS,但这对于演示这个想法并不是很重要。

以下是在 Debian 中如何执行此操作。

一个/etc/crypttab文件看起来像这样:

lvm0 /dev/md/lvm0 none cipher=aes-xts-plain64,hash=ripemd160,keyscript=/etc/initramfs-tools/lvm0.sh

我使用名为 md raid(superblock 版本 1.2)作为基础设备,因此它是安全的,因为该设备可以通过 UUID 有效识别。未加密的设备将如/dev/mapper/lvm0本例所示,正如您可能已经猜到的那样,它是 LVM PV。

keyscript 是将密钥打印到标准输出的 shell 脚本。这里给出的路径就是路径在根文件系统中(已加密)。 debian的initramfs生成脚本足够聪明,可以找到lvm0.sh需要复制到initramfs中的文件,并调整路径,以便init脚本真正找到initramfs中的关键脚本。关键脚本本身可能如下所示(不要逐字复制,生成您自己的所需长度的随机字符串):

#!/bin/sh

cat - <<EOF
egjseoius9usajogj8g...
EOF

实际设置如下:启动分区位于启动计算机所需的可移动介质上;计算机完成启动后,该介质将被删除。我基于这个想法构建了多个系统;由于启动介质(闪存棒)是解锁加密设备的唯一方法,因此在每种情况下,我们都要求客户始终拥有至少两份安全存储的启动介质副本。

我也在 Gentoo 中采用了完全相同的概念,但是那里的系统更加定制化,并且发明了整个定制的 initramfs init 脚本。该脚本包含与此类似的命令来解锁加密设备:

cryptsetup open /dev/sda3 pv0 --key-file=/etc/keys/pv0.key --allow-discards --type=plain --cipher=aes-xts-plain64 --key-size=256

(我们还需要确保 initramfs 包含该/etc/keys/pv0.key文件)。

我希望您能够将其适应 CentOS。

相关内容