systemd: Berechtigungsproblem mit mkdir & ExecStartPre

37

Ich habe ein Problem mit dieser (verkürzten) Systemd-Servicedatei:

[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

Es sei FOOd der Benutzername und FOO der Gruppenname, der für meinen Daemon bereits existiert /usr/local/bin/FOOd.

Ich muss das Verzeichnis erstellen, /var/run/FOOd/bevor ich den Daemon-Prozess /usr/local/bin/FOOdüber starte # systemctl start FOOd.service. Dies schlägt fehl, da mkdir das Verzeichnis aufgrund von Berechtigungen nicht erstellen kann:

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

Warum schlägt mkdir bei ExecStartPre fehl und wie kann ich das beheben? (Und nein, ich kann sudo nicht für mkdir verwenden ...)

Matt
quelle
Zu Ihrer Information: Ich verwende Debian 8
Matt
Können Sie bitte die Fehlermeldung ins Englische übersetzen?
Thushi
1
... Jun 03 16:18:49 PC0515546 mkdir [2469]: / bin / mkdir: das Verzeichnis / var / run / FOOd / kann nicht erstellt werden: keine Berechtigung Jun 03 16:18:49 PC0515546 systemd [1] : FOOd.service: Steuerprozess beendet, Code = Status beendet = 1 ...
Matt

Antworten:

56

Sie müssen hinzufügen

PermissionsStartOnly=true

zu [Service]. Ihr Benutzer FOOdist selbstverständlich nicht berechtigt, ein Verzeichnis in anzulegen /var/run. So zitieren Sie die Manpage:

Nimmt ein boolesches Argument an. Wenn true, werden die berechtigungsbezogenen Ausführungsoptionen, die mit User = und ähnlichen Optionen konfiguriert wurden (weitere Informationen finden Sie in systemd.exec (5)), nur auf den Prozess angewendet, der mit ExecStart = gestartet wurde, und nicht auf die verschiedenen anderen ExecStartPre = , ExecStartPost =, ExecReload =, ExecStop = und ExecStopPost = Befehle. Bei false wird die Einstellung auf alle konfigurierten Befehle auf dieselbe Weise angewendet. Der Standardwert ist false.

embik
quelle
1
Wunderbar, genau das, wonach ich gesucht habe.
Robert
2
Mit dieser Option werden Befehle ExecReload=mit Root-Rechten ausgeführt. Dies ist möglicherweise nicht das, was Sie wollen.
Rockallite
@Rockallite Das ist, was die Dokumentation, die ich zitiert habe, wörtlich sagt, ja.
Embik
2
PermissionsStartOnlywurde veraltet. Referenz: github.com/NixOS/nixpkgs/issues/53852 Wie geht das jetzt?
Adrelanos
2
@adrelanos Fügen Sie nun +unmittelbar danach ein ExecStartPre=. Zum BeispielExecStartPre=+/bin/mkdir test
Jamie Scott
28

Dies ist keine Antwort, die das Berechtigungsproblem erklärt oder behebt, aber ich denke, Sie sollten nur die Option systemds RuntimeDirectory verwenden. Zitieren der Manpage :

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

Sie müssen also lediglich Ihre Servicedatei ändern in:

[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
quelle
Danke Danke. Leider fehlt im OpenVPN-Ubuntu-Paket !!
BaseZen