systemd 依赖项是否只能应用于单元的“ExecStart”操作?

systemd 依赖项是否只能应用于单元的“ExecStart”操作?

我有一个场景,其中使用可移动加密 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 开发人员提出,并已添加到待办事项清单

相关内容