![systemd 依赖项是否只能应用于单元的“ExecStart”操作?](https://linux22.com/image/47211/systemd%20%E4%BE%9D%E8%B5%96%E9%A1%B9%E6%98%AF%E5%90%A6%E5%8F%AA%E8%83%BD%E5%BA%94%E7%94%A8%E4%BA%8E%E5%8D%95%E5%85%83%E7%9A%84%E2%80%9CExecStart%E2%80%9D%E6%93%8D%E4%BD%9C%EF%BC%9F.png)
我有一个场景,其中使用可移动加密 USB“密钥环”闪存驱动器上包含的密钥对多个存储卷进行加密。我正在运行 Arch Linux,这个问题是关于 systemd 依赖项配置的。
系统配置为只要存在密钥环,系统就会启动并安装卷。密钥环密码是在启动期间手动输入的。
我希望能够在系统启动后删除 USB 密钥环,但是,我遇到了问题,因为 systemd 卸载了所有内容。
这是我所做的一个例子。第一的,/etc/crypttab
# <name> <device> <password> <options>
keyring PARTLABEL=keyring none noauto
abc /dev/lvm/abc /root/keyring/abc.key header=/root/keyring/abc.hdr
xyz /dev/lvm/xyz /root/keyring/xyz.key header=/root/keyring/xyz.hdr
我正在使用最近的 Git 检出,
systemd
它支持该header
选项;它于 1 月 8 日添加到代码库中。我使用密钥环的分区标签,因为出于备份/方便的原因有多个物理密钥环。它们可能具有不同的 UUID,但使用相同的 PARTUUID 设置。
我正在使用
noauto
,因此密钥环只是任何需要解密的设备的依赖项。
接下来是/etc/fstab
:
# <file system> <dir> <type> <options>
/dev/mapper/keyring /root/keyring ext4 ro,noauto
/dev/mapper/abc /srv/abc ext4
/dev/mapper/xyz /srv/xyz ext4
同样,密钥环之所以noauto
如此安装,只是因为它是依赖项。此外,它以只读方式安装,因此可以安全地将其拉出。
现在,为了创建卷和密钥环之间的依赖关系,我使用了插入覆盖, 例如:
# /etc/systemd/system/systemd-cryptsetup\@abc.service.d/override.conf
[Unit]
Requires=root-keyring.mount
这对于启动来说一切都很好。问题是移除密钥环会停止依赖它的单元。我不希望发生这种情况 - 仅需要依赖项才能在加密卷解锁时使密钥和标头可访问。解锁后,不再需要密钥和标头。
所以,我的问题是问如何安排对仅在“ExecStart”命令持续时间内存在的密钥环的依赖关系[电子邮件受保护]单元?
或者,如果这是错误的方法,任何改进的解决方案都将受到欢迎。
答案1
除了显式依赖之外,也许您可以使用自动挂载。
我记得 Systemd 在Poettering 的最初博客文章,作为一种隐式依赖。这就像您如何(使用 systemd)向套接字写入请求,然后将为您启动适当的服务,即“套接字激活”。在这种情况下,访问文件系统将导致其被挂载。
通过这种方法,您可以预期会阻塞,直到服务或文件系统准备就绪。 笔记:这意味着你的系统将有一个目录,如果你试图查看它(一旦你删除了“钥匙圈”驱动器),它会阻止你......也许如果你曾经使用 /root 做其他事情,那就更好了将其安装在其他地方,例如/automount/keyring
,避免被其绊倒。就我个人而言,我认为此类问题使自动挂载有点令人困惑 - 但它似乎确实可以非常快速地解决您的问题。
如果文件系统在 中列出/etc/fstab
,只需添加x-systemd.automount
到选项列表中即可。
如果它是由本机.mount
文件描述的,则看起来您需要创建一个.automount
同名的文件。例如root-keyring.automount
,包含:
[Automount]
Where=/root/keyring
答案2
在当前的 systemd(撰写本文时为 218)中,一个条目会导致系统启动时 systemd 执行的单元生成/etc/crypttab
一个实例。[email protected]
systemd-cryptsetup-generator
生成的单元包含对密钥文件路径的依赖项:
RequiresMountsFor=/path/to/key_file
这种依赖性记录在man systemd.unit
其中解释它导致Requires=
访问After=
指定路径所需的所有安装的依赖性。
如果挂载单元被停用,该Requires=
依赖性会导致 systemd 停止 cryptsetup 单元。
这意味着卸载包含密钥的设备会导致 cryptsetup 单元停用,并在执行此操作时锁定卷。
目前唯一的解决方法是不使用/etc/crypttab
任何可能出现问题的卷,而是提供不包含RequiresMountsFor=
依赖项的自定义单元。 。这是一个合适的自定义单位,它基于生成器生成的单位:
# /etc/systemd/system/systemd-cryptsetup\@.service
[Unit]
Description=Cryptography Setup for %I
Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:[email protected](8)
DefaultDependencies=no
Conflicts=umount.target
BindsTo=dev-mapper-%i.device
IgnoreOnIsolate=true
After=cryptsetup-pre.target
Before=cryptsetup.target
BindsTo=dev-lvmvg-%i.device
After=dev-lvmvg-%i.device
Before=umount.target
[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutSec=0
ExecStart=/usr/lib/systemd/systemd-cryptsetup attach '%i' '/dev/lvmvg/%i' '/root/keyring/%i.key' 'header=/root/keyring/%i.hdr'
ExecStop=/usr/lib/systemd/systemd-cryptsetup detach '%i'
[Install]
WantedBy=dev-mapper-%i.device
将使用此示例代替此条/etc/crypttab
目:
# <name> <device> <password> <options>
mail /dev/lvmvg/mail /root/keyring/mail.key header=/root/keyring/mail.hdr
这个问题已向 systemd 开发人员提出,并已添加到待办事项清单。