在用户登录时安全地自动挂载加密驱动器

当我登录时,我的加密/home目录会自动挂载。我有一块第二个内部硬盘,我用磁盘工具格式化并加密了它。我希望在我登录时它也能自动挂载,就像我的加密/home目录一样。我该如何做到这一点?

这里有几个非常相似的问题,但答案不适用于我的情况。最好关闭/合并我的问题并编辑下面的第二个问题,但我认为它可能已经被放弃了(因此永远不会被标记为接受)。

这个解决方案不是一个安全的方法,它绕过了加密。
这个方法需要编辑fstab,这意味着在启动时需要输入额外的密码。它不像挂载/home那样自动。
这个问题非常相似,但不适用于加密驱动器。这个解决方案对我的需求不起作用。
这里有一个,但它是针对NTFS驱动器的,我的是ext4。

如果解决方案需要的话,我可以重新格式化和重新加密第二个驱动器。我已经将所有数据备份到其他地方了。


你用什么文件系统进行加密?LUKS 还是 ecryptfs? - daisy
@AaronLewis 我只是使用Ubuntu的磁盘工具来格式化驱动器,然后勾选“加密该驱动器”的选项。如果我要猜的话,我会选择ecryptfs,因为这是默认情况下/home文件夹的加密方式。由于操作非常简单,所以我从未深入研究过它。 - Tom Brossman
7个回答

当我几年前写下这个答案时,这是实现解决方案的最佳方式。现在我建议您查看下一个答案,使用mount.ecryptfs_private代替。
我也在寻找一种自动挂载第二个eCryptfs卷的方法。以下一系列脚本和配置修改将安全且自动地在登录时挂载您的卷,无论是GUI还是CLI。
有一个更好的解决方案正在被创建中(尽管我认为它还没有准备好在用户登录时自动挂载,因此这个脚本的使用寿命有限): ecryptfs on too-small harddrive - how to add links into the encryption? 脚本的安全性取决于您的主目录是否使用eCryptfs加密,以便脚本和包含解开密码的文件都得到加密。如果您在登录后将计算机解锁并打开了root shell,则可以访问密码。但是,使用sudo NOPASSWD允许在不需要输入密码或将密码短语留在用户可读取的文件中的情况下安全地挂载分区。
这些脚本的一个已知缺陷是,您的第二个卷在注销时不会被卸载,因此对于多用户系统来说并不特别适用。
我的解决方案由几个部分组成,包括两个shell脚本,一个用于执行实际挂载操作,另一个作为其包装器。
这是包装器脚本,它会验证目录是否已经挂载,如果没有,则会使用sudo调用挂载脚本:
/home/johnf/scripts/automount_ecryptfs
#!/bin/bash

MOUNT_POINT=/home/johnf/slow

grep -q $MOUNT_POINT /proc/mounts
if [ $? -eq 1 ]; then
  sudo /home/johnf/scripts/mount_other_ecryptfs
fi

这个脚本调用/home/johnf/scripts/mount_other_ecryptfs,其内容如下。
请注意,该脚本假设您已启用文件名加密。如果没有启用,您需要修改脚本以处理检测(参考ecryptfs-recover-private),或者可以删除ecryptfs_fnek_sig挂载选项。
以下是/home/johnf/scripts/mount_other_ecryptfs脚本的内容:
#!/bin/bash

ENCRYPTED_VOLUME=/vol0/.ecryptfs/johnf/.Private/
MOUNT_POINT=/home/johnf/slow
PASSFILE=/home/johnf/scripts/ecryptfs_passphrase
MOUNT_PASSWORD=secret_passphrase
ECRYPTFS_SIG=`head -1 ${ENCRYPTED_VOLUME}//../.ecryptfs/Private.sig`
ECRYPTFS_FNEK_SIG=`tail -1 ${ENCRYPTED_VOLUME}//../.ecryptfs/Private.sig`

