在启动时使用单个密码短语来解锁多个加密磁盘


23

我的机器有一个SSD(用于安装系统)和一个HDD(用于存储大型和/或不经常使用的文件)。两者都是加密的,但是我选择对它们使用相同的密码。SSD安装在/HDD 上,HDD 安装在/usr/hdd(每个用户都有一个目录,可以根据需要从主目录进行符号链接)。

系统启动后,立即要求输入SSD密码,仅几秒钟后输入HDD密码(自动安装)。鉴于两个密码短语都相同,是否可以将系统配置为只询问一次?


您可以编写一个expect脚本或类似脚本来调用它来挂载磁盘,而不是由系统来执行。取而代之的是,系统将调用脚本,该脚本将要求输入密码,进行存储并将其提供给每个安装操作。
h3rrmiller

如果我正确理解您的想法,则无法将其应用于SSD,因为这是系统引导的来源。但这变得毫无意义,因为我仍然需要分别输入HDD的密码。或者没有?
2017年

您可以/etc/crypttab 用来解锁第二个驱动器
jasonwryan

1
@jasonwryan如果可以扩展为答案,则...答案应发布为答案,而不是评论。
derobert

1
@derobert有时人们没有时间或倾向来写一个好的答案。
jasonwryan

Answers:


24

基于Debian的发行版:

Debian和Ubuntu 附带了带有cryptsetup软件包的密码缓存脚本cryptol_keyctl

crypto_keyctl脚本为多个加密的LUKS目标提供了相同的密码,从而使您无需多次键入密码。可以在带有选项的crypttab中启用keyscript=decrypt_keyctl。相同的密码用于在keyfile字段中具有相同标识符的目标。在启动时,每个标识符的密码将被询问一次。

crypttab示例:

<target>      <source>         <keyfile>      <options>
part1_crypt   /dev/disk/...    crypt_disks    luks,keyscript=decrypt_keyctl
part2_crypt   /dev/disk/...    crypt_disks    luks,keyscript=decrypt_keyctl

更新cryptab之后,还必须更新initramfs来应用更改。使用update-initramfs -u

关于delete_keyctl的完整自述文件位于 /usr/share/doc/cryptsetup/README.keyctl

不幸的是,由于存在错误,当前在使用systemd init的Debian系统上不起作用(其他init系统应不受影响)。作为解决方法,Debian crypttab手册页建议initramfs在启动的initramfs阶段使用选项来强制处理。


不提供decrypt_keyctl脚本的发行版:

如果您的发行版未提供crypto_keyctrl,则可以使用加密的根文件系统中的密钥文件来解锁设备。根文件系统可以在任何其他加密设备之前被解锁和挂载的情况。

LUKS支持多个按键槽。如果密钥文件不可用/丢失,您可以使用密码来解锁设备。

  1. 生成具有随机数据的密钥,并将其权限设置为所有者可读,以免泄露。请注意,密钥文件必须位于首先解锁的根分区上。

    dd if=/dev/urandom of=<path to key file> bs=1024 count=1
    chmod u=rw,g=,o= <path to key file>
    
  2. 将密钥添加到您的LUKS设备

    cryptsetup luksAddKey <path to encrypted device> <path to key file>
    
  3. 配置crypttab以使用密钥文件。第一行应该是根设备,因为设备的解锁顺序与crypttab中列出的顺序相同。对密钥文件使用绝对路径。

    <target>      <source>         <keyfile>                  <options>
    root_crypt    /dev/disk/...    none                       luks
    part1_crypt   /dev/disk/...    <path to key file>         luks
    

从自述文件的第一行看,它看起来很有希望,谢谢。我明天再检查一次(现在不想重新启动)。
2017年

不幸的是,它不起作用(不变)。在中查看我的crypttab(我没有碰到UUID=系统安装程序创建的,我想应该没关系)和产生的条目/var/log/syslog。这些错误是可以理解的,但是我不知道该如何处理。文件/lib/cryptsetup/scripts/decrypt_keyctl存在,所以我不知道为什么它抱怨未知的选项。我也不知道该指定什么作为密钥文件,我什么地方也看不见任何解释……
doublep

