SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-25

Dienste unter einem unprivilegierten Benutzer ausführen

Dienste als root auszuführen, kann eine einzelne Lücke in vollständigen Serverzugriff verwandeln. Nutzen Sie eigene Konten oder systemd DynamicUser für weniger Rechte.

Warum nicht einfach alles als root ausführen

root kann auf dem System alles tun: jede Datei lesen, jede Einstellung ändern und das gesamte System löschen. Wenn Sie einen Dienst als root ausführen, übertragen Sie diese vollständigen Berechtigungen auf den Dienst. Enthält der Dienst eine Sicherheitslücke, die ein Angreifer ausnutzen kann, erhält der Angreifer nicht nur Zugriff auf den Dienst, sondern auf root und damit auf den gesamten Server. Die Ausführung unter einem nicht privilegierten Benutzer begrenzt den Schaden. Eine Sicherheitslücke in einem Dienst, der unter einem eingeschränkten Konto läuft, ermöglicht dem Angreifer nur den Zugriff auf die Ressourcen, auf die dieses Konto zugreifen kann. Das sollte nahezu nichts sein.

Das ist das Prinzip der geringsten Privilegien: Geben Sie jedem Teil des Systems genau die Zugriffsrechte, die er für seine Aufgabe benötigt, und keine weiteren. Dies ist die wirksamste einzelne Maßnahme, um die Auswirkungen eines Einbruchs zu begrenzen. Auf einem modernen Server lässt sich dieses Prinzip mit nahezu keinem zusätzlichen Aufwand umsetzen.

Ein eigenes Konto pro Dienst

Der klassische Ansatz besteht darin, für jeden Dienst einen separaten Systembenutzer anzulegen. Dieser besitzt nur die Dateien des jeweiligen Dienstes und kann sich nicht anmelden. Ein Systemkonto für eine Webanwendung kann beispielsweise so aussehen:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

Jede Option ist relevant. --system legt ein Dienstkonto und kein menschliches Benutzerkonto an. --no-create-home überspringt ein nicht benötigtes Home-Verzeichnis. --shell /usr/sbin/nologin bedeutet, dass ein Angreifer selbst dann keine Shell mit diesem Konto öffnen kann, wenn er irgendwie Zugriff darauf erhält. Das Konto dient ausschließlich dazu, einen Prozess und dessen Dateien zu besitzen.

Geben Sie diesem Benutzer anschließend nur die benötigten Dateien und nichts darüber hinaus:

sudo chown -R appsvc:appsvc /opt/myapp

Der Dienst liest und schreibt nun in seinem eigenen Verzeichnis und benötigt an keiner anderen Stelle des Datenträgers Zugriffsrechte. Wird der Dienst dennoch kompromittiert, sind die Dateien, die der Angreifer ändern kann, auf /opt/myapp begrenzt. Das Konto kann weiterhin alle weltweit lesbaren Dateien lesen, aber den übrigen Teil des Systems nicht ändern.

Lassen Sie systemd den Dienst unter diesem Benutzer ausführen

Sobald das Konto vorhanden ist, weisen Sie systemd an, den Dienst unter diesem Benutzer auszuführen. In der Unit-Datei genügt dafür eine Zeile:

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc bedeutet, dass der Prozess mit den eingeschränkten Berechtigungen dieses Kontos statt mit den Berechtigungen von root gestartet wird. Dies ist der übliche und bewährte Weg, eine Anwendung unter systemd auszuführen. Sie sollten dies für jeden Dienst umsetzen, für den Sie eine Unit-Datei erstellen. Das Herabsetzen der Berechtigungen hilft jedoch nicht, wenn systemd den falschen Prozess überwacht. Wenn die Unit weiterhin als aktiv gemeldet wird, obwohl der Daemon bereits unbemerkt beendet wurde, prüfen Sie daher, ob Sie den richtigen Type=-Wert für die Startweise Ihres Prozesses ausgewählt haben.

Oder überspringen Sie das Konto vollständig mit DynamicUser

systemd kann noch einen Schritt weitergehen und einen temporären Benutzer für Sie anlegen. Dieser Benutzer existiert nur, solange der Dienst ausgeführt wird. Setzen Sie DynamicUser=yes, und Sie müssen kein Konto verwalten:

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

Beim Start weist systemd eine ungenutzte Benutzer-ID zu. Beim Beenden gibt systemd sie wieder frei. Der Dienst erhält außerdem ein privates /tmp, eine schreibgeschützte Ansicht des größten Teils des Dateisystems und ein beschreibbares Zustandsverzeichnis unter /var/lib/myapp. StateDirectory= richtet dieses Verzeichnis ein und übergibt es an den Dienst. Unter SysV init war dies nicht möglich. Dort hing die Abgabe von Berechtigungen davon ab, was das jeweilige Startskript des Dienstes umsetzte. Diese Lücke ist ein wesentlicher Grund dafür, warum Distributionen überhaupt zu systemd gewechselt sind. Für einen eigenständigen Dienst, der nur sein eigenes Zustandsverzeichnis benötigt, ist DynamicUser=yes der einfachste Weg zu einer starken Isolation. Es gibt dann kein dauerhaft vorhandenes Konto, das ein Angreifer überhaupt angreifen kann.

