#!/bin/sh
set -e
if [ ! -e /sdboot ]; then
mkdir -p /sdboot
sleep 3
fi
if mount /dev/mmcblk0p1 /sdboot >/dev/null; then
if [ -e /sdboot/$CRYPTTAB_KEY.lek ]; then
cat /sdboot/$CRYPTTAB_KEY.lek
umount /sdboot
exit
fi
umount /sdboot
fi
/lib/cryptsetup/askpass "Insert key or enter passphrase: "
我一直在苦苦寻找解决这个问题的方法,直到这个答案提醒了我
dropbear-initramfs
。这似乎是迄今为止最简单的解决方案。只需在 中安装一个 SSH 服务器即可initramfs
。以下是我遵循的步骤,以使它正常工作。所有命令都必须以超级用户身份运行,
sudo -s
以打开 root shell。标有█ 的步骤可能需要使用特定于您情况的数据更改命令或文件内容。
准备
initramfs
将系统安装到 SD 卡上(我使用了 Raspberry Pi Imager),插入树莓派并启动。运行以下命令更新系统:
安装
dropbear-initramfs
并busybox
:█添加您的 SSH 公钥,
/etc/dropbear/initramfs/authorized_keys
以便在 SSH 服务器运行后能够访问它。您可以从您的机器上复制密钥:并将其粘贴到 RPi 上的相应文件中:
█编辑文件
/etc/initramfs-tools/initramfs.conf
,使 initramfs 从 DHCP 获取 IP 地址。找到文件末尾,添加:替换
<hostname>
为 Pi 应具有的主机名。SSH 可能会因为 Pi 不断更改签名而感到恼火。如果实在不行,可以参考这个答案。
编辑
/etc/initramfs-tools/modules
以添加 LUKS 和加密所需的内核模块initramfs
。在文件末尾添加以下内容:initramfs
通过创建/etc/initramfs-tools/hooks/luks_hooks
以下内容来添加用于处理文件系统的工具:不要忘记使其可执行:
更新
initramfs
以应用所有这些更改:█您可以
initramfs
使用以下命令验证是否具有所有必要的工具和模块。它应该打印:
和
应该打印:
对我来说,
<...>
是6.8.0-1020-raspi
,我猜是内核版本。不过,您的版本可能有所不同。请注意,在上述所有命令中,请将其替换为您的版本。准备启动
生成用于加密的密钥并将其放置在 中
/boot/firmware
,因为这是一个可从 轻松访问的位置initramfs
:编辑
/etc/fstab
以使用我们将在几个步骤中创建的加密卷。将第一行更改为:更新
initramfs
,忽略其可怕的警告:编辑
/boot/firmware/cmdline.txt
:root=LABEL=writable
为root=/dev/mapper/rootfs
cryptdevice=/dev/mmcblk0p2:rootfs
在行尾添加break=init
有些文章建议你在行尾也添加,但如果你这样做,它会跳转到initramfs
两次,第一次是因为无法启动,第二次是因为你需要它。问题是,dropbear 第二次启动不了。所以如果你在无头模式下操作,就不要这么做。Ubuntu 桌面版似乎也有
splash
参数cmdline.txt
,应该将其删除,因为启动画面根本无法帮助您完成此操作。现在您终于可以重新启动了:
rootfs
就地加密initramfs
█你的树莓派现在应该已经启动,
initramfs
并且会通过 DHCP 从路由器获取 IP 地址。如果你不知道这个 IP 地址,可以登录路由器查看。之后,你就可以开始使用 SSH 登录 initramfs 了:(如果您的 SSH 私钥存储在其他位置,请务必调整命令)
进入后
initramfs
,挂载system-boot
分区:检查并修复
rootfs
(e2fsck
此步骤是必需的):缩小
rootfs
以为 LUKS 标头腾出空间:█
rootfs
使用以下方法进行就地加密cryptsetup reencrypt
(这将花费一些时间,具体取决于 SD 卡的大小及其性能等级,对我来说,64 GB 的加密需要 40 分钟):█加密完成后,解锁加密的
rootfs
:扩展
rootfs
以填充整个分区:此时,您可以尝试安装
rootfs
以查看一切是否正常工作:如果任何命令的输出不正确,请回溯您的步骤。
█此时,尽管
/dev/mapper/rootfs
已经存在,但 Pi 不会尝试切换到它。为此,请先重启 Pi:然后,无需等待太长时间,按照本节第 1 步的操作进行连接,然后
rootfs
再次解锁:你应该得到类似的东西
解锁后 2-3 秒内
rootfs
。如果无效,请重试,但要更快。此后,Pi 将启动到rootfs
。恢复正常启动
由于 Debian 的 crypttab 实现似乎不支持直接从设备读取密钥文件,您可以使用“keyscript”来执行此操作。创建
/lib/cryptsetup/scripts/unlock
以下内容:此脚本将尝试将
system-boot
SD 卡的分区挂载到 ,/sdboot
并使用 传递给它的密钥文件名crypttab
在该分区上查找正确的密钥system-boot
。然后,它会将文件内容转储到标准输出 (stdout),并将其解释为密钥文件的内容。/sdboot
挂载点仅存在于 中initramfs
,不会成为 的一部分rootfs
。不要忘记使其可执行:
█添加一个条目以在启动时自动
/etc/crypttab
解锁:rootfs
更新
initramfs
以应用更改:重启测试:
此时,您可以根据自己的喜好修改设置。例如,您可能想将密钥文件移动到 U 盘上,并相应地修改脚本。我有一个GitHub Gist,其中包含有关如何操作的详细说明。或者,您可以切换到基于密码的解锁方式,并将密钥作为备份。关键在于,您现在拥有一个可以启动并可以执行任何操作的系统。
我的建议是,如果您切换到基于 USB 驱动器的解锁,则更改加密密钥(因为如果擦除不当,写入 SD 卡的密钥仍然可以读取),并使用设备 UUID(您可以使用查看它们
blkid
)而不是/dev/<whatever>
样式块设备规范,因为 UUID 不依赖于系统。