IT-Security
Ein frisch aufgesetzter VPS ist ohne zusätzliche Härtung ein offenes Einfallstor. Dieser Artikel beschreibt eine praxiserprobte Security-Baseline für Linux-Server – von der ersten SSH-Verbindung bis hin zu kontinuierlichem Monitoring.
Ausgangslage: Was ein nackter VPS mitbringt
Die meisten Anbieter liefern einen VPS mit einem minimalen Debian- oder Ubuntu-Image aus. Root-Login per Passwort ist oft aktiviert, alle Ports sind erreichbar, und automatische Sicherheitsupdates sind deaktiviert. Innerhalb von Minuten nach dem ersten Start beginnen Bots damit, Port 22 nach schwachen Passwörtern abzutasten. Die Security-Baseline setzt genau hier an: Sie reduziert die Angriffsfläche systematisch, bevor die erste produktive Anwendung deployed wird.
Benutzerverwaltung und minimale Rechtevergabe
Der erste Schritt ist das Anlegen eines dedizierten Benutzers mit sudo-Berechtigung. Root sollte danach für direkte Logins gesperrt werden. Jede Person, die Zugriff auf den Server benötigt, erhält einen eigenen Account – gemeinsam genutzte Zugangsdaten machen eine spätere Nachvollziehbarkeit von Aktionen unmöglich.
Sudo-Regeln sollten so restriktiv wie möglich gehalten werden. Wer nur Nginx neu starten darf, bekommt auch nur diese eine Erlaubnis in /etc/sudoers.d/. Das Prinzip der minimalen Rechtevergabe (Least Privilege) verhindert, dass ein kompromittiertes Konto den gesamten Server übernehmen kann.
SSH-Härtung: Schlüssel statt Passwörter
Passwortbasierter SSH-Login gehört abgeschaltet. Ed25519-Schlüsselpaare sind heute der Standard – sie sind kompakter als RSA-4096 und bieten mindestens gleichwertige Sicherheit. Der öffentliche Schlüssel landet in ~/.ssh/authorized_keys, der private verbleibt verschlüsselt auf dem Gerät des Administrators.
Die wichtigsten Anpassungen in /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
X11Forwarding no
AllowTcpForwarding no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
Nach jeder Änderung an der Konfiguration sollte sshd -t die Syntax prüfen, bevor der Dienst neu gestartet wird. Eine bestehende Session im selben Fenster hält die Verbindung aufrecht, falls ein Fehler den SSH-Daemon zum Absturz bringt.
Den SSH-Port auf einen nicht standardisierten Wert zu verlegen reduziert zwar den Lärm in den Logs, ist aber kein Sicherheitsmerkmal – automatisierte Scanner erfassen heute alle Ports. Sinnvoller ist die Kombination aus Schlüsseln und Rate-Limiting.
Firewall mit nftables oder UFW
Eine restriktive Default-deny-Policy ist das Fundament jeder Firewall-Konfiguration. Eingehender Traffic wird grundsätzlich geblockt; nur explizit freigegebene Ports passieren die Firewall. UFW eignet sich für einfache Setups, nftables bietet mehr Kontrolle für komplexe Regelwerke.
Ein minimales UFW-Setup für einen Webserver sieht so aus:
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp comment 'SSH'
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
ufw enable
ufw status verbose
IPv6 muss explizit berücksichtigt werden. UFW verwaltet beide Protokollstapel parallel, sofern IPV6=yes in /etc/default/ufw gesetzt ist. Wer IPv6 nicht benötigt, deaktiviert es systemweit über /etc/sysctl.d/, da eine vergessene IPv6-Regel sonst den gesamten Schutz unterlaufen kann.
Connection Tracking sollte genutzt werden, um ausgehende Verbindungen, die ein Angreifer nach einer Kompromittierung aufbaut (Reverse Shells, C2-Kommunikation), zu erschweren. Ausgehender Traffic auf ungewöhnliche Ports lässt sich mit Allowlists weiter einschränken.
Brute-Force-Schutz mit Fail2ban
Fail2ban wertet Logdateien aus und sperrt IP-Adressen temporär, die zu viele fehlgeschlagene Authentifizierungsversuche produzieren. Die Standardkonfiguration deckt SSH ab; eigene Jails lassen sich für Nginx, Postfix oder jede andere Anwendung definieren, die fehlgeschlagene Logins loggt.
Wichtige Parameter im SSH-Jail: maxretry = 5, bantime = 3600 und findtime = 600. Bei Servern mit öffentlicher Erreichbarkeit empfiehlt sich ein deutlich längeres bantime – 86400 Sekunden (24 Stunden) oder mehr reduziert den Aufwand für persistente Angreifer erheblich. Die eigene IP-Adresse oder der IP-Bereich des Unternehmens sollte in der ignoreip-Liste stehen, um versehentliche Selbstsperrungen zu vermeiden.
Automatische Sicherheitsupdates
Ungepatchte Software ist die häufigste Ursache für erfolgreiche Einbrüche. Automatische Sicherheitsupdates reduzieren das Zeitfenster zwischen Bekanntwerden einer Schwachstelle und ihrer Behebung erheblich. Unter Debian und Ubuntu übernimmt unattended-upgrades diese Aufgabe.
Die Konfiguration in /etc/apt/apt.conf.d/50unattended-upgrades sollte mindestens den Security-Origin aktivieren. Für Produktionssysteme ist es sinnvoll, Reboots nach Kernel-Updates auf ein Wartungsfenster zu legen – Unattended-Upgrade::Automatic-Reboot-Time "03:00" steuert das. E-Mail-Benachrichtigungen über durchgeführte Updates liefern zusätzliche Transparenz ohne manuellen Aufwand.
Drittanbieter-Repositories – etwa für Docker oder Node.js – sind von automatischen Updates ausgenommen, sofern sie nicht explizit konfiguriert werden. Diese Pakete müssen in einem separaten Update-Prozess berücksichtigt werden.
Kernel-Parameter und Systemhärtung
Über /etc/sysctl.d/ lassen sich zahlreiche sicherheitsrelevante Kernel-Parameter setzen. Besonders relevant sind:
- IP-Spoofing-Schutz:
net.ipv4.conf.all.rp_filter = 1 - ICMP-Redirects ablehnen:
net.ipv4.conf.all.accept_redirects = 0 - SYN-Flood-Schutz:
net.ipv4.tcp_syncookies = 1 - Kernel-Pointer verbergen:
kernel.kptr_restrict = 2 - dmesg einschränken:
kernel.dmesg_restrict = 1
AppArmor (Ubuntu) oder SELinux (Debian/RHEL) bieten Mandatory Access Control und begrenzen, was ein Prozess tun darf, selbst wenn er kompromittiert wurde. Profile für gängige Dienste wie Nginx oder MySQL existieren bereits und lassen sich mit minimalem Aufwand aktivieren.
Monitoring und zentrales Logging
Security ohne Monitoring ist blind. Mindestanforderung ist, dass sicherheitsrelevante Ereignisse – fehlgeschlagene Logins, Sudo-Verwendung, Änderungen an kritischen Dateien – erfasst und an einen zentralen Ort weitergeleitet werden. Auf dem Server selbst können Logs manipuliert werden; ein externer Log-Aggregator (z.B. Loki, Graylog oder ein einfacher Syslog-Server) sichert die Integrität.
auditd ergänzt das Standard-Syslog um detaillierte Nachvollziehbarkeit von Systemaufrufen. Regeln wie das Überwachen von Schreibzugriffen auf /etc/passwd oder /etc/sudoers liefern wertvolle Signale bei einem aktiven Angriff.
Für die Verfügbarkeitsüberwachung eignen sich Prometheus mit Node Exporter und Alertmanager. Schwellenwerte für CPU-Last, Speicherverbrauch und offene Dateideskriptoren lösen Alarme aus, bevor ein Problem eskaliert. Angriffsindikatoren wie ungewöhnlich hohe ausgehende Bandbreite lassen sich ebenfalls über diese Infrastruktur erfassen.
Dateiintegritätsprüfung mit AIDE
AIDE (Advanced Intrusion Detection Environment) erstellt eine kryptografische Baseline aller Systemdateien und erkennt nachträgliche Änderungen. Nach der Grundinstallation und Härtung wird eine initiale Datenbank angelegt: aide --init. Regelmäßige Prüfungen per Cron vergleichen den aktuellen Zustand mit dieser Baseline und melden Abweichungen.
Wichtig: Die AIDE-Datenbank darf nicht auf dem überwachten System selbst gespeichert werden – ein Angreifer mit Root-Rechten kann sie einfach überschreiben. Eine externe Ablage (Read-only-Mount, S3-Bucket, separater Server) ist obligatorisch. AIDE ist kein Echtzeitschutz, sondern ein forensisches Werkzeug zur Erkennung von Kompromittierungen im Nachhinein.
Zusammenfassung: Die Security-Baseline im Überblick
Eine konsistente Härtung eines VPS lässt sich in reproduzierbare Schritte fassen, die idealerweise per Ansible oder Cloud-Init automatisiert werden:
- Dedizierten Admin-Benutzer anlegen, Root-Login deaktivieren
- SSH auf Schlüsselauthentifizierung umstellen, Passwort-Login deaktivieren
- Firewall mit Default-deny konfigurieren, nur benötigte Ports öffnen
- Fail2ban für SSH und relevante Dienste aktivieren
- Automatische Sicherheitsupdates einrichten und testen
- Sicherheitsrelevante Kernel-Parameter setzen
- AppArmor- oder SELinux-Profile aktivieren
- Zentrales Logging einrichten, Logs extern sichern
- AIDE-Baseline erstellen und Prüfung automatisieren
- Monitoring für Verfügbarkeit und Anomalien aufsetzen
Diese Maßnahmen sind kein einmaliges Projekt, sondern ein kontinuierlicher Prozess. Neue Schwachstellen, geänderte Anforderungen und wachsende Infrastruktur erfordern regelmäßige Überprüfung und Anpassung der Baseline. Wer sie von Beginn an konsequent umsetzt, schafft eine stabile Grundlage, auf der sich produktive Anwendungen sicher betreiben lassen.