Units manuell zu schreiben ist umständlich. Der größte Nutzen liegt darin, die Hardening-Direktiven korrekt festzulegen. Der Generator im Leitfaden zu systemd-Diensten und -Timern kann diese Optionen für Sie ergänzen. Dadurch ist die Unit von Anfang an korrekt.

Wie sich dies in das Gesamtkonzept einfügt

Das Prinzip der geringsten Rechte ist eine Schutzschicht. Es ergänzt die anderen Maßnahmen, statt sie zu ersetzen. Eine standardmäßig alles verweigernde Firewall legt fest, was den Dienst erreichen kann. Wenn der Dienst als Benutzer ohne privilegierte Rechte läuft, wird begrenzt, was er nach einer Kompromittierung tun kann. Ein gehärtetes SSH hält Angreifer von vornherein vom Server fern. Keine dieser Maßnahmen reicht allein aus. Zusammen verhindern sie, dass eine Schwachstelle in einem Dienst zur Kompromittierung des gesamten Servers führt. Beim Betrieb eines Dienstes, der Geheimnisse schützt, werden die Grenzen dieser Schichten deutlich: Ein eingeschränktes Konto begrenzt, auf welche Ressourcen ein kompromittierter Prozess zugreifen kann. Ein selbst gehosteter Passwortmanager wie Vaultwarden steht und fällt dennoch damit, wie Sie sein Admin-Token und seine Backup-Datei schützen. Die Benutzerisolierung deckt beides nicht ab.

Bevor Sie fortfahren, arbeiten Sie eine Hardening-Checkliste für den gesamten Server durch und erstellen Sie eine personalisierte Kopie als Arbeitsgrundlage:

ToolVPS hardening checklist

FAQ

Warum sollte ich einen Dienst nicht als root ausführen?

Weil root auf dem Rechner alles tun kann, übergibt ein als root ausgeführter und kompromittierter Dienst dem Angreifer den gesamten Server und nicht nur den Dienst. Wenn Sie den Dienst unter einem eingeschränkten, unprivilegierten Konto ausführen, begrenzen Sie den Schaden auf die Ressourcen, auf die dieses Konto zugreifen kann. Verwenden Sie root nur für Administrationsaufgaben und führen Sie jeden dauerhaft laufenden Dienst unter einem eingeschränkten Benutzer aus.

Wie erstelle ich einen Benutzer, der sich nicht anmelden kann?

Führen Sie sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME aus. Die Shell nologin verhindert, dass das Konto eine interaktive Sitzung öffnet, selbst wenn seine Zugangsdaten gestohlen werden. --system kennzeichnet es als Dienstkonto, und --no-create-home überspringt ein nicht benötigtes Home-Verzeichnis. Übertragen Sie ihm mit chown nur den Besitz an den eigenen Dateien.

Was ist systemd DynamicUser?

DynamicUser=yes weist systemd an, für den Dienst einen temporären Benutzer anzulegen, der nur während der Laufzeit existiert. Dadurch müssen Sie kein dauerhaftes Konto verwalten. Der Dienst erhält außerdem ein privates /tmp, eine weitgehend schreibgeschützte Sicht auf das Dateisystem und ein verwaltetes Zustandsverzeichnis. Dies ist die Lösung mit dem geringsten Verwaltungsaufwand, um einen eigenständigen Dienst unter einer temporären Identität mit geringen Rechten auszuführen.

Ersetzt die Ausführung unter einem Nicht-root-Benutzer eine Firewall?

Nein. Beide schützen unterschiedliche Bereiche. Die Ausführung unter einem unprivilegierten Benutzer begrenzt, was ein Dienst nach einer Kompromittierung tun kann. Eine Firewall begrenzt dagegen, welche Verbindungen den Dienst überhaupt erreichen können. Verwenden Sie beides zusammen mit einem gehärteten SSH, damit jede Schicht die Schwächen der anderen ausgleicht.

Welche Dateien sollte der Dienstbenutzer besitzen?

Nur die Dateien, die der Dienst tatsächlich benötigt, und keine weiteren. Übertragen Sie dem Konto den Besitz seines eigenen Arbeitsverzeichnisses und seiner Daten. Alles andere sollte weiterhin root gehören. Ein gutes Muster ist sudo chown -R svc-app:svc-app /opt/svc-app für das Anwendungsverzeichnis. Die Konfiguration unter /etc bleibt dagegen im Besitz von root und ist für den Dienst nur lesbar. Ziel ist, dass die Dateien, die der Prozess im Fall einer Kompromittierung ändern kann, auf seine eigenen Daten und nicht auf den übrigen Teil des Systems beschränkt sind.

#security#least-privilege#systemd#users#hardening#linux