Hardening/Linux/Dienste
Erscheinungsbild
Hardening/Linux/Dienste
Beschreibung
Aktive Dienste erweitern die Angriffsfläche eines Systems. Ziel ist die Reduktion nicht benötigter Komponenten sowie die Begrenzung von Rechten, Schnittstellen und Netzwerkerreichbarkeit.
- Grundsätze
- Nicht benötigte Pakete, Dienste und Timer entfernen oder deaktivieren
- Nur notwendige Netzwerk-Listener bereitstellen. Interne Dienste möglichst auf lokale Schnittstellen binden
- Standardkonfigurationen von Diensten prüfen und sicherheitsrelevante Parameter (z. B. TLS, Authentifizierung, Zugriffskontrolle) anpassen
- Änderungen schrittweise umsetzen und Dienstfunktion nach jedem Schritt validieren
Bestandsaufnahme
- Laufende Dienste
systemctl list-units --type=service --state=running
- Autostart-Status
systemctl list-unit-files --type=service
- Timer (periodische Aktivierungen)
systemctl list-timers --all
- Sockets
systemctl list-units --type=socket
- Netzwerk-Listener
- TCP/UDP:
ss -tulnp
- Inventarisierung (Template)
| Unit | Zweck | Start (enabled/disabled) | Aktivierung (service/timer/socket) | Netzwerk (ja/nein) | Port/Bind | Benutzer | Maßnahme |
|---|---|---|---|---|---|---|---|
| <unit>.service |
Maßnahmen ergreifen
- Pakete entfernen
- Entfernung reduziert Codebasis und Abhängigkeiten, sofern Funktionalität nicht benötigt wird
apt purge <PAKET>
apt autoremove --purge
- Dienst deaktivieren
- Deaktivierung verhindert automatischen Start, ein manueller Start bleibt möglich
systemctl disable --now <unit>.service
- Dienst maskieren
- Maskierung verhindert Start auch durch Abhängigkeiten oder manuelle Ausführung
systemctl mask --now <unit>.service
- Status prüfen
systemctl is-enabled <unit>.service
systemctl status <unit>.service
Timer und Socket-Aktivierung
- Timer deaktivieren
- Ein deaktivierter Dienst kann weiterhin über Timer gestartet werden. Timer separat prüfen
systemctl status <unit>.timer
- Deaktivieren:
systemctl disable --now <unit>.timer
- Socket-Aktivierung prüfen
Ein Dienst kann bei eingehender Verbindung über Socket gestartet werden
systemctl status <unit>.socket
- Deaktivieren:
systemctl disable --now <unit>.socket
Netzwerk-Exposition minimieren
- Ziele
- Listener auf das notwendige Minimum reduzieren
- Interne Dienste auf Loopback binden (127.0.0.1/::1)
- Administrative Interfaces per Zugriffskontrolle einschränken
- Externe Exposition über Firewall/Reverse Proxy/VPN steuern
- Verifikation
ss -lntup
Dienstkonfiguration
- Prüfbereiche
- TLS: Protokollversionen, Cipher-Suites, Zertifikate, HSTS
- Authentifizierung: keine Default-Credentials, minimale Rollen, MFA
- Zugriffskontrolle: Admin-Endpunkte einschränken, Bind auf interne Interfaces, ACLs
- Logging: ausreichende Protokollierung sicherstellen, Fehlermeldungen auswerten
systemd-Unit-Härtung
- Vorgehen
- Anpassungen als Drop-in-Override pflegen (Update-sicher), nicht in Paketdateien editieren
systemctl cat <unit>.service
systemctl edit <unit>.service
systemctl daemon-reload
systemctl restart <unit>.service
- Sicherheitsbewertung
systemd-analyze security <unit>.service
- Häufige Direktiven
| Direktive | Zweck |
|---|---|
| User= / Group= | Ausführung unter dediziertem (unprivilegiertem) Konto |
| DynamicUser=yes | Temporärer, isolierter Service-User (sofern kompatibel) |
| NoNewPrivileges=yes | Verhindert Privilege Escalation durch setuid/setcap innerhalb des Prozesses |
| PrivateTmp=yes | Separates /tmp pro Dienst |
| PrivateDevices=yes | Restriktion von /dev-Zugriff |
| ProtectSystem=full/strict | Systempfade schreibschützen |
| ProtectHome=yes/read-only | Zugriff auf Home-Verzeichnisse einschränken |
| ReadWritePaths= | Erlaubte Schreibpfade explizit definieren |
| InaccessiblePaths= | Pfade explizit sperren |
| CapabilityBoundingSet= | Linux-Capabilities auf Minimum begrenzen |
| AmbientCapabilities= | Ambient Capabilities nur wenn erforderlich |
| RestrictAddressFamilies= | Erlaubte Address Families einschränken (z. B. AF_UNIX/AF_INET/AF_INET6) |
| RestrictNamespaces=yes | Namespaces einschränken |
| LockPersonality=yes | Personality-Änderungen unterbinden |
| MemoryDenyWriteExecute=yes | W^X erzwingen |
| SystemCallArchitectures=native | Nur native Syscall-Architektur erlauben |
| SystemCallFilter= | Syscalls filtern (Whitelist/Blacklist) |
| UMask=0077 | Restriktive Standardrechte für neu erstellte Dateien |
- Beispiel
Drop-in Override
- Platzhalter anpassen (User, Pfade, Filter)
- Bei Inkompatibilitäten einzelne Direktiven entfernen und schrittweise nachschärfen
[Service]
# Identität
User=<service-user>
Group=<service-group>
# Rechte/Privilege Escalation
NoNewPrivileges=yes
UMask=0077
# Isolation
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
# Schreibpfade explizit erlauben
ReadWritePaths=/var/lib/<app> /var/log/<app>
# Capabilities minimieren (leer = keine zusätzlichen)
CapabilityBoundingSet=
AmbientCapabilities=
# Kernel-Schutz
LockPersonality=yes
RestrictNamespaces=yes
MemoryDenyWriteExecute=yes
SystemCallArchitectures=native
# Netzwerk einschränken
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
Betrieb
- Funktionstest
- Dienststart und restart prüfen
- Kritische Workflows des Dienstes ausführen
- Netzwerk-Listener erneut prüfen
- Logs prüfen
journalctl -u <unit>.service --since today
Rollback
- Drop-in entfernen
systemctl revert <unit>.service
systemctl daemon-reload
systemctl restart <unit>.service
- Maskierung aufheben
systemctl unmask <unit>.service