printf "%s" $MOUNT_PASSWORD | ecryptfs-insert-wrapped-passphrase-into-keyring ${ENCRYPTED_VOLUME}/../.ecryptfs/wrapped-passphrase
mount -t ecryptfs -o key=passphrase:passfile=${PASSFILE},ecryptfs_sig=${ECRYPTFS_SIG},ecryptfs_fnek_sig=${ECRYPTFS_FNEK_SIG},ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n ${ENCRYPTED_VOLUME} ${MOUNT_POINT}

你还需要创建一个包含密码的文件,这个文件将被eCryptfs挂载命令使用:
/home/johnf/scripts/ecryptfs_passphrase:
passwd=secret_passphrase

你需要修改几个文件的权限:
chmod +x /home/johnf/scripts/automount_ecryptfs
sudo chown root:root /home/johnf/scripts/mount_other_ecryptfs /home/johnf/scripts/ecryptfs_passphrase
sudo chmod a=x /home/johnf/scripts/mount_other_ecryptfs
sudo chmod 400 /home/johnf/scripts/ecryptfs_passphrase

在创建脚本之前,您需要创建一个sudoers配置文件,以允许使用sudo执行挂载脚本而无需输入sudo密码。
将以下内容添加到/etc/sudoers(或/etc/sudoers.d中的文件)。您需要将johnf替换为您的用户名。必须使用绝对路径指定挂载脚本。
johnf   ALL = NOPASSWD: /home/johnf/scripts/mount_other_ecryptfs

最后一步是在登录时调用automount_ecryptfs脚本。
在Ubuntu Unity(和可能的gnome)上,使用"启动应用程序"小程序创建一个新的启动程序,调用/home/johnf/scripts/automount_ecryptfs。
为了在登录时自动挂载第二个eCryptfs卷到bash shell,您需要修改您的~/.bashrc文件。添加以下内容:
/home/johnf/scripts/automount_ecryptfs

有了这个配置,你现在应该可以自动挂载你的第二个 eCryptfs 卷了。

哇,太棒了!点赞并接受了。虽然还不能测试,但看起来非常完整。 - Tom Brossman
mount.ecryptfs_private 的作者现在建议使用 ecryptfs-mount-private,也是由他编写的一个包装脚本,用于执行 mount.ecryptfs_private。https://thesimplecomputer.info/encrypt-your-linux-home-folder-2-ways-and-10-steps 可能值得一读,以了解 ecryptfs 和 LUKS 的相对优点。 - mc0e

在@johnf的回答基础上,使用mount.ecryptfs_private进行如下操作:
  • /home/bob/(例如在SSD上)进行加密,使用Ubuntu的普通加密家目录功能。
  • /media/hdd/bob_extra/(例如在HDD上)进行加密,将其挂载到/home/bob/extra。这应该在登录时自动挂载,就像家目录一样。
  • 使用相同的密钥/凭据。

创建它

mkdir /media/hdd/bob_extra
cp /home/bob/.ecryptfs/Private.sig /home/bob/.ecryptfs/extra.sig
echo "/media/hdd/bob_extra /home/bob/extra ecryptfs none 0 0" > /home/bob/.ecryptfs/extra.conf

测试一下
mount.ecryptfs_private extra

运行mount命令,你应该看到:
...
/media/hdd/bob_extra on /home/bob/extra type ecryptfs (ecryptfs_check_dev_ruid,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_unlink_sigs,ecryptfs_sig=12345678abcdef,ecryptfs_fnek_sig=abcdef12345678)

卸载:
sudo umount /media/hdd/bob_extra

设置自动挂载
创建/home/bob/bin/automount_ecryptfs.extra,如果尚未挂载,则将其挂载。
#!/bin/bash

MOUNT_POINT=/home/bob/extra

grep -q $MOUNT_POINT /proc/mounts
if [ $? -eq 1 ]; then
  mount.ecryptfs_private extra
fi

将其设置为可执行(chmod +x),然后将其添加到/home/bob/.bashrc中:
...
/home/bob/bin/automount_ecryptfs.extra

然后也将其添加到Gnome的启动应用程序中。

