在系统启动时解密 LUKS 容器

大家早安晚安! 这篇文章将对那些使用 LUKS 数据加密并希望在 Linux(Debian,Ubuntu)下解密磁盘的人有用 解密根分区的阶段. 我在互联网上找不到这样的信息。

最近,随着上架磁盘数量的增加,我遇到了通过/etc/crypttab使用比众所周知的方法解密磁盘的问题。 就个人而言,我强调了使用此方法的一些问题,即正在读取文件 仅在加载(挂载)根分区后,这会对 ZFS 导入产生负面影响,特别是如果它们是从 *_crypt 设备上的分区构建的,或者也是从分区构建的 mdadm raids。 我们都知道您可以在 LUKS 容器上使用 parted,对吧? 还有其他服务提前启动的问题,当还没有数组的时候,但是 使用 我已经需要一些东西(我在 iSCSI 上使用集群 Proxmox VE 5.x 和 ZFS)。

关于 ZFSoverISCSI 的一些信息iSCSI 通过 LIO 为我工作,实际上当 iSCSI 目标启动并且没有看到 ZVOL 设备时,它只是将它们从配置中删除,从而阻止客户系统启动。 因此,要么恢复 json 文件备份,要么手动添加具有每个 VM 标识符的设备,当有几十台这样的机器并且每个配置都有超过 1 个磁盘时,这简直太糟糕了。

而我要考虑的第二个问题是如何解密(这是本文的重点)。 我们将在下面讨论这个,切入!

大多数情况下,在 Internet 上使用密钥文件(在此之前通过命令 - cryptsetup luksAddKey 自行添加到插槽中),或者在极少数情况下(在俄语 Internet 上信息很少) - decrypt_derived 脚本位于/lib/cryptsetup/script/(当然还有其他方法,但我使用了这两个,它们构成了本文的基础)。 我还努力在重新启动后实现完全自主包含,而无需在控制台中添加任何其他命令,这样一切都会立即为我“飞起来”。 因此,为什么要等待? —

让我们开始吧!

让我们假设一个系统,如 Debian,安装在 sda3_crypt 加密分区和十几个磁盘上,准备好根据您的喜好进行加密和创建。 我们有一个关键短语(密码)来解锁 sda3_crypt,正是从这个分区,我们将从运行(解密)系统上的密码中删除“散列”并将其添加到其余磁盘。 一切都是基本的,在我们执行的控制台中:

/lib/cryptsetup/scripts/decrypt_derived sda3_crypt | cryptsetup luksFormat /dev/sdX

其中 X 是我们的磁盘、分区等。

使用我们的密码短语中的“散列”加密磁盘后,您需要找出 UUID 或 ID - 取决于谁习惯了什么和什么。 我们分别从 /dev/disk/by-uuid 和 by-id 中获取数据。

下一步是为我们需要的功能准备文件和迷你脚本,让我们继续:

cp -p /usr/share/initramfs-tools/hooks/cryptroot /etc/initramfs-tools/hooks/
cp -p /usr/share/initramfs-tools/scripts/local-top/cryptroot /etc/initramfs-tools/scripts/local-top/

进一步

touch /etc/initramfs-tools/hooks/decrypt && chmod +x /etc/initramfs-tools/hooks/decrypt

../解密的内容

#!/bin/sh

cp -p /lib/cryptsetup/scripts/decrypt_derived "$DESTDIR/bin/decrypt_derived"

进一步

touch /etc/initramfs-tools/hooks/partcopy && chmod +x /etc/initramfs-tools/hooks/partcopy

../partcopy 的内容

#!/bin/sh

cp -p /sbin/partprobe "$DESTDIR/bin/partprobe"
cp -p /lib/x86_64-linux-gnu/libparted.so.2 "$DESTDIR/lib/x86_64-linux-gnu/libparted.so.2"
cp -p /lib/x86_64-linux-gnu/libreadline.so.7 "$DESTDIR/lib/x86_64-linux-gnu/libreadline.so.7"

还有一些

touch /etc/initramfs-tools/scripts/local-bottom/partprobe && chmod +x /etc/initramfs-tools/scripts/local-bottom/partprobe

内容../partprobe

#!/bin/sh

$DESTDIR/bin/partprobe

最后,在 update-initramfs 之前,您需要编辑 /etc/initramfs-tools/scripts/local-top/cryptroot 文件,从 ~360 行开始,下面的代码片段


                # decrease $count by 1, apparently last try was successful.
                count=$(( $count - 1 ))
                
                message "cryptsetup ($crypttarget): set up successfully"
                break

并把它带到这个表格

已编辑


                # decrease $count by 1, apparently last try was successful.
                count=$(( $count - 1 ))
                

                /bin/decrypt_derived $crypttarget | cryptsetup luksOpen /dev/disk/by-uuid/ *CRYPT_MAP*
                /bin/decrypt_derived $crypttarget | cryptsetup luksOpen /dev/disk/by-id/ *CRYPT_MAP*

                message "cryptsetup ($crypttarget): set up successfully"
                break

请注意,此处可以使用 UUID 或 ID。 主要是在 /etc/initramfs-tools/modules 中添加了 HDD / SSD 设备必要的驱动程序。 您可以通过命令找出正在使用哪个驱动程序 udevadm 信息 -a -n /dev/sdX | egrep 'looking|DRIVER'.

现在我们已经完成并且所有文件都已就位,运行 更新-initramfs -u -k all -v, 在日志中 不应该 我们脚本的执行错误。 我们重新启动,输入密码并稍等片刻,具体取决于磁盘数量。 接下来,系统将启动,在启动的最后阶段,即“挂载”根分区之后,将执行 partprobe 命令——它将查找并拾取 LUKS 设备和任何阵列上创建的所有分区,无论是 ZFS 还是mdadm,将毫无问题地组装! 而这一切 加载前 需要这些磁盘/阵列的核心服务和服务。

update1: 如何 我注意到 AEP, 此方法仅适用于 LUKS1。

来源: habr.com

添加评论