目标
我正在寻找一种非交互方式,以便在下次系统重启时解密根文件分区和使用 LUKS 加密的交换分区。除此之外,我还需要一种方法在重启后撤消它,以便在再次重启后再次需要密码(甚至是新密码)。
系统使用 LVM。
我不想必须在系统上输入密码,或者使用其他系统来解锁它,它必须自行解锁一次。
我有加密密码,愿意将其以明文形式保存在硬盘上。目前我并不担心安全性。
背景
我有一个部署 Ubuntu 的流程,该流程基于带有自定义预置和 kickstart 文件的 Ubuntu 服务器安装,kickstart 会安装一个在第一次重启后(并且仅在第一次重启后)运行的服务,然后再次重启。我试图在这个流程中实现 LUKS 磁盘加密,但我需要它保持非交互性,因此它必须能够在第一次重启时无需密码。
安装时设置的密码是临时的,会被第一次重启后运行的服务更改,因此第一个密码可以以明文形式存储。
在发布这个问题之前我已经研究过的事情
我进行了大量 Google 搜索,试图找出答案,而我发现的大部分结果都指向一个交换 initramfs 文件的解决方案。
我发现有多个资源解释了如何使用此功能来实现远程解锁系统,但我需要在没有交互的情况下完成此操作。以下是其中一个资源:https://hamy.io/post/0005/remote-unlocking-of-luks-encrypted-root-in-ubuntu-debian/
我认为我找到的最接近解决方案的资源是这种资源,它据称是实现我想要的 VPS 解决方案的一种方法,但它只是一堆没有任何解释的命令,而且我不知道如何调整它:https://dradis.com/support/guides/customization/auto-unlock-luks-encrypted-drive.html
我还发现了这个 ArchLinux 资源https://wiki.archlinux.org/index.php/Dm-crypt/System_configuration#cryptkey,我也尝试添加内核参数,但也没有成功。不知道是不是因为 LUKS 不支持这些内核参数。
答案1
解决方案似乎相当简单,在如何配置 LVM 和 LUKS 来自动解密分区?
以下是我如何做到的。请首先注意:
我的
/boot
分区是/dev/sda1
。我想要解密的 LVM 卷是
/dev/sda3
。我是 root,但如果您不是,请将其添加
sudo
到所有命令的前面。
以下是解决方案的实际步骤:
首先设置
keyfile
一个密码(我生成一个伪随机密码):dd if=/dev/urandom of=/boot/keyfile bs=1024 count=4
然后为 root 设置读取权限,但不为其他任何人设置读取权限:
chmod 0400 /boot/keyfile
然后添加
keyfile
作为解锁密钥:cryptsetup -v luksAddKey /dev/sda3 /boot/keyfile
然后系统将提示您输入加密密码。
使用以下命令查找分区的 UUID
/boot
(此命令不需要您是 root 用户):ls -l /dev/disk/by-uuid/
下面是输出的示例(这不是实际输出,因为我从另一台机器上获取的):
$ ls -l /dev/disk/by-uuid/ total 0 lrwxrwxrwx 1 root root 10 Jan 15 03:36 025c66a2-c683-42c5-b17c-322c2188fe3f -> ../../sda2 lrwxrwxrwx 1 root root 10 Jan 15 03:36 9e7a7336-3b81-4bbe-9f1a-d43415df1ccb -> ../../sda1
然后
/etc/crypttab
使用您喜欢的编辑器进行编辑:nano /etc/crypttab
内容看起来会像这样(再次强调,这是来自另一台机器):
sda3_crypt UUID=025c66a2-c683-42c5-b17c-322c2188fe3f none luks,discard
您要做的是,用 替换
none
,/dev/disk/by-uuid/[the uuid of the /boot partition]:/keyfile
并且您想用discard
替换keyscript=/lib/cryptsetup/scripts/passdev
。结果看起来应该是这样的:
sda3_crypt UUID=025c66a2-c683-42c5-b17c-322c2188fe3f /dev/disk/by-uuid/9e7a7336-3b81-4bbe-9f1a-d43415df1ccb:/keyfile luks,keyscript=/lib/cryptsetup/scripts/passdev
保存文件并继续更新
initramfs
:update-initramfs -u
就这样,你现在可以重新启动:
reboot
再次删除它(正如我想要的那样):
首先确认系统上只有两个密钥(原始密钥和新密钥
keyfile
):cryptsetup luksDump /dev/sda3 | grep BLED
这将生成类似如下的输出:
Key Slot 0: ENABLED Key Slot 1: ENABLED Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
要删除密钥槽 1 中的密钥(
keyfile
),请运行:cryptsetup luksKillSlot /dev/sda3 1
然后系统会提示您输入加密密码(原始密码,而不是 中的密码
keyfile
)。然后删除实际的
keyfile
:rm /boot/keyfile
再次更新
initramfs
:update-initramfs -u
现在,当您重新启动时,系统将再次提示您输入密码。您已完成。
答案2
Tobias 的回答很棒,但我想要一些更易于使用的东西。我不想手动完成所有配置工作,而且我想要一种方法来轻松配置我的系统,以便在下次重新启动时无需输入密码,然后自动恢复为需要密码。
我写无钥匙进入实现这两个目标。尽情享受吧!