TokkNet

Systemd-Overrides: Anpassung von Systemdiensten mittels Drop-In

Ohne Änderung der ausgelieferten Service-Dateien
Tokk EN 495 Wörter ~3 Min.

In den Paketen vieler Programme sind systemd-Service-Dateien enthalten, damit die installierten Dienste im Hintergrund laufen oder periodisch ausgeführt werden. Ab und an kommt es aber natürlich vor, das die Dateien nicht kompatibel mit dem eigenen Setup sind und angepasst werden müssen.

So sieht die Unit-Datei für den Mattermost Server aus dem Arch-Repository zum Beispiel in Auszügen so aus:

[Unit]
Description=Mattermost Chat Server
After=mysqld.service
After=postgresql.service

[Service]
Type=simple
User=mattermost
[...]
ReadWritePaths=/etc/webapps/mattermost/config.json
[...]
ProtectSystem=strict
[...]

ProtectSystem=strict sorgt dafür, das der Prozess nur in den angegebenen ReadWritePaths lesend und schreibend zugreifen darf.1
In meinem System habe ich aber den Speicher für im Chat verschickte Anhänge auf einem gemounteten Storage liegen, da diese Daten auf Dauer den Rahmen meiner System-SSD sprengen würden. So lobenswert diese abgesicherte Standardkonfiguration auch ist, so bringt es hier natürlich auch das Problem mit sich, das Mattermost den Speicherort unter /media/store/mattermost nicht nutzen darf.

Nun kann man natürlich einfach die mitgelieferte Service-Datei anpassen und die Direktive ReadWritePath auf die eigenen Bedürfnisse anpassen, aber beim nächsten Update kann es dann zu einem der folgenden Probleme kommen: Entweder wird die Service-Datei wieder durch die aus dem Paket ersezt oder notwendige Änderungen aus dem Upstream kommen nicht am eigenen System an. Gerade bei Services die im Web exponiert sind ist letztes auch ein Sicherheitsrisiko und daher nicht empfehlenswert.

Systemd-Overrides

Die Lösung für dieses Problem bringt Systemd auch gleich mit, es ist möglich, spezielle Override-Dateien anzulegen, die dann einfach einzelne Werte aus der Originaldatei ändern ohne diese direkt zu editieren.
Der leichteste Weg führt über den Befehl systemctl edit <service> also hier im Beispiel systemctl edit mattermost.service. Es wird ein Editor geöffnet, der entweder eine neue Override-Datei erstellt oder aber eine bereits angelegte öffnet. Zusätzlich befindet sich im Editor die komplette Datei im auskommentierten Zustand, so dass man sich die Originaldatei einfach während der Bearbeitung ansehen kann.

### Editing /etc/systemd/system/mattermost.service.d/override.conf
### Anything between here and the comment below will become the contents of the drop-in file

[Service]
ReadWritePaths=/etc/webapps/mattermost/config.json /var/mattermost /media/store/mattermost

### Edits below this comment will be discarded


### /usr/lib/systemd/system/mattermost.service
# [Unit]
# Description=Mattermost Chat Server
# After=mysqld.service
# After=postgresql.service
[...]

In dieser Datei können nun alle Werte den Bedürfnissen des eigenen Systems angepasst werden, es muss jedoch immer auf die Sections geachtet werden. Nach dem Speichern zeigt auch systemctl status <service> entsprechend an, dass die Unit-Konfiguration mittels einer weiteren Datei erweitert wurde:

❯ sudo systemctl status mattermost
● mattermost.service - Mattermost Chat Server
    Loaded: loaded (/usr/lib/systemd/system/mattermost.service; enabled; preset: disabled)
    Drop-In: /etc/systemd/system/mattermost.service.d
             └─override.conf

die Datei /etc/systemd/system/mattermost.service.d/override.conf wurde als Drop-In geladen, beide Dateien werden gemerged und das Ergebnis wird als Konfiguration verwendet.
Änderungen an der Unit-Datei können somit ohne weiteres eingespielt werden, da diese niemals verändert wird und die notwendigen Lokalen anpassungen werden zur Laufzeit immer mit geladen. Bei Umfangreichen Änderungen kann mittels systemctl edit --full <service> auch eine komplette Kopie der Datei angelegt werden, in diesem Fall werden zukünfigte Updates natürlich höchstwahrscheinlich auch direkt immer wieder überschrieben und man ist wieder komplett selbst für den Zustand der Dienstkonfiguration verwantwortlich.