systemd:mkdir 和 ExecStartPre 的权限问题

systemd:mkdir 和 ExecStartPre 的权限问题

我的这个(缩短的)systemd 服务文件有问题:

[Unit]
Description=control FOO daemon
After=syslog.target network.target

[Service]
Type=forking
User=FOOd
Group=FOO
ExecStartPre=/bin/mkdir -p /var/run/FOOd/
ExecStartPre=/bin/chown -R FOOd:FOO /var/run/FOOd/
ExecStart=/usr/local/bin/FOOd -P /var/run/FOOd/FOOd.pid
PIDFile=/var/run/FOOd/FOOd.pid

[Install]
WantedBy=multi-user.target

食物是用户名并且FOO组名称,该名称已存在于我的 daemon 中/usr/local/bin/FOOd

我需要在通过/var/run/FOOd/启动守护进程之前创建目录。这会失败,因为 mkdir 由于权限而无法创建目录:/usr/local/bin/FOOd# systemctl start FOOd.service

...
Jun 03 16:18:49 PC0515546 mkdir[2469]: /bin/mkdir: cannot create directory /var/run/FOOd/: permission denied
Jun 03 16:18:49 PC0515546 systemd[1]: FOOd.service: control  process exited, code=exited status=1
...

为什么 mkdir 在 ExecStartPre 时失败以及如何修复它? (不,我不能使用 sudo 来执行 mkdir...)

答案1

你需要添加

PermissionsStartOnly=true

[Service]。您的用户FOOd当然无权在/var/run.引用手册页:

采用布尔参数。如果为 true,则使用 User= 和类似选项配置的与权限相关的执行选项(有关详细信息,请参阅 systemd.exec(5))仅应用于使用 ExecStart= 启动的进程,而不应用于其他各种 ExecStartPre= 、ExecStartPost=、ExecReload=、ExecStop= 和 ExecStopPost= 命令。如果为 false,则该设置将以相同的方式应用于所有配置的命令。默认为 false。

答案2

这不是解释或修复权限问题的答案,但我认为您应该只使用 systemds RuntimeDirectory 选项。引用手册页:

RuntimeDirectory=, RuntimeDirectoryMode=
       Takes a list of directory names. If set, one or more directories by
       the specified names will be created below /run (for system
       services) or below $XDG_RUNTIME_DIR (for user services) when the
       unit is started, and removed when the unit is stopped. The
       directories will have the access mode specified in
       RuntimeDirectoryMode=, and will be owned by the user and group
       specified in User= and Group=. Use this to manage one or more
       runtime directories of the unit and bind their lifetime to the
       daemon runtime. The specified directory names must be relative, and
       may not include a "/", i.e. must refer to simple directories to
       create or remove. This is particularly useful for unprivileged
       daemons that cannot create runtime directories in /run due to lack
       of privileges, and to make sure the runtime directory is cleaned up
       automatically after use. For runtime directories that require more
       complex or different configuration or lifetime guarantees, please
       consider using tmpfiles.d(5).

因此,您所要做的就是将服务文件更改为:

[Unit]
Description=control FOO daemon
After=syslog.target network.target

[Service]
Type=forking
User=FOOd
Group=FOO
RuntimeDirectory=FOOd
RuntimeDirectoryMode=$some-mode
ExecStart=/usr/local/bin/FOOd -P /run/FOOd/FOOd.pid
PIDFile=/run/FOOd/FOOd.pid

[Install]
WantedBy=multi-user.target

答案3

+在要以完全权限运行的命令之前添加。

例如:

ExecStartPre=+/bin/mkdir test

请参阅“特殊可执行前缀”部分:https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=

相关内容