为什么我的 LUKS 分区在不要求密码的情况下被挂载?

wie*_*ede 6 luks cryptsetup raspbian

在我的系统上,我有两个加密磁盘:

  1. 包含 raspbian 拉伸根分区的 crypt
  2. usb-crypt 是一个外部 USB 磁盘。在该磁盘上使用 LVM。

两个磁盘都使用相同的密码保护,但主密钥根据“cryptsetup luksDump”不同。两个磁盘均未使用密钥文件进行配置(每个 LUKS 容器仅使用一个密钥槽)。

当系统启动时,它要求输入密码“crypt”,但 usb-crypt 会自动挂载而不要求输入密码。注意:我从一个未加密的根分区开始,通过该设置,我在启动过程中被要求输入 usb-crypt 的密码。

下面是详细的设置:

$ sudo dmsetup ls --target crypt
crypt   (254, 0)
usb-crypt       (254, 1)

$ sudo cat /etc/fstab
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/mapper/crypt  /            ext4    defaults,noatime  0       1
# ...
UUID=b9fb061f-0877-4d2c-bd3c-9c155b8f88a5       /mountpoint       ext4            rw,auto                 0       0

$ sudo cat /etc/crypttab 
# <target name> <source device>         <key file>      <options>
crypt   /dev/mmcblk0p2  none    luks
usb-crypt       UUID=31fb8df7-6148-4408-90a2-93b8ec752fa0       none    luks
Run Code Online (Sandbox Code Playgroud)

虽然只需要输入一次密码很方便,但我很惊讶看到这种行为。我本来希望被要求提供这两个密码。

这与在两个磁盘上使用相同的密码有关吗?还是U盘的主密钥自动保存在“crypt”的加密根分区的某处?如果有人可以解释这里发生了什么,并可能对相关日志文件等提供一些提示,我将不胜感激。

提前致谢!

fro*_*utz 6

取决于询问您密码的初始化脚本正在使用它做什么。

如果是systemd,它可能只是一个功能。systemd-ask-password带有可能负责的缓存功能。

https://www.freedesktop.org/software/systemd/man/systemd-ask-password.html

--accept-cached

    If passed, accept cached passwords, i.e. passwords previously entered.

--multiple

    When used in conjunction with --accept-cached accept multiple passwords.
    This will output one password per line.
Run Code Online (Sandbox Code Playgroud)

以这种方式,它会首先尝试您已经输入的密码,如果不起作用,则只要求输入另一个密码。

这种想法的缺点是使用 LUKS 检查密码需要 1 秒的 CPU 时间,所以如果你有很多 LUKS 容器,这些尝试可能会减慢你的速度。但是大多数人只有一两个密码,他们使用相同的密码实际上并不少见。

我实际上找不到对此负责的源代码,因此以上只是猜测,我不知道这是否是您可以选择禁用的功能。


找到了似乎是负责任的代码,请在 Github 上查看

有一个 for 循环,每次迭代以 1开始tries = 0并递增tries

这种循环调用get_password()bool accept_cached设置为如果为true tries == 0 && !arg_verify。因此,如果在循环的第一次迭代中已经缓存了密码,它只会返回缓存的密码。如果这些不起作用,tries == 1则将下一次迭代设置accept_cached为 false,然后它才会要求您提供另一个密码来尝试。

密码列表传递给attach_luks_or_plain()。这将是第一次迭代中先前缓存的密码,以及所有后续密码中的单个新密码,因此它不会重试先前尝试过的密码(除非您继续输入相同的密码)。

至于将密码明文保存在内存中,密码列表被声明为 a_cleanup_strv_free_erase_ char **passwords = NULL;以便至少听起来像清理会在某个时候得到妥善处理。

密钥总是在内存中的某个地方,这无济于事,crypt 需要 masterkey 才能工作,只要容器处于打开状态,您始终可以使用dmsetup table --showkeys.


似乎您通常有arg_tries = 33 次尝试输入有效密码,但是如果您有多个容器并且缓存的密码不起作用,它只会给您两次输入密码的尝试,因为缓存的密码尝试已经算作第一次尝试。我没有加密的 systemd 机器来测试这是否属实,或者我只是在某处误读了代码。