systemd: problème d'autorisation avec mkdir & ExecStartPre

37

J'ai un problème avec ce fichier de service Systemd (raccourci):

[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

Soit FOOd le nom d'utilisateur et FOO le nom du groupe, qui existe déjà pour mon démon /usr/local/bin/FOOd.

Je dois créer le répertoire /var/run/FOOd/avant de lancer le processus démon /usr/local/bin/FOOdvia # systemctl start FOOd.service. Cela échoue, car mkdir ne peut pas créer le répertoire en raison d'autorisations:

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

Pourquoi mkdir échoue-t-il dans ExecStartPre et comment puis-je résoudre ce problème? (Et non, je ne peux pas utiliser sudo pour mkdir ...)

Mat
la source
Pour votre information: j'utilise Debian 8
Matt
Pouvez-vous s'il vous plaît traduire le message d'erreur en anglais?
Thushi
1
... 03 juin 16:18:49 PC0515546 mkdir [2469]: / bin / mkdir: le répertoire / var / run / FOOd / ne peut pas être créé: aucune autorisation Jun 03 16:18:49 PC0515546 systemd [1] : FOOd.service: processus de contrôle abandonné, code = statut abandonné = 1 ...
Matt

Réponses:

56

Vous devez ajouter

PermissionsStartOnly=true

à [Service]. Votre utilisateur FOOdn'est bien sûr pas autorisé à créer un répertoire dans /var/run. Pour citer la page de manuel:

Prend un argument booléen. Si la valeur est true, les options d'exécution liées aux autorisations, telles que configurées avec User = et des options similaires (voir systemd.exec (5) pour plus d'informations), sont uniquement appliquées au processus démarré avec ExecStart = et non aux divers autres ExecStartPre =. , ExecStartPost =, ExecReload =, ExecStop = et ExecStopPost =. Si la valeur est false, le paramètre est appliqué à toutes les commandes configurées de la même manière. La valeur par défaut est false.

embik
la source
1
Merveilleux, exactement ce que je cherchais.
robert
2
Cette option permet d’ ExecReload=exécuter des commandes dans le privilège root. Cela peut ne pas être ce que vous voulez.
Rockallite
@Rockallite, c'est ce que dit littéralement la documentation que j'ai citée, oui.
Embik
2
PermissionsStartOnlyétait obsolète. Référence: github.com/NixOS/nixpkgs/issues/53852 Comment faire cela maintenant?
Adrelanos
2
@adrelanos Maintenant, ajoutez un +immédiatement après ExecStartPre=. Par exempleExecStartPre=+/bin/mkdir test
Jamie Scott
28

Ce n'est pas une réponse qui explique ou résout le problème d'autorisation, mais je pense que vous devriez simplement utiliser l'option systemds RuntimeDirectory. Citation de la page de manuel :

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

Il vous suffit donc de modifier votre fichier de service pour:

[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
la source
Merci merci. Malheureusement, il manque au paquet OpenVPN Ubuntu !!
BaseZen