systemd Service erstellen

Anleitung, wie man ein Start-Script für einen eigenen Dienst erstellt, den man dann beim Neustart automatisch starten lassen kann.

Jeder Dienst unter Linux mit systemd besteht aus einer Datei im Ordner /usr/lib/systemd/system

Unter diesem Dateinamen kann der Dienst gesteuert werden:

# Dienst starten
/bin/systemctl start testservice.service

# Dienst stoppen
/bin/systemctl stop testservice.service

# beim Boot starten
systemctl enable testservice.service

# nicht mehr beim Boot starten
systemctl disable testservice.service

Eine einzelne Dienst-Datei sieht dann so aus:

[Unit]
Description=Test service
After=network.target

[Service]
Type=forking
ExecStartPre=/usr/bin/testservice-beforestart
ExecStart=/usr/bin/testservice-start arg1 arg2
ExecStartPost=/usr/bin/testservice-started
ExecStopPre=/usr/bin/testservice-beforestop
ExecStop=/usr/bin/testservice-stop
ExecStopPost=/usr/bin/testservice-stopped
StandardOutput=null
StandardError=null
User=testuser
ProtectHome=true
PrivateTmp=true
PermissionsStartOnly=true
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

Ich konzentriere mich hier auf die wichtigsten Einstellungsmöglichkeiten:

  • Description: eine kurze Beschreibung des Dienstes, wird beim Aufruf von "systemctl" angezeigt
  • After: wird nach folgendem Dienst gestartet. Häufig network.target, damit das Netzwerk bei Dienststart schon bereit ist. Mehrere Dienste durch Leerzeichen getrennt.
  • Type: diese unscheinbare Einstellung entscheidet massgeblich, ob der Dienst wie gewünscht funktioniert. Es gibt mehrere Typen, relevant sind insbesondere drei, welche sich auch einfach unterscheiden lassen. Hierfür ist massgeblich, wie sich das Programm unter ExecStart verhält, wenn man es in der Kommandozeile aufruft (ohne nohup, & oder dergleichen):
    • oneshot: das Programm erledigt etwas und ist dann wieder beendet (z.B. Datei kopieren oder Dateirechte ändern).
    • simple: das Programm startet und bleibt im Vordergrund (Shell nicht weiter nutzbar). Muss mit Ctrl+C oder einem Kommando beendet werden.
    • forking: das Programm startet, läuft im Hintergrund weiter und Shell ist wieder nutzbar.
  • ExecStartPre: optional, führt ein Kommando vor dem Start aus. Die Zeile darf nie, einmal aber auch mehrmals vorkommen. Kann insbesondere dann wichtig sein, wenn der Prozess nicht mit Root-Rechten läuft und die Umgebung vorbereitet werden muss.
  • ExecStart: ausführbares Kommando des Dienstes
  • ExecStartPost: optional, führt ein Kommando nach dem Start aus. Die Zeile darf nie, einmal aber auch mehrmals vorkommen.
  • ExecStopPre: optional, führt ein Kommando vor dem Stop aus. Die Zeile darf nie, einmal aber auch mehrmals vorkommen.
  • ExecStop: Kommando zum stoppen des Dienstes. Ist dies nicht vorhanden werden alle Prozesse beendet, die gestartet wurden.
  • ExecStopPost: optional, führt ein Kommando nach dem Stop aus. Die Zeile darf nie, einmal aber auch mehrmals vorkommen.
  • StandardOutput: optional, definiert, wohin Ausgaben an STDOUT gesendet werden sollen:
    • null: verwerfen
    • syslog: an syslogd senden
    • append:/var/log/testservice.log - Ausgaben an Logfile anhängen
  • StandardError: optional für STDERR, selbe Argumente wie StandardOutput
  • User: optional, startet Dienst nicht als root sondern als angegebener Benutzer
  • ProtectHome: optional true/false, Prozess hat keinen Zugriff auf /root und /home
  • PrivateTmp: optional true/false, Prozess bekommt eigenes Temp-Verzeichnis
  • PermissionsStartOnly: optional true/false. Wenn Prozess unter einem anderen Benutzer startet werden ExecStartPre Kommandos bei true als Root ausgeführt, wenn Parameter fehlt oder false ist auch schon als Benutzer
  • SuccessExitStatus: optional, weitere Status-Codes, die als erfolgreich beendet gelten. Häufig 143 für Prozess gekillt.
  • WantedBy: wird benötigt von, in der Regel multi-user.target für Start ab Runlevel 3

Aus Sicherheitsgründen muss nach dem erstellen oder Änderungen von Diensten die Konfiguration mit Root-Rechten neu eingelesen werden. Dies erfolgt mit

systemctl daemon-reload