Fernwartung Download starten

Systemd Security: Linux-Services härten und absichern

LinuxSecurityServer
Systemd Security: Linux-Services härten und absichern

Jeder Service auf einem Linux-Server ist eine potentielle Angriffsfläche. Ein kompromittierter Webserver, der als root läuft und Zugriff auf das gesamte Dateisystem hat, wird schnell zur Katastrophe. Systemd bietet dutzende Sicherheitsoptionen, die Services in Sandboxen isolieren, Dateisystemzugriffe einschränken und Ressourcen begrenzen — ohne die Anwendung selbst ändern zu müssen.

systemd-analyze security: Den Status quo bewerten

Bevor Sie Härtungsmaßnahmen implementieren, analysieren Sie den aktuellen Zustand:

systemd-analyze security

Die Ausgabe zeigt für jeden Service eine Sicherheitsbewertung von 0.0 (sicher) bis 10.0 (unsicher):

UNIT                      EXPOSURE PREDICATE   HAPPY
nginx.service             9.6      UNSAFE      😨
postgresql.service        9.2      UNSAFE      😨
sshd.service              9.6      UNSAFE      😨
prometheus.service        9.6      UNSAFE      😨

Ein Score von 9+ bedeutet: Der Service hat praktisch keine Einschränkungen. Für eine detaillierte Analyse eines einzelnen Services:

systemd-analyze security nginx.service

Das zeigt alle Sicherheitsdirektiven und ihren aktuellen Status — rot markierte Einträge sind aktive Risiken.

Dateisystem-Schutz

ProtectSystem

ProtectSystem macht Systemverzeichnisse schreibgeschützt:

[Service]
# "strict" macht das gesamte Dateisystem read-only
# Ausnahmen über ReadWritePaths definieren
ProtectSystem=strict
ReadWritePaths=/var/log/nginx /var/cache/nginx /run/nginx
WertWirkung
true/usr und /boot read-only
fullWie true + /etc read-only
strictGesamtes Dateisystem read-only (empfohlen)

ProtectHome

Verhindert Zugriff auf Home-Verzeichnisse:

[Service]
# true: /home, /root, /run/user unzugänglich
ProtectHome=true

# read-only: Lesezugriff erlaubt, kein Schreiben
# ProtectHome=read-only

# tmpfs: Leere tmpfs-Mounts statt der echten Verzeichnisse
# ProtectHome=tmpfs

PrivateTmp

Gibt dem Service ein eigenes /tmp-Verzeichnis, isoliert von allen anderen Prozessen:

[Service]
PrivateTmp=true

Ohne PrivateTmp teilen sich alle Services das gleiche /tmp — ein klassischer Vektor für Symlink-Attacken und Privilege Escalation.

ReadOnlyPaths und InaccessiblePaths

Für granulare Kontrolle:

[Service]
# Bestimmte Pfade schreibgeschützt
ReadOnlyPaths=/etc /var/lib/shared-data

# Bestimmte Pfade komplett unzugänglich
InaccessiblePaths=/root /home /mnt /media

# Nur bestimmte Pfade beschreibbar (mit ProtectSystem=strict)
ReadWritePaths=/var/lib/myapp /var/log/myapp /run/myapp

Kernel- und Geräte-Schutz

ProtectKernelTunables

Verhindert Änderungen an /proc/sys, /sys und ähnlichen Kernel-Interfaces:

[Service]
ProtectKernelTunables=true

Ein kompromittierter Service kann damit keine Kernel-Parameter ändern — kein sysctl-Manipulation, kein Deaktivieren von ASLR oder ähnliche Angriffe.

ProtectKernelModules

Verhindert das Laden und Entladen von Kernel-Modulen:

[Service]
ProtectKernelModules=true

ProtectKernelLogs

Blockiert den Zugriff auf den Kernel-Log-Ring-Buffer:

[Service]
ProtectKernelLogs=true

ProtectControlGroups

Macht die cgroup-Hierarchie schreibgeschützt:

[Service]
ProtectControlGroups=true

PrivateDevices

Erstellt eine minimale /dev-Umgebung ohne physische Geräte:

[Service]
PrivateDevices=true

Der Service sieht nur /dev/null, /dev/zero, /dev/full, /dev/random und /dev/urandom — keinen Zugriff auf Festplatten, USB-Geräte oder andere Hardware.

Capabilities einschränken

Linux Capabilities unterteilen die root-Rechte in einzelne Privilegien. Statt einem Service vollen root-Zugriff zu geben, können Sie genau die Capabilities zuweisen, die er benötigt:

