systemd: problema de permisos con mkdir y ExecStartPre

37

Tengo un problema con este archivo de servicio systemd (acortado):

[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

Deja que FOOd sea ​​el nombre de usuario y FOOd el nombre del grupo, que ya existe para mi demonio /usr/local/bin/FOOd.

Necesito crear el directorio /var/run/FOOd/antes de comenzar el proceso de demonio a /usr/local/bin/FOOdtravés de # systemctl start FOOd.service. Esto falla porque mkdir no puede crear el directorio debido a permisos:

...
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
...

¿Por qué falla mkdir en ExecStartPre y cómo puedo solucionarlo? (Y no, no puedo usar sudo para mkdir ...)

Mate
fuente
FYI: estoy usando Debian 8
Matt
¿Puede traducir el mensaje de error al inglés?
Thushi
1
... 03 de junio 16:18:49 PC0515546 mkdir [2469]: / bin / mkdir: el directorio / var / run / FOOd / no se puede crear: sin permiso 03 de junio 16:18:49 PC0515546 systemd [1] : FOOd.service: proceso de control salido, código = estado salido = 1 ...
Matt

Respuestas:

56

Necesitas agregar

PermissionsStartOnly=true

a [Service]. FOOdPor supuesto, su usuario no está autorizado para crear un directorio en /var/run. Para citar la página del manual:

Toma un argumento booleano. Si es verdadero, las opciones de ejecución relacionadas con los permisos, configuradas con Usuario = y opciones similares (consulte systemd.exec (5) para obtener más información), solo se aplican al proceso iniciado con ExecStart =, y no a los otros ExecStartPre = , ExecStartPost =, ExecReload =, ExecStop = y ExecStopPost = comandos. Si es falso, la configuración se aplica a todos los comandos configurados de la misma manera. Por defecto es falso.

embik
fuente
1
Maravilloso, exactamente lo que estaba buscando.
Robert
2
Esta opción hace que los comandos se ExecReload=ejecuten con privilegios de root. Esto puede no ser lo que quieres.
Rockallite
@Rockallite, eso es lo que dice literalmente la documentación que cité, sí.
embik
2
PermissionsStartOnlyfue desaprobado. Referencia: github.com/NixOS/nixpkgs/issues/53852 ¿Cómo hacer eso ahora?
adrelanos
2
@adrelanos Ahora, agregue un +inmediatamente después ExecStartPre=. Por ejemploExecStartPre=+/bin/mkdir test
Jamie Scott,
28

Esta no es una respuesta que explique o solucione el problema de permisos, pero creo que debería usar la opción systemds RuntimeDirectory. Citando la página del manual :

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).

Entonces, todo lo que tendría que hacer es cambiar su archivo de servicio a:

[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
Wieland
fuente
Gracias Gracias. Lamentablemente falta en el paquete OpenVPN Ubuntu !!
BaseZen