打开:cryptsetup 内存不足(“没有足够的可用内存来打开密钥槽。”)

打开:cryptsetup 内存不足(“没有足够的可用内存来打开密钥槽。”)

我正在开发 yocto 发行版,包括 2.3.2 版本中的 cryptsetup

我在具有 1 GB RAM 的主板上运行此类发行版,在尝试打开无法正确调试的加密分区时遇到“内存不足”错误。有任何想法吗?

我的发行版从具有 3 个分区的 mSD 运行;第三个 (30 MB) 是加密的。

我用了ArchLinux 指南中描述的步骤使用 ext3 而不是 ext4 加密该分区

# cryptsetup -y -v luksFormat /dev/sda2
# cryptsetup open /dev/sda2 cryptroot
# mkfs.ext3 /dev/mapper/cryptroot

但尝试在我的主板上打开该分区会引发错误:

cryptsetup --debug open /dev/mmcblk0p3  cryptroot
# cryptsetup 2.3.2 processing "cryptsetup --debug open /dev/mmcblk0p3 cryptroot"
# Running command open.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /dev/mmcblk0p3.
# Trying to open and read device /dev/mmcblk0p3 with direct-io.
# Initialising device-mapper backend library.
# Trying to load any crypt type from device /dev/mmcblk0p3.
# Crypto backend (OpenSSL 1.1.1k  25 Mar 2021) initialized in cryptsetup library version 2.3.2.
# Detected kernel Linux 4.1.35-rt41 ppc.
# Loading LUKS2 header (repair disabled).
# Acquiring read lock for device /dev/mmcblk0p3.
# Opening lock resource file /run/cryptsetup/L_179:3
# Verifying lock handle for /dev/mmcblk0p3.
# Device /dev/mmcblk0p3 READ lock taken.
# Trying to read primary LUKS2 header at offset 0x0.
# Opening locked device /dev/mmcblk0p3
# Veryfing locked device handle (bdev)
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:43e122216ab19330fdfb6d2f9d7b586c4e5189884aef24be884e7159228e9ee5 (on-disk)
# Checksum:43e122216ab19330fdfb6d2f9d7b586c4e5189884aef24be884e7159228e9ee5 (in-memory)
# Trying to read secondary LUKS2 header at offset 0x4000.
# Reusing open ro fd on device /dev/mmcblk0p3
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:4ed9a44c22fde04c4b59a638c20eba6da3a13e591a6a1cfe7e0fec4437dc14cc (on-disk)
# Checksum:4ed9a44c22fde04c4b59a638c20eba6da3a13e591a6a1cfe7e0fec4437dc14cc (in-memory)
# Device size 32505856, offset 16777216.
# Device /dev/mmcblk0p3 READ lock released.
# Only 1 active CPUs detected, PBKDF threads decreased from 4 to 1.
# Not enough physical memory detected, PBKDF max memory decreased from 1048576kB to 255596kB.
# PBKDF argon2i, time_ms 2000 (iterations 0), max_memory_kb 255596, parallel_threads 1.
# Activating volume cryptroot using token -1.
# Interactive passphrase entry requested.
Enter passphrase for /dev/mmcblk0p3:
# Activating volume cryptroot [keyslot -1] using passphrase.
device-mapper: ioctl: 4.31.0-ioctl (2015-3-12) initialised: [email protected]
# dm version   [ opencount flush ]   [16384] (*1)
# dm versions   [ opencount flush ]   [16384] (*1)
# Detected dm-ioctl version 4.31.0.
# Device-mapper backend running with UDEV support enabled.
# dm status cryptroot  [ opencount noflush ]   [16384] (*1)
# Keyslot 0 priority 1 != 2 (required), skipped.
# Trying to open LUKS2 keyslot 0.
# Keyslot 0 (luks2) open failed with -12.
Not enough available memory to open a keyslot.
# Releasing crypt device /dev/mmcblk0p3 context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/mmcblk0p3.
# Unlocking memory.
Command failed with code -3 (out of memory).

答案1