CapabilityBoundingSet

[Service]
# Nur die nötigen Capabilities erlauben
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH

# Alle Capabilities entfernen (für Services ohne root-Bedarf)
CapabilityBoundingSet=

Wichtige Capabilities:

CapabilityErlaubtTypische Services
CAP_NET_BIND_SERVICEPorts < 1024 bindennginx, Apache
CAP_DAC_READ_SEARCHDateiberechtigungen umgehen (lesen)Backup-Agents
CAP_NET_RAWRaw SocketsMonitoring (Ping)
CAP_SYS_PTRACEProzesse debuggenDebugging-Tools
CAP_CHOWNDatei-Eigentümer ändernFTP-Server

AmbientCapabilities

Für Services, die als Nicht-Root-User laufen, aber bestimmte Capabilities brauchen:

[Service]
User=www-data
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

Privilege Escalation verhindern

NoNewPrivileges

Die wichtigste einzelne Sicherheitsdirektive — verhindert, dass der Prozess oder seine Kinder jemals mehr Privilegien erhalten als beim Start:

[Service]
NoNewPrivileges=true

Mit NoNewPrivileges=true funktionieren SUID-Binaries und Capability-Escalation nicht mehr. Das verhindert eine ganze Klasse von Privilege-Escalation-Angriffen.

PrivateUsers

Erstellt einen eigenen User-Namespace — der Service sieht nur sich selbst:

[Service]
PrivateUsers=true

RestrictSUIDSGID

Verhindert das Setzen von SUID/SGID-Bits:

[Service]
RestrictSUIDSGID=true

Netzwerk-Isolation

RestrictAddressFamilies

Beschränkt die nutzbaren Netzwerk-Protokollfamilien:

[Service]
# Nur IPv4, IPv6 und Unix-Sockets erlauben
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX

# Für Services ohne Netzwerkbedarf
RestrictAddressFamilies=AF_UNIX

IPAddressDeny und IPAddressAllow

Firewall auf Service-Ebene:

[Service]
# Nur lokales Netz und Loopback erlauben
IPAddressAllow=127.0.0.0/8 192.168.0.0/16
IPAddressDeny=any

PrivateNetwork

Komplette Netzwerk-Isolation — der Service sieht nur das Loopback-Interface:

[Service]
# Nur für Services ohne Netzwerkbedarf
PrivateNetwork=true

Syscall-Filtering

SystemCallFilter

Beschränkt die nutzbaren Systemaufrufe auf das Minimum:

[Service]
# Systemd bietet vordefinierte Gruppen
SystemCallFilter=@system-service

# Alternativ: Gefährliche Syscalls explizit blockieren
SystemCallFilter=~@mount @clock @debug @module @reboot @swap @raw-io

Vordefinierte Syscall-Gruppen:

GruppeBeschreibung
@system-serviceBasis-Set für normale Services
@network-ioNetzwerk-Operationen
@file-systemDateisystem-Operationen
@mountMount/Unmount
@clockSystemzeit ändern
@debugDebugging (ptrace)
@moduleKernel-Module laden
@rebootSystem neustarten

SystemCallArchitectures

Beschränkt die erlaubten CPU-Architekturen für Syscalls:

[Service]
# Nur native Architektur (verhindert 32-Bit-Exploitation auf 64-Bit)
SystemCallArchitectures=native

Resource Limits: CPUQuota und MemoryMax

Neben Security-Sandboxing bietet systemd auch Ressourcenbegrenzung über cgroups:

CPU begrenzen

[Service]
# Maximal 200% CPU (2 Kerne auf einem Multi-Core-System)
CPUQuota=200%

# CPU-Gewichtung (relativ zu anderen Services)
CPUWeight=50

Speicher begrenzen

[Service]
# Maximaler RAM-Verbrauch
MemoryMax=2G

# Weiches Limit (Service darf darüber, wird aber bevorzugt zurückgefahren)
MemoryHigh=1G

# Swap begrenzen
MemorySwapMax=500M

I/O begrenzen

[Service]
# I/O-Gewichtung
IOWeight=50

# Maximaler Durchsatz pro Gerät
IOReadBandwidthMax=/dev/sda 100M
IOWriteBandwidthMax=/dev/sda 50M

Prozesse und Tasks begrenzen

[Service]
# Maximale Anzahl Prozesse/Threads
TasksMax=64