+1 感谢您的回答。我现在有一个更复杂的设置,包括多个固态硬盘和符号链接到共享驱动器,所以我无法测试这个。我希望将来加密多个硬盘会像加密/home 一样简单。 - Tom Brossman
另请参阅ecryptfs-mount-private,它更加功能齐全。例如,它可以自动使用用户密钥环中的密钥。 - mc0e
1这个答案是关于挂载一个eCryptfs私有目录的。问题是关于使用“磁盘”工具创建的LUKS分区的挂载。 - Victor

你不再需要上面的解决方案。

先决条件:

注意:这种方法比手动挂载加密驱动器更不安全。如果有人可以物理访问您的计算机,您对根密码不小心,或者您的计算机有多个用户/访客账户,这种方法是不安全的;次要驱动器在您注销但不关闭系统时仍然挂载,因此其内容对其他用户可见。

第一部分:加密次要驱动器。

  1. 在Unity Dash中键入“disks”,然后按Enter键。
  2. 在“设备”下方,点击要加密的硬盘。
  3. 在“卷”下方,点击齿轮/更多操作按钮。
  4. 点击“格式化卷”。选择“与Linux系统兼容的加密”作为类型。给驱动器命名并设置一个强密码。
  5. 点击“格式化”
第二部分:在系统启动时自动挂载硬盘。
1. 保持“Disks”应用程序打开,并点击齿轮图标。 2. 点击“编辑加密选项”。 3. “自动加密选项”将被打开,并且下方的菜单将变灰。关闭自动加密选项。 4. 输入您格式化磁盘时设置的密码。点击“确定”。
现在,您拥有一个加密的硬盘,在计算机启动时会自动挂载。

1虽然我相信有人会对这个有用,但它并不是问题的答案,因为问题明确指定了次要挂载应该在用户登录时发生,而不是系统启动时。这使得最初声称“你不再需要上述解决方案”的说法不合适,我邀请作者相应地重新措辞答案。 - mc0e
2我认为你在这里是错误的。也就是说,次要挂载确实发生在用户登录时(仅限于我提到的操作所涉及的帐户),而不是在之前的第二个时间点。当我妻子在同一台计算机上登录她的Ubuntu帐户时,驱动器没有被挂载。如果她尝试挂载它,系统会要求输入加密密钥。我坚持认为,你不需要上面的答案。 - tryion
1同意,这绝对是目前最简单的方法,因为我是该机器上唯一的用户。这对每个人都不适用,但如果你安装了Ubuntu并且是主要/管理员用户,那就可以这样做。现在应该有一个大的“使其与加密的/home完全一样”复选框,这是一个简单的使用案例。 - Tom Brossman
1@tryion 在系统启动时,LUKS分区会被解锁,但不会被挂载。因此,一旦计算机开机,该分区就像一个未加密的分区一样容易访问。密码以明文形式存储在“/etc/crypttab”中。无需用户密码即可访问该分区。因此,这个设置等同于根本没有加密,并不能解答问题。 - Victor
有没有使用libsecret将其存储在其他位置以供特定用户解密的选项,以及是否有适用于非GUI/无头用户的CLI指南? - MrMesees

在您的加密主目录中创建一个脚本:~/scripts/mount_storage.sh
#!/bin/bash

sudo cryptsetup open --type luks UUID=12e26119-0ee2-4eb4-bd40-d8a3547ecf0c storage --key-file ~/keys/storage_keyfile
sudo mount /dev/mapper/storage /storage

添加到“启动应用程序”:
sh ~/scripts/mount_storage.sh

添加到/etc/sudoers文件中:
%sudo   ALL= NOPASSWD: /sbin/cryptsetup open --type luks UUID=12e26119-0ee2-4eb4-bd40-d8a3547ecf0c storage --key-file *
%sudo   ALL= NOPASSWD: /bin/mount /dev/mapper/storage /storage

你需要创建 /storage 挂载点,并在上述脚本中更改 UUID(使用 blkid 命令查找)。