LUKS2用途氩2i密钥派生函数是内存困难的 - 这意味着它需要大量内存才能打开设备以防止(或至少使其更难)使用 GPU 的暴力攻击。您可以检查打开设备需要多少内存cryptsetup luksDump /dev/sda2,查找Memory: 755294下面的行Keyslots

创建设备时,cryptsetup检查可用内存量并相应调整打开所需的内存量,但如果您确实从另一台计算机(例如在桌面上格式化 SD 卡时)甚至在同一台计算机上创建 LUKS 设备机器有更多可用内存,您现在可能没有足够的内存。我们只讨论 RAM,在这种情况下不使用交换。

我建议重新创建 LUKS 设备,以--pbkdf pbkdf2切换到“旧”(LUKS1 中的默认设置)密钥派生函数 PBKDF2,该函数不使用额外的内存。或者,您也可以使用--pbkdf-memory <num>强制减少默认 Argon2i 的内存量。

答案2

Vojtech Trefny 已经解释过,发生这种情况是因为 Argon2i 需要太多内存。确实,从man cryptsetup:

对于 PBKDF2,仅适用时间成本(迭代次数)。对于Argon2i/id,还有内存成本(密钥派生过程中所需的内存)和并行成本(密钥派生过程中并行运行的线程数)。

但是,只要您能够访问具有足够内存1 的硬件,重新创建设备就显得有些过分了。

相反,使用具有足够内存的计算机,只需使用以下命令将密钥添加到加密设备中pbkdf2

cryptsetup luksAddKey -S 1 --pbkdf pbkdf2 /dev/sdxy

假设密钥槽 1 是空闲的(您可以通过检查找到空闲密钥槽cryptsetup luksDump /dev/sdxy)。

然后,在功能较弱的计算机中,使用以下命令解锁设备

cryptsetup luksOpen -S 1 /dev/sdxy name

-S 1是必要的,否则可能会尝试更昂贵的密钥,并且仍然会触发 OOM 杀手。

1:请记住,您始终可以保留一个带有最少外壳和核心实用程序的可启动 USB(Debian ISO 为我剪裁了它),并且您将能够在大多数计算机中启动它并访问您的加密卷。

答案3

除了最重要的答案之外,我还想把它放在这里。使用具有更多内存的计算机,您可以通过以下方式减少现有密钥的内存要求。内存要求以 KB 为单位。如果磁盘上已有数据,这非常有用。

cryptsetup luksConvertKey --key-file /path/to/keyfile --pbkdf-memory=10240 /dev/<device>

答案4

好吧,我在尝试加密我最近购买的 VPS 时遇到了同样的问题。实际上,在我的例子中,在运行# cryptsetup luksFormat /dev/<Partition>求解时遇到了相同的“内存不足”,我重新创建了分区表,如下所示:制作了一个| /dev/sda1 ( EXT4, BOOT ) | /dev/sda2 ( LUKS, ROOT and SWAP ) | /dev/sda3 ( SWAP ) |.

在创建 LUKS 分区时可能有一种方法可以更改一些配置,但可能会变得更不安全,即使只是一点点。

生成的磁盘分区表

分区表 /dev/sda1 /dev/sda2 /dev/sda3
GPT 启动 幸运 交换
左心室容量 不适用 交换/根 不适用

所以我已经将 SWAP 打开了/dev/sda3#swapon /dev/sda3)。然后运行命令:cryptsetup luksFormat /dev/sda2成功。

在 LUKS 内部,我决定创建一个 SWAP,然后创建 EXT4/ROOT。一开始我想放在SWAP之后,但是在删除/dev/sda2并扩展LUKS之后,我必须将SWAP移动到LUKS分区的末尾,然后增加ROOT分区。将SWAP放在LUKS开始,我只需增加根分区即可。

从现在起,我明白如果没有交换,我将不会出现 OOM。我想我需要交换只是为了创造运气。

我已经配置了系统,接下来的步骤是删除/dev/sda3、扩展/dev/sda2留下的可用空间/dev/sda3。增加rootLVM分区。

相关内容