# Maximale Anzahl offener Dateien
LimitNOFILE=65536

Vollständiges Hardening-Beispiel: nginx

# /etc/systemd/system/nginx.service.d/hardening.conf
[Service]
# Dateisystem
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ReadWritePaths=/var/log/nginx /var/cache/nginx /run/nginx

# Kernel
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true

# Capabilities
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true

# Netzwerk
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX

# Syscalls
SystemCallFilter=@system-service
SystemCallArchitectures=native

# Weitere Härtung
RestrictRealtime=true
RestrictSUIDSGID=true
ProtectClock=true
LockPersonality=true
MemoryDenyWriteExecute=true
RemoveIPC=true

# Resource Limits
MemoryMax=1G
TasksMax=512

Anwenden:

systemctl daemon-reload
systemctl restart nginx

# Sicherheit erneut prüfen
systemd-analyze security nginx.service
# Erwartung: Score sinkt von 9.6 auf ca. 2.0-3.0

Eigene Timer als Cron-Ersatz

Systemd Timer bieten gegenüber cron Vorteile: Logging über journald, Abhängigkeiten, Randomized Delay und die gleichen Sandboxing-Optionen wie Services.

Timer erstellen

# /etc/systemd/system/backup-daily.timer
[Unit]
Description=Daily backup timer

[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=1800
Persistent=true

[Install]
WantedBy=timers.target
# /etc/systemd/system/backup-daily.service
[Unit]
Description=Daily backup job

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
User=backup
Group=backup

# Hardening (gleiche Optionen wie bei Services)
ProtectSystem=strict
ReadWritePaths=/var/backup /var/log/backup
ProtectHome=true
PrivateTmp=true
NoNewPrivileges=true
MemoryMax=4G
systemctl enable --now backup-daily.timer
systemctl list-timers backup-daily.timer

Timer-Varianten

DirektiveBeispielBeschreibung
OnCalendardaily, weekly, *-*-* 02:00:00Kalenderbasiert (wie cron)
OnBootSec5minNach Systemstart
OnUnitActiveSec1hNach letzter Aktivierung
RandomizedDelaySec30minZufälliger Delay (Last verteilen)
PersistenttrueVerpasste Läufe nachholen

Hardening schrittweise einführen

Aktivieren Sie Härtungsoptionen nicht alle auf einmal — gehen Sie schrittweise vor:

  1. Phase 1: ProtectSystem=strict, ProtectHome=true, PrivateTmp=true
  2. Phase 2: NoNewPrivileges=true, CapabilityBoundingSet
  3. Phase 3: SystemCallFilter, RestrictAddressFamilies
  4. Phase 4: MemoryMax, CPUQuota, TasksMax

Nach jeder Phase: Service testen, Logs auf Fehler prüfen, systemd-analyze security erneut ausführen.

Monitoring mit DATAZONE Control

DATAZONE Control überwacht die Systemd-Security-Konfiguration aller verwalteten Server: Security-Scores, aktive Hardening-Direktiven und Abweichungen von der Baseline fließen in das zentrale Compliance-Dashboard. Automatische Alerts warnen, wenn ein neuer Service ohne Hardening installiert wird oder ein Update Sicherheitsoptionen zurücksetzt.

Häufig gestellte Fragen

Kann Hardening einen Service kaputt machen?

Ja. Zu restriktive Einstellungen verhindern, dass der Service auf benötigte Ressourcen zugreift. Testen Sie Änderungen immer in einer Testumgebung und prüfen Sie journalctl -u <service> auf Fehlermeldungen.

Funktioniert Hardening mit Docker-Containern?

Systemd-Hardening gilt für den Docker-Daemon-Service, nicht für die Container selbst. Container haben ihr eigenes Isolation-Modell (Namespaces, cgroups). Beide Ansätze ergänzen sich.

Wie finde ich heraus, welche Capabilities ein Service braucht?

Starten Sie mit CapabilityBoundingSet= (keine Capabilities) und beobachten Sie die Fehlermeldungen im Journal. Fügen Sie dann die benötigten Capabilities einzeln hinzu.


Sie möchten Ihre Linux-Server systematisch härten? Kontaktieren Sie uns — wir implementieren Systemd-Hardening und überwachen die Compliance mit DATAZONE Control.

Mehr zu diesen Themen:

IT-Beratung gewünscht?

Kontaktieren Sie uns für eine unverbindliche Beratung zu Proxmox, OPNsense, TrueNAS und mehr.

Jetzt Kontakt aufnehmen