如何在一个 systemd 单元文件中有条件地执行两个不同的 ExecStart 命令?

如何在一个 systemd 单元文件中有条件地执行两个不同的 ExecStart 命令?

我想要有条件地执行其中之一(或两者)这些命令在单身的系统单元文件:

ExecStart=/usr/bin/ssh-keygen -t rsa -b 4096
ExecStart=/usr/bin/ssh-keygen -t ed25519 -a 32

第一个将在以下条件下执行:

ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key.pub

第二个将在以下条件下执行:

ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key.pub

两把钥匙都可能丢失,或者只有一把钥匙丢失,或者两把钥匙都不丢失。显然,如果密钥存在,我不想重新生成它。我的问题是关于 ssh 密钥,但这些概念应该适用于任何 systemd 单元文件。如果有一种通用方法可以在单元文件中执行此操作,那么它应该在这里工作(我认为)。

背景是:

/usr/lib/systemd/system/sshd.service包括:

Wants=sshdgenkeys.service

标准内容为/usr/lib/systemd/system/sshdgenkeys.service

[Unit]
Description=SSH Key Generation
ConditionPathExists=|!/etc/ssh/ssh_host_dsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_dsa_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_ecdsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_ecdsa_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key.pub

[Service]
ExecStart=/usr/bin/ssh-keygen -A
Type=oneshot
RemainAfterExit=yes

我对该单元文件的问题是当任何一种密钥类型丢失时,所有密钥类型都会重新生成。我计划删除 DSA 和 ECDSA 密钥。所以我只需要检查两种密钥类型,并且我只想重新生成丢失的特定密钥(如果有)。

请建议如何实现这一点。我在这里有一个相关但不同的问题:如何从 systemd 单元文件中删除(不覆盖,不创建新的)选项?。这两个问题是独立的,涉及处理单元文件的不同方面。这个问题是关于有条件地执行不同的命令,另一个问题是关于从单元文件中删除标准选项。

答案1

条件仅适用于整个单位,不适用于其中的个别工作规范。

因此,为了有条件地执行某些作业,这些作业规范应该在执行它们的最终操作之前自行检查。

fe。像这样:(没有测试过,只是网上写的)

ExecStart=bash -c \
'\
  if test ! -f /etc/ssh/ssh_host_rsa_key -o ! -f /etc/ssh/ssh_host_rsa_key.pub; then\
    /usr/bin/ssh-keygen -t rsa -b 4096;\
  fi\
' 'my-rsa-key-gen'
ExecStart=bash -c \
'\
  if test ! -f /etc/ssh/ssh_host_ed25519_key -o ! -f /etc/ssh/ssh_host_ed25519_key.pub; then\
    /usr/bin/ssh-keygen -t ed25519 -a 32;\
  fi\
' 'my-ed25519-key-gen'
1. `$$` 是为了防止 systemd 解释 `$` 本身。\ 来自 `man systemd.service` 部分“命令行”:
要传递文字美元符号,请使用“$$”。
2. 隐式“exit”命令分别是返回“ssh-keygen”的状态并防止设备失败。

为了获得最佳结果和简便性,我建议创建一个外部脚本来在一个地方执行所有条件执行。

相关内容