您是否验证了initramfs中包含了decrypt_keyctl?更新图像时使用verbose选项进行检查:update-initramfs -u -k $(uname -r) -v,应输出Adding binary /lib/cryptsetup/scripts/decrypt_keyctl
sebasth

1
要查看initramfs包含的内容:lsinitramfs /boot/initrd.img-$(uname -r)
sebasth

3
嗯,很抱歉,现在我更加注意了update-initramfs所说的话,我注意到了:E: /usr/share/initramfs-tools/hooks/cryptkeyctl failed with return 1.。经过一番谷歌搜索,我发现我可能需要keyutils软件包(确实没有安装)。现在update-initramfs成功并lsinitramfs提及decrypt_keytls。将在下次启动后更新(可能在明天)。
2017年

3

考虑到@sebasth上面提到的错误,这是我对debian的解决方法。

我的设置略有不同。我有一个加密的根分区和一堆RAID磁盘。对我来说,我必须在crypttab中添加一个initramfs选项:

<target>      <source>         <keyfile>      <options>
part1_crypt   /dev/disk/...    crypt_disks    plain,cipher=aes-xts-plain64,keyscript=decrypt_keyctl,initramfs
part2_crypt   /dev/disk/...    crypt_disks    plain,cipher=aes-xts-plain64,keyscript=decrypt_keyctl,initramfs

这告诉update-initramfs我想将这些crypttab条目安装在initramfs中。我通过运行检查了我的crypttab

cryptdisks_start part1_crypt
cryptdisks_start part2_crypt

请注意,我的RAID磁盘是普通的dm-crypt。这意味着我无法使用可解决systemd keyscript错误的luks keyfile方法。对于纯dm-crypt,我必须将密码存储在纯文本中。

必须先安装加密的磁盘,然后才能update-initramfs运行。否则会引发错误。建立initramfs时,我必须寻找以下几行:

update-initramfs -k -u -v | grep 'keyctl'

其中显示了以下两个文件:

/bin/keyctl
cryptkeyctl

被添加到initramfs。

最后,我不得不禁用systemd处理我的crypttab,以处理上面提到的错误:systemd不支持crypttab中的keyscript选项。为此,我添加了内核选项

GRUB_CMDLINE_LINUX_DEFAULT="quiet luks.crypttab=no"     

到/ etc / default / grub并运行update-grub。现在,systemd将忽略crypttab,并且所有加密分区都将加载到initramfs中。

因为我有一个加密的根分区,所以cryptroot似乎没有缓存我的密钥。这意味着我必须输入两次密码。一个用于根分区,一次用于我的raid数组。


1

另一个选择是使用/lib/cryptsetup/scripts/decrypt_derived脚本,它也是Debian / Ubuntu中cryptsetup的一部分。

不用缓存密钥,而是将一个磁盘的卷密钥用作第二个磁盘的附加密码。这需要向第二个(和第三个等)加密磁盘添加第二个密码,但是LUKS支持该密码。因此,如果您的多个加密磁盘不使用相同的密码,则此解决方案也适用。

将密钥从sda6crypt添加到sda5的示例:

添加sda6crypt的卷密钥作为sda5的附加密码:

mkfifo fifo
/lib/cryptsetup/scripts/decrypt_derived sda6crypt > fifo &
cryptsetup luksAddKey /dev/sda5 fifo
rm fifo

将sda5crypt配置为在中自动解锁 /etc/crypttab

ls -la /dev/disk/by-uuid/ | grep sda5
echo "sda5crypt UUID=<uuid> sda6crypt luks,initramfs,keyscript=/lib/cryptsetup/scripts/decrypt_derived" >> /etc/crypttab

这使用命名管道(fifo)传递密钥,以避免必须将卷密钥存储在磁盘上的临时文件中。

keyscript选项仅在crypttab由Debian的原始cryptsetup工具处理时才有效,systemd重新实现当前不支持该选项。如果您的系统使用systemd(大多数系统),那么您需要initramfs选择在systemd启动之前通过cryptsetup工具强制在initrd中进行处理。

基于/unix//a/32551/50793


一定要说这是一个漂亮的解决方案在debian 10 buster上毫不费力地工作了!
Janus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.