有没有一种简单的方法,可以在插入USB时运行这样的脚本? - naught101
我自己没有尝试过,所以不能确定,但我不认为会有问题。您需要创建一个针对特定USB设备的udev规则,并运行上述脚本。例如,这篇帖子可能是一个起点。 - Raul Laasner

按照以下步骤进行应该是安全的。要求输入密码可以阻止其他用户访问卷,即使它已经挂载。
1. 打开Disks,选择驱动器并点击LUKS卷。点击齿轮图标,取消选择"User Session Defaults"。选择"系统启动时解锁"和"需要额外授权才能解锁": enter image description here 2. 点击磁盘卷(在LUKS卷下方)。点击齿轮图标,取消选择"User Session Defaults"。选择"系统启动时挂载"和"在用户界面中显示": enter image description here 您也可以选择要求额外的身份验证来挂载卷,但在这种情况下,对于相关用户来说,挂载将不会自动进行。

这应该是被接受的答案——它简单而且有效。 - moomima

很抱歉,这个答案可能不会受到欢迎...
没有办法在不绕过加密本身的安全性的情况下自动挂载任何加密分区。
想一想“自动”是什么意思,并且要明白“自动”也意味着他们会看到你的数据。

我在主观上使用了“Securely”,我可以从问题中删除它。我只是希望在登录时挂载加密的照片驱动器,就像/home一样。我知道这在理论上是可能的,因为我有一个作为Déjà Dup目标的第三个(也加密的)驱动器。只有当备份工具启动时,该驱动器才会被挂载。完全自动化,我已经保存了密钥,所以不需要每次都输入。在登录屏幕输入密码后,我对自动处理所有密钥感到满意。有什么办法可以实现这个吗?谢谢。 - Tom Brossman
3在这个上下文中,自动化意味着在输入登录密码后应该挂载。您的登录密码可以是您加密分区的钥匙,或者更常见的是钥匙的钥匙。只要您设置一个强大的登录密码,这是相当安全的。 - Javier Rivera
它不会自动挂载到另一台计算机上,这就是为什么我们大多数人加密一些磁盘的原因。在我的情况下,这是我用来备份的磁盘。我在一个共享空间工作,知道你们其中一个具有很多知识的人可以通过物理访问我的磁盘/计算机来绕过我所做的任何事情:我只是想减少他人对我的文件的可访问性,以便其他人无法做到。 - Ramon Suarez
通过将其变成自动过程,有可能让窃取你电脑的人能够访问到你加密的额外硬盘的密钥吗?(然后当然可以挂载和访问这个硬盘) - miguelfg
简单明显的情景:我在办公室将USB驱动器插入服务器以备份数据。我把USB驱动器带回家以确保在服务器发生意外情况时进行离线备份。当我在回家途中去商店时,有人闯入我的车并拿走了USB盘。现在他们必须要知道1)服务器的位置,以及2)闯入办公室来解密该磁盘。这一部分要比“只需将其插入他们家的计算机”难得多。 - Ernie
现在安装Linux到加密分区已经变得非常容易,所以这个答案的意义更少了。如果你的Linux安装是加密的,并且当你离开时电脑会锁定,那么你的密钥文件实际上是无法访问的,即使有物理接触(除非有人能够拆解电脑并在其仍然通电的情况下直接读取RAM,但在大多数情况下这似乎是非常不可能的)。 - naught101

关于rcoup's anwser的更新:

  • 根据mount.ecryptfs_private的手册,如果文件夹已经挂载,它将不会执行任何操作,因此检查这一点是没有用的;
  • 使用systemd可能更合适,它可以自动运行,独立于bash或图形会话,并且还提供了一个方便的方式,在会话结束时明确卸载。

所以我们可以执行systemctl --user edit --force --full mount-ecryptfs-extra.service:这将打开一个编辑器,在其中我们可以输入以下内容

[Unit]
Description=Mount ecryptfs folder extra

[Service]
Type=oneshot
ExecStart=mount.ecryptfs_private extra
RemainAfterExit=yes
ExecStop=umount.ecryptfs_private extra

[Install]
WantedBy=default.target

然后执行systemctl --user install mount-ecryptfs-extra.service命令。