自从最近从 20.04 更新到 20.10 以来,cryptsetup 无法打开 luks 容器。
讯息是:
> Cannot use twofish-ecb cipher for keyslot encryption. Keyslot open
> failed. No usable keyslot is available.
- 我能够在 Ubuntu 20.04 下打开并编辑 luks 容器。
- 自升级后才失败。
- 我仍然可以在 Fedora 下打开和编辑 luks 容器。数据在 Fedora 下仍然可用,并且 luks 容器本身也很好。
伊斯卢克斯
为正数,
cryptsetup -v luksDump /dev/sdx3
带来预期的结果,完美。
问题:
sudo cryptsetup luksOpen /dev/sdx3 luks-61[...]51
成功请求并接受密码,然后失败
> Cannot use twofish-ecb cipher for keyslot encryption.
> Keyslot open failed.
> No usable keyslot is available.
随后 /dev/mapper 不会显示此 luks 映射,但其他 luks 映射仍可正常工作。
/dev/sdx 的唯一特殊之处是:它是一个 btrfs/gpt 磁盘。在升级之前,Ubuntu、Fedora、Suse 都可以正常工作。事件发生后,在 Fedora 32 下调整大小可以正常工作,没有任何问题(缩小 gpt/btrfs/LUKS 分区尤其有用)。
在 Ubuntu 20.04 下曾经运行良好(直到升级到 20.10 后重新启动)。
升级之前 kern.log 中没有问题:
Oct 18 16:14:47 kurt kernel: [ 24.243562] BTRFS: device label bxxxxxxxx_crypt devid 1 transid 612 /dev/dm-2
Oct 18 16:14:47 kurt kernel: [ 24.269818] BTRFS info (device dm-2): use zlib compression, level 3
Oct 18 16:14:47 kurt kernel: [ 24.269820] BTRFS info (device dm-2): disk space caching is enabled
Oct 18 16:14:47 kurt kernel: [ 24.269821] BTRFS info (device dm-2): has skinny extents
比较其他风格:与 U20.10 的版本:cryptsetup 2.3.3(但是不起作用)与 Suse 15.1、cryptsetup 2.0.6 一起使用,与 Fedora 32、cryptsetup 2.3.4 一起使用,并且据我所知曾与 U20.04、cryptsetup 2.2.2 一起使用。
为什么它在 Ubuntu 20.10 下失败?我该怎么做才能修复它?
答案1
虽然不是明确的答案,但您的 initramfs 缺少加密模块。今天我自己也遇到了这个问题,方式略有不同,但结果相同(因此我偶然发现了这篇文章):
Cannot use serpent-xts cipher for keyslot encryption.
Keyslot open failed.
发生这种情况时,内核 dmesg 和 cryptsetup 都可疑地没有任何消息。遗憾的是,我无法告诉你你的情况是缺少哪个模块,但就我的情况而言是缺少模块cryptd
。
我认为磁盘布局、cryptsetup 甚至特定内核版本都不是问题所在。最可能的原因是 Debian/Ubuntu 系统在内核升级时生成 initramfs 的方式。以下是内核 (dist-) 升级失败的原因:
apt
安装新的主要内核版本update-initramfs
使用当前加载的模块来收集系统挂载根文件系统所需的所有模块- 因为您的系统当前正在运行旧内核,所以此列表不包含(A)任何新模块,或(B)当前模块(或已重命名的模块等)的新依赖项
- 你的系统顺利地启动了新内核,但 initramfs 中的模块集不完整
通常,当模块缺少某些依赖项时,您会看到“未解析符号”错误。但是,内核加密 API 为所有加密算法提供了通用接口,因此即使缺少特定算法,符号也在那里。更糟糕的是,如果请求的算法不可用,内核加密解析器不会记录任何警告。
怎么修?
首先,使用旧内核启动新系统。Debian 始终确保您可以在以前的内核上运行当前用户空间,我想 Ubuntu 也是如此。
使用以下命令(或类似命令)查看内核版本之间的所有模块变化(所有内容都在一行上,我将命令拆分以便于阅读):
diff <(cd /lib/modules/$OLD_KERNEL_VERSION/ && find . -type f) \
<(cd /lib/modules/$NEW_KERNEL_VERSION/ && find . -type f)
以 开头的行>
表示只存在于新内核的模块。考虑到错误,可以肯定的是,缺少的模块是加密模块,因此您可以添加| grep /crypto/
以缩小列表。
/etc/initramfs-tools/modules
一旦您确定了可能的嫌疑人,您可以通过将它们添加到(每行一个)并运行update-initramfs -u -k all
以重新生成 initramfs,强制将它们包含在 initramfs 中。
它仍然不起作用
这里的方法仅涵盖上述情况 (A),即您缺少一个模块,因为它不存在于旧内核中。情况 (B) 实际上没有直接的解决方法。您可以做出有根据的猜测,或者简单地将所有加密模块添加到/etc/initramfs-tools/modules
,然后希望获得最佳效果。但最好确保您已在 USB 上准备好 Ubuntu 安装程序以使用其救援模式(第二项,该页面没有锚点)使用正确的内核版本启动您的系统。