如何安全地挂载加密容器?
我想加密一堆小文件(比如说我的日记)。锁定后,该文件应显示为包含不可读内容的单个文件。当我解锁它时,它应该被安装为一个文件系统,显示内部的文件和目录,并在容器的根目录下打开一个外壳。 shell 应该能够运行常规程序,如 ls、cat、gedit 或 git。当 shell 退出时,容器也应该被卸载。但是,即使容器已安装,其他进程也不应该看到其内容 - 只有 shell 及其子进程应该能够执行此操作。
有办法做到这一点吗?
答案1
我假设您已经通过 LUKS 设置了一个容器。如果没有,请使用fallocate
(不小于 100MB)创建一个空文件,然后cryptsetup luksFormat
像通常设置 LUKS 卷一样继续操作。
这是(某种程度上)可能的,如果你有root
特权;如果你想保护它免受其他人谁拥有系统的 root 权限。
隔离文件访问的最简单方法是让容器的文件由专用用户帐户拥有 - 您描述的隔离 shell 可以使用打开su otheruser
。然而,我建议完全登录,即并排运行两个图形会话 – 您的普通帐户使用 Ctrl-Alt-F1,您的“私人日记”帐户使用 Ctrl-Alt-F2 – 因为这样会更少尝试授予su
对“主机”X11 或 Wayland 显示器的访问权限时遇到麻烦。
单独的图形会话还具有避免剪贴板泄漏的优点(例如,意外地将日志内容粘贴到 Stack Exchange 帖子中),更重要的是,防止“主机”帐户上的进程窥探您的信息。屏幕内容和键盘输入,这在 Wayland 会话中不是问题,但在 X11 中微不足道。即使“外部”进程无法访问当前加载到 gedit 中的文件,它也可以简单地对 gedit 窗口进行屏幕截图。
(最后,它允许您为两个环境使用不同的 GUI 主题,以避免混淆。)
ext4 中的内置“fscrypt”文件加密功能还可以跟踪每个 UID 加载的密钥。
另一种方法是使用 创建一个新的挂载命名空间unshare
,因为在命名空间内完成的挂载对于“父”命名空间中的进程来说是不可见的。 (这与 Flatpak 或 Docker 等容器用来避免污染主机操作系统挂载列表的机制完全相同。)
outer$ sudo cryptsetup luksOpen ... myluksvol
outer$ sudo unshare --mount --propagation=private su - $USER
inner$ sudo mount /dev/mapper/myluksvol ~/mnt
(退出命名空间中的所有进程将自动卸载仅对该命名空间可见的所有内容,因此安装不会“丢失”。)
您将遇到的一个问题是许多图形程序(例如 )gedit
将启动不是作为 shell 的子进程,但间接作为会话dbus-daemon
或systemd --user
服务管理器的子进程,因此将位于名称空间之外。 (尽管 gedit 特别具有-s
--standalone
禁用此功能的选项。)
为了避免这种情况,您需要dbus-run-session
在 shell 内使用启动一个全新的 D-Bus 会话总线,但这可能有其自身的问题。 (例如,GNOME 用于序列化对 GSettings 数据库的写入的“dconf”服务假定只有一个该服务实例正在运行。拥有第二个会话总线和第二个 dconf 实例可能会损坏 GSettings 数据库。)