如何在登录时按用户解密 LUKS 加密设备?

如何在登录时按用户解密 LUKS 加密设备?

我创建了以下[email protected]服务systemd

[Unit]
Description=Cryptography Setup for '%I'
After=cryptsetup-pre.target
After=dev-mapper-%i.device
Before=cryptsetup.target
Before=umount.target
BindsTo=dev-mapper-%i.device
BindsTo=dev-mapper-%i.luks.device
Conflicts=umount.target
DefaultDependencies=no
IgnoreOnIsolate=true
RequiresMountsFor=/home

[Service]
ExecStart=/usr/lib/systemd/systemd-cryptsetup attach '%I.luks' '/dev/mapper/%I' '%h/%I/secret.key' 'luks,header=%h/%I/header'
ExecStop=/usr/lib/systemd/systemd-cryptsetup detach '%I.luks'
KillMode=none
RemainAfterExit=yes
TimeoutSec=0
Type=oneshot

[Install]
WantedBy=default.target

这个想法是仅为特定用户解密某些 LUKS 加密xxx设备xxx.luks,该用户启用该服务,例如:

systemctl --user enable luks@xxx

不幸的是,即使测试它

systemctl --user start luks@xxx

失败,因为它总是返回退出代码1而不说明实际原因。对我来说,很明显问题可能出在权限上。我确信,为了手动触发cryptsetup luksOpen ...,必须抬起外壳,例如使用sudo。确实,如果我发出

sudo systemctl start luks@xxx

它的作用就像一个魅力,同样

sudo systemctl enable luks@xxx

适用于启动阶段。

笔记:
对于这种系统范围的安装,当然需要通过替换%h为给定用户的实际主目录来修改服务,这很丑陋并且无论如何也达不到最终目的。

现在,我知道pam_mount哪个能够在每个用户的基础上进行类似的安装(我无法使用它,因为它不支持分离的 LUKS 标头,并且因为它实际上安装了设备,这是我不想要的),事实上,pam_systemd启动systemctl --user,因此肯定应该有一种方法可以在启动期间为每个用户获取权限以执行设备解密。

顺便说一下,故障症状

systemctl --user enable luks@xxx

甚至比用它进行测试的结果还要糟糕

systemctl --user start luks@xxx

(仅返回退出代码1)。也就是说,我什至无法使用给定用户登录,因为它抱怨

Failed to create bus connection: No such file or directory

因为XDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESS不再设置,而它们应该由服务设置systemd-logind.service。显然,luks@xxx不知何故破坏了整个初始化过程,但由于日志中的信息不足,我无法确切地确定原因。因此,我目前对缺乏权限的怀疑仍然存在。

期待有教育意义的建议。谢谢。

答案1

另一种解决方案是编辑该sudoers文件以添加相关用户的权限,以便在/usr/lib/systemd/systemd-cryptsetup启用 NOPASSWD 选项的情况下以 root 权限运行。

然后,您可以编辑上面的(特定于用户的)服务文件以读取:

ExecStart=/usr/bin/sudo /usr/lib/systemd/systemd-cryptsetup attach '%I.luks' '/dev/mapper/%I' '%h/%I/secret.key' 'luks,header=%h/%I/header'
ExecStop=/usr/bin/sudo /usr/lib/systemd/systemd-cryptsetup detach '%I.luks'

我不确定您是否还必须启用!要求为了这个工作

更新:

为了提高安全性,特别是对于多用户系统,我强烈建议创建几个脚本来代表用户执行“附加”和“分离”步骤,而不是/usr/lib/systemd/systemd-cryptsetup直接授予 sudo 访问权限,否则任何有权运行此命令的用户都可能干扰其他加密卷。

答案2

我建议Type=oneshot RemainAfterExit=yes为用户创建并启用一项服务,该服务使用其ExecStart指令创建文件,并使用其ExecStop指令删除它,例如

ExecStart="/usr/bin/touch %h/.decrypt"
ExecStop="/usr/bin/rm %h/.decrypt"

[email protected]然后,您可以使用绝对路径为系统用户创建并启用单元文件:

PathExists="/home/user/.decrypt"

这将检查上面的用户服务创建的路径,在[email protected]创建该单元时激活该单元,并在删除该单元时停用它,从而建立系统服务对用户服务的间接依赖关系。

请注意,为了安全运行,创建文件的目录当然应该只能由用户写入。

相关内容