Einen Linux-VPS abzusichern bedeutet nicht, UFW und Fail2ban zu installieren und die Arbeit für erledigt zu halten. Ein ins Internet gestellter Server muss in der Tiefe verteidigt werden: gepflegtes System, personenbezogene Administratorzugänge, robuste SSH-Authentifizierung, ausschließlich notwendige Ports, Dienste mit minimalen Rechten, auswertbare Protokolle, wiederherstellbare Sicherungen und ein Verfahren für den Fall einer Kompromittierung.
Diese Anleitung bietet eine realistische Grundlage für Debian und Ubuntu. Zu jeder heiklen Änderung gehört eine Kontrolle und, wo nötig, eine Vorkehrung gegen das versehentliche Aussperren.
Am Ende sollten Sie diese Fragen genau beantworten können:
- Welche Systemversion ist installiert und wie lange wird sie gepflegt?
- Welche Dienste lauschen auf IPv4 und IPv6?
- Wer darf sich per SSH verbinden, mit welchem Verfahren und aus welchem Netz?
- Welche Firewallregeln greifen tatsächlich?
- Sind die Sicherheitsupdates installiert und werden Fehlschläge gemeldet?
- Überleben die Protokolle einen Neustart und werden sie außerhalb des VPS gesichert?
- Welche Sicherung wurde zuletzt erfolgreich wiederhergestellt?
- Was tun Sie, wenn ein Schlüssel, ein Konto oder der ganze Server kompromittiert ist?
Vorgehen, Umfang und Grenzen
Die Empfehlungen wurden am 31. August 2026 mit den Veröffentlichungen der französischen ANSSI zur GNU/Linux-Härtung, der offiziellen Dokumentation von Debian, Ubuntu Server, OpenSSH, systemd, dem Linux-Kernel, Docker und restic abgeglichen. Der ANSSI-Leitfaden liefert einen Härtungsrahmen; Befehle und Verhaltensweisen, die sich ändern können, wurden in der aktuellen Projektdokumentation überprüft.
Versionen, Supportzeiträume und das Verhalten der Werkzeuge ändern sich. Bevor Sie diese Grundlage produktiv einsetzen, führen Sie sie auf einem Test-VPS aus und prüfen Sie die datierten Angaben dieses Artikels auf den im Text verlinkten offiziellen Seiten.
Diese Anleitung behandelt einen direkt administrierten Debian- oder Ubuntu-VPS. Sie ersetzt weder die Härtung von Nginx, Apache, PHP, Docker, einer Datenbank oder einer Anwendung, noch eine hochverfügbare Architektur, noch ein regulatorisches Audit oder einen Penetrationstest, noch die Regeln für Kubernetes, Proxmox, einen Router, einen Mailserver oder einen Hypervisor, noch die Maßnahmen des Anbieters unterhalb der Virtualisierungsschicht.
Sicherheit ist eine Eigenschaft des Ganzen: Anbieter, Netzwerk, System, Anwendung, Identitäten, Daten, Sicherungen und Betrieb.
Berücksichtigte Versionen im August 2026
Debian 13 „trixie“ ist die aktuelle stabile Version. Debian nennt vollen Support bis zum 9. August 2028, danach eine LTS-Phase bis zum 30. Juni 2030 mit reduziertem Architektursatz. Debian 12 wurde inzwischen von Debian 13 abgelöst: Der volle Support endete am 11. Juli 2026, die LTS-Phase läuft noch bis zum 30. Juni 2028 und ist auf bestimmte Architekturen beschränkt. Siehe die offiziellen Seiten zu Debian 13 und Debian 12.
Ubuntu 22.04, 24.04 und 26.04 sind im August 2026 weiterhin gepflegte LTS-Versionen. Canonical veröffentlicht die genauen Daten im Ubuntu-Lebenszyklus.
| System | Stand am 31. August 2026 | Empfohlene Entscheidung |
|---|---|---|
| Debian 13 | aktuelle Stable | empfohlene Debian-Wahl für eine Neuinstallation |
| Debian 12 | LTS, je nach Architektur eingeschränkter Support | Migration auf Debian 13 planen |
| Ubuntu 26.04 LTS | aktuelle LTS | empfohlene Ubuntu-Wahl nach Prüfung der Anwendungskompatibilität |
| Ubuntu 24.04 LTS | Standardpflege bis 2029 | ausgezeichnete Wahl für einen bereits qualifizierten Stack |
| Ubuntu 22.04 LTS | Standardpflege bis 2027 | Versionswechsel einplanen |
| Version außerhalb des Supports | keine regulären Korrekturen mehr | migrieren; eine Firewall gleicht ein ungepflegtes System nicht aus |
Beurteilen Sie die Sicherheit eines Systems nicht allein anhand von uname -r. Debian und Ubuntu portieren Korrekturen zurück, ohne zwingend die neueste Upstream-Versionsnummer zu übernehmen. Prüfen Sie eine CVE im Debian Security Tracker oder in der Ubuntu-CVE-Übersicht, jeweils mit der tatsächlich installierten Distribution und dem installierten Paket.
Bedrohungsmodell: was diese Anleitung verringern soll
Ein öffentlicher VPS ist insbesondere automatisierten Scans und Anmeldeversuchen ausgesetzt, der Ausnutzung eines nicht korrigierten Dienstes oder einer Abhängigkeit, dem Diebstahl eines SSH-Schlüssels, eines API-Tokens oder eines Anwendungsgeheimnisses, einem Fehler bei Firewall, Rechten oder Docker-Portfreigabe, der Rechteausweitung nach Kompromittierung einer Anwendung, dem Löschen oder Verschlüsseln erreichbarer Daten und Sicherungen, dem Löschen der Protokolle durch einen Angreifer mit Administratorrechten sowie menschlichen Fehlern bei einem Update oder einer Netzwerkänderung.
Diese Grundlage macht den VPS nicht unverwundbar. Sie soll die Wahrscheinlichkeit eines Einbruchs senken, die Auswirkung eines ersten Zugriffs begrenzen, die Erkennung verbessern und einen kontrollierten Wiederaufbau ermöglichen.
Drei Reifegrade
| Stufe | Mindestmaßnahmen | Einsatz |
|---|---|---|
| Grundlage | Inventar, Updates, personenbezogenes Konto, SSH-Schlüssel, root und SSH-Passwort deaktiviert, Firewall, entfernte Sicherung | jeder exponierte VPS |
| Produktion | überwachte Updates, AppArmor, Fail2ban je nach Risiko, persistente und entfernte Protokolle, externe Alarme, getestete Wiederherstellung | Website oder Dienst im Produktivbetrieb |
| Verstärkt | Administration über VPN oder Bastion, FIDO2-Schlüssel oder MFA, durchdachte ausgehende Filterung, auditd/AIDE, Append-only-Sicherungsdepot, deklarative Konfiguration | sensible Daten oder hohe Anforderungen |
Nicht jede Maßnahme darf blind angewendet werden. Das Abschalten der IP-Weiterleitung etwa zerstört einen Router, ein VPN oder bestimmte Containernetze. Professionelle Härtung beginnt beim Kontext.
Vor jeder Änderung: sich nicht selbst aussperren
Bevor Sie SSH oder die Firewall anfassen:
- prüfen Sie, ob die Notfallkonsole des Anbieters funktioniert;
- lassen Sie die aktuelle SSH-Sitzung offen;
- öffnen Sie ein zweites Fenster, um jede Änderung zu testen;
- notieren Sie die tatsächliche SSH-Adresse und den Port;
- erstellen Sie vorsorglich einen Snapshot, sofern die Plattform das erlaubt;
- sichern Sie die geänderten Dateien;
- deaktivieren Sie den alten Zugang erst, nachdem der neue geprüft ist.
Ein vor der Änderung erstellter Snapshot erleichtert den betrieblichen Rückweg, ersetzt aber keine Sicherung außerhalb des VPS. Er kann inkonsistent sein, wenn eine Datenbank im selben Moment schreibt, und wird in der Regel weiterhin aus demselben Anbieterkonto verwaltet.
1. Das System vor der Härtung inventarisieren
Beginnen Sie mit einer rein lesenden Erhebung:
cat /etc/os-release
uname -a
hostnamectl
systemd-detect-virt
ip -brief address
ip route
ip -6 route
sudo ss -lntup
sudo systemctl --type=service --state=running --no-pager
sudo systemctl list-unit-files --state=enabled --no-pager
df -hT
df -ih
findmnt
timedatectl
ss -lntup listet die lauschenden Sockets auf. Für aufgebaute TCP-Verbindungen, auch ausgehende:
sudo ss -tpn state established
Legen Sie ein Betriebsdatenblatt an mit:
| Element | Zu erfassender Wert |
|---|---|
| Distribution und Version | Ausgabe von /etc/os-release |
| Kernel und Architektur | Ausgabe von uname -a |
| öffentliche IPv4 und IPv6 | tatsächlich geroutete Adressen |
| Hauptschnittstelle | Name, Adresse, Gateway |
| erwartete Ports | zum Beispiel TCP 22, 80 und 443 |
| erwartete Dienste | SSH, Nginx, Anwendung, Überwachungsagent |
| berechtigte Administratoren | personenbezogene Konten, Schlüssel und Netzherkunft |
| kritische Daten | Dateien, Datenbanken, Geheimnisse und Konfigurationen |
| RPO | maximal hinnehmbarer Datenverlust |
| RTO | maximal hinnehmbare Ausfalldauer |
Jeder Port ohne Eigentümer und Begründung ist zu untersuchen, bevor er geschlossen wird. Ein Dienst kann ausschließlich auf 127.0.0.1 lauschen, auf einer privaten Adresse, auf allen IPv4-Schnittstellen mit 0.0.0.0 oder auf IPv6 mit ::. Prüfen Sie beide Familien.
2. Personenbezogene Konten und minimale Rechte verwenden
Vermeiden Sie die tägliche Administration mit einem gemeinsam genutzten Konto oder direkt als root. Legen Sie ein Konto je Administrator an, damit Protokolle und Sperrungen zurechenbar bleiben.
Beispiel mit adminops:
sudo adduser adminops
sudo usermod -aG sudo adminops
sudo groupadd --force ssh-admins
sudo usermod -aG ssh-admins adminops
id adminops
getent group ssh-admins
Unter Debian und Ubuntu können Mitglieder der Gruppe sudo gemäß der lokalen Richtlinie Rechte erhalten. Ubuntu erläutert den Nutzen von sudo für die Nachvollziehbarkeit in seiner Dokumentation zur Benutzerverwaltung.
Erzeugen Sie auf dem Arbeitsplatz des Administrators einen modernen, durch eine Passphrase geschützten Schlüssel:
ssh-keygen -t ed25519 -a 100 -C "adminops@organisation"
ssh-copy-id -i ~/.ssh/id_ed25519.pub adminops@VPS_ADRESSE
Ed25519 ist die in der OpenSSH-Dokumentation von Ubuntu empfohlene Wahl. Die Option -a erhöht die Rundenzahl der Ableitungsfunktion, die den privaten Schlüssel über seine Passphrase schützt; sie ändert den Schlüsselalgorithmus nicht. Unsere Anleitung zum Konfigurieren eines SSH-Schlüssels auf einem Linux-VPS beschreibt das Vorgehen unter Windows, macOS und Linux.
Für eine verstärkte Stufe verlangt ein FIDO2-Schlüssel vom Typ ed25519-sk die Anwesenheit eines kompatiblen Hardware-Authentifikators:
ssh-keygen -t ed25519-sk -C "adminops-fido2@organisation"
Halten Sie eine getrennte, geschützte und getestete Wiederherstellungsmethode bereit. Ein einziger Hardwareschlüssel ohne Notfallverfahren macht seinen Verlust zu einem Verfügbarkeitsvorfall.
Testen Sie in einem neuen Fenster:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 adminops@VPS_ADRESSE
sudo -v
id
Fahren Sie nicht fort, solange Anmeldung per Schlüssel und sudo nicht funktionieren.
Bestehende Konten prüfen
getent passwd
awk -F: '($3 == 0) {print $1}' /etc/passwd
sudo lastlog
sudo passwd -S root
Normalerweise darf es nur eine einzige UID 0 geben. Sperren oder entfernen Sie überflüssig gewordene Konten, nachdem Sie ihre Dateien, geplanten Aufgaben, Prozesse und Anwendungsabhängigkeiten geprüft haben.
3. OpenSSH härten, ohne den Zugang zu unterbrechen
Ubuntu akzeptiert die Hauptkonfiguration in /etc/ssh/sshd_config und Fragmente in /etc/ssh/sshd_config.d/. Die Konfiguration bindet dieses Verzeichnis normalerweise am Anfang der Hauptdatei ein. OpenSSH übernimmt bei den meisten Direktiven den zuerst gefundenen Wert; eine Datei namens 00-hardening.conf ist daher berechenbarer als eine späte Datei, die hinter einem von cloud-init erzeugten Fragment landen könnte. Dieses Verhalten dokumentieren Ubuntu und das sshd_config-Handbuch von Debian.
Prüfen Sie zunächst die Einbindung:
grep -nE '^[[:space:]]*Include' /etc/ssh/sshd_config
sudo sshd -T | sort
Sichern Sie die Konfiguration:
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.before-hardening
sudo install -d -m 755 /etc/ssh/sshd_config.d
sudoedit /etc/ssh/sshd_config.d/00-hardening.conf
Fügen Sie hinzu:
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
AuthenticationMethods publickey
AllowGroups ssh-admins
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
PermitTunnel no
Vor dem Neuladen:
sudo sshd -t
sudo sshd -T | grep -E '^(port|permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|authenticationmethods|allowgroups|maxauthtries|logingracetime|x11forwarding|permittunnel) '
Existieren Match-Blöcke, prüfen Sie auch die Konfiguration, die für das Administrationskonto und dessen Adresse gilt:
sudo sshd -T \
-C user=adminops,host="$(hostname -f)",addr=198.51.100.10 |
grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|authenticationmethods|allowgroups) '
Die Adresse 198.51.100.10 stammt aus einem für Dokumentation reservierten Bereich. Ersetzen Sie sie durch die tatsächliche Adresse, von der aus der Administrator sich verbindet.
Gibt sshd -t nichts aus, ist die Syntax gültig. Laden Sie neu, ohne die aktuelle Sitzung zu schließen:
sudo systemctl reload ssh
sudo systemctl status ssh --no-pager
sudo journalctl -u ssh -n 50 --no-pager
Testen Sie sofort eine neue Verbindung mit dem Schlüssel und danach sudo -v. Schließen Sie die alte Sitzung erst nach diesem Test.
Was bedingt bleiben muss
AllowTcpForwarding noundAllowAgentForwarding nosind sinnvoll, wenn kein SSH-Tunnel und kein Sprungserver nötig sind, zerstören diese Anwendungen aber;- SSH auf eine IP-Adresse oder ein VPN zu beschränken senkt die Exposition erheblich, erfordert aber einen Notfallweg;
- der Wechsel von Port 22 verringert vor allem das Rauschen der Bots; er ersetzt weder Schlüssel noch Firewall noch Korrekturen;
- eine TOTP-MFA kann den Schlüssel ergänzen. Die Ubuntu-Dokumentation beschreibt die Kombination
AuthenticationMethods publickey,keyboard-interactivein ihrem TOTP/HOTP-Leitfaden.
4. Sicherheitsupdates einspielen und überwachen
Ein Befehl mit -y ist im Labor praktisch, doch eine erste produktive Härtung sollte erlauben, die vorgeschlagenen Änderungen zu lesen:
sudo apt update
apt list --upgradable
sudo apt-get -s upgrade
sudo apt upgrade
sudo apt autoremove --dry-run
Führen Sie apt autoremove erst nach Prüfung der Liste aus. Ein Distributionsupdate, ein Kernel, ein Treiber oder ein Fachpaket kann einen Neustart und einen Anwendungstest erfordern.
Automatische Korrekturen aktivieren
Auf Ubuntu Server ist unattended-upgrades installiert und die Sicherheitsupdates sind normalerweise standardmäßig aktiv. Setzen Sie das nicht voraus, sondern prüfen Sie es. Die Ubuntu-Dokumentation zu automatischen Updates nennt die Dateien, Timer, erlaubten Quellen und Protokolle.
Unter Debian installieren und aktivieren Sie den Mechanismus ausdrücklich gemäß Ihrer Richtlinie:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
systemctl list-timers 'apt-daily*' --all
sudo unattended-upgrade --dry-run --debug
sudo journalctl -u apt-daily-upgrade.service -n 100 --no-pager
Prüfen Sie insbesondere:
grep -RhsE 'APT::Periodic::(Update-Package-Lists|Unattended-Upgrade)' \
/etc/apt/apt.conf.d/
sudo sed -n '/Allowed-Origins/,/};/p' \
/etc/apt/apt.conf.d/50unattended-upgrades
Eine Fremdquelle ist nicht automatisch abgedeckt. Prüfen Sie, welche Depots die Pakete liefern:
grep -RhsE '^[[:space:]]*(deb |Types:|URIs:|Suites:|Signed-By:)' \
/etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null
apt-cache policy
Unter Debian 13 schlagen die Versionshinweise außerdem diese Suche nach installierten Paketen vor, die nicht von Debian stammen:
apt list '?narrow(?installed, ?not(?origin(Debian)))'
Ein für ein einziges Paket hinzugefügtes Depot erweitert die Vertrauenskette und kann auch Updates für andere Pakete liefern. Nutzen Sie offizielle oder Hersteller-Depots, einen eigenen Schlüssel über Signed-By, und entfernen Sie überflüssig gewordene Quellen. Führen Sie curl ... | sh nicht direkt aus, ohne das Skript herunterzuladen, zu prüfen und zu lesen.
Neustarts und Alarme
Unter Ubuntu wird ein empfohlener Neustart in der Regel so angezeigt:
if [ -f /var/run/reboot-required ]; then
cat /var/run/reboot-required
cat /var/run/reboot-required.pkgs 2>/dev/null
fi
Automatisierung ohne Überwachung ist unvollständig. Alarmieren Sie mindestens bei Fehlschlag des Update-Timers oder -Dienstes, beim Alter des letzten erfolgreichen Laufs, bei einem zu lange ausstehenden Neustart, bei einem zurückgehaltenen Paket oder einer nicht abgedeckten Quelle und bei einem System nahe dem Supportende.
5. Die Firewall einrichten: nur einen Verwalter wählen
Eine Firewall ist kein Inventarwerkzeug: Bestimmen Sie zuerst die legitimen Datenflüsse. Sie ergänzt die Härtung der Dienste, ersetzt sie aber nicht, wie das Debian-Sicherheitshandbuch betont.
Wählen Sie einen Hauptansatz:
| Kontext | Empfohlene Wahl |
|---|---|
| Ubuntu, einfache Regeln | UFW |
| Debian, native und fortgeschrittene Politik | nftables |
| Docker Engine | zuerst Docker-Ketten und -Grenzen studieren |
| Infrastruktur mit Anbieter-Firewall | Netzfilterung zusätzlich anwenden, ohne die lokale Firewall aufzugeben |
UFW ist das von Ubuntu dokumentierte Standardwerkzeug. nftables ist das von Debian empfohlene Standard-Framework. Stapeln Sie nicht UFW, ein manuelles nftables-Regelwerk und weitere Verwalter, ohne deren Reihenfolge zu verstehen.
Variante A: UFW unter Ubuntu oder für einen einfachen Bedarf
Ermitteln Sie den tatsächlichen SSH-Port:
sudo sshd -T | awk '$1 == "port" {print $2; exit}'
Das folgende Beispiel setzt SSH auf 22 sowie einen Webserver voraus. Passen Sie die Ports vor der Aktivierung an:
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH administration'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw show added
sudo ufw enable
sudo ufw status verbose
sudo ufw status numbered
Lassen Sie die Sitzung offen und testen Sie eine neue SSH-Verbindung.
Kommt die Administration von einer festen IPv4-Adresse, legen Sie zuerst eine einschränkende Regel an:
sudo ufw allow from 198.51.100.10 to any port 22 proto tcp \
comment 'SSH vom Administrationsrechner'
sudo ufw status numbered
Nach dem Test von dieser Adresse aus löschen Sie die für alle offene SSH-Regel über ihre Nummer:
sudo ufw delete REGELNUMMER
Wiederholen Sie die Logik für IPv6, wenn der Administrator es nutzt. Deaktivieren Sie IPv6 nicht bloß, um sich dessen Regeln zu ersparen: Ein vergessener AAAA-Eintrag oder eine IPv6-Schnittstelle kann eine andere Exposition schaffen als die über IPv4 getestete.
Unsere Anleitung zum Konfigurieren von UFW auf einem Linux-VPS behandelt die Regelverwaltung im Detail.
Variante B: nftables auf einem Debian-VPS ohne Docker
Das folgende Beispiel eignet sich für einen neuen Web-VPS, der kein Router ist, kein Docker betreibt und SSH auf 22 nutzt. Es ersetzt das gesamte Regelwerk: Verwenden Sie es nicht, wenn bereits andere Software netfilter verwaltet.
Sichern Sie zunächst den aktuellen Stand in eine Datei, die selbst mit einer Zurücksetzung des Regelwerks beginnt:
sudo sh -c '{
printf "%s\n" "flush ruleset"
nft list ruleset
} > /root/nftables.before-hardening.nft'
sudoedit /etc/nftables.conf
Inhalt:
#!/usr/sbin/nft -f
flush ruleset
define ssh_port = 22
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
iifname "lo" accept
ct state invalid drop
ct state established,related accept
ip protocol icmp accept
ip6 nexthdr ipv6-icmp accept
tcp dport $ssh_port ct state new accept comment "SSH"
tcp dport { 80, 443 } ct state new accept comment "Web"
counter drop
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
Nützliches ICMP und ICMPv6 zuzulassen verhindert, dass IPv6-Nachbarschaftserkennung, Diagnose und Pfad-MTU-Ermittlung zerstört werden. Übernehmen Sie keine Regel, die sämtliches ICMP blockiert, ohne diese Funktionen zu verstehen.
Prüfen Sie die Syntax vor dem Anwenden:
sudo nft -c -f /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo nft list ruleset
sudo systemctl enable nftables
Testen Sie eine neue SSH-Sitzung und den Webdienst. Rückweg von der Konsole aus:
sudo nft -f /root/nftables.before-hardening.nft
Auch die Rückfalldatei enthält flush ruleset: Ihr Laden ersetzt daher die aktuelle Politik, statt doppelte Regeln hinzuzufügen. Führen Sie diesen Rückweg über die Notfallkonsole aus, wenn SSH bereits unterbrochen ist.
Routet der VPS Verkehr, betreibt er ein VPN, nutzt er mehrere Schnittstellen oder Docker, entwerfen Sie die forward-Ketten und NAT für diese Architektur. Eine unangepasst übernommene drop-Politik kann den Dienst unterbrechen.
Eine Netzwerk-Firewall ergänzen
Bietet der Anbieter eine vorgelagerte Firewall, nutzen Sie sie als zweite Barriere: SSH nur von den Administrationsadressen oder dem VPN, HTTP/HTTPS aus dem Internet, wenn der Server öffentlich ist, Datenbanken und Verwaltungsoberflächen niemals für alle offen, konsistente IPv4- und IPv6-Regeln sowie eine getestete Notfallkonsole.
Vorgelagerte Filterung kann Verkehr blockieren, bevor er Ressourcen des VPS verbraucht. Sie sieht jedoch nicht zwingend containerinterne Netze und schützt keinen Dienst, der vom VPS selbst erreichbar ist.
6. Kritischer Fall: Docker und UFW- oder nftables-Regeln
Docker verändert Filter- und NAT-Regeln, um Containerports zu veröffentlichen. Die Dokumentation warnt, dass Verkehr zu einem veröffentlichten Port umgeleitet wird, bevor er die von UFW genutzten Ketten INPUT und OUTPUT erreicht; ein Docker-Port kann also erreichbar bleiben, obwohl eine UFW-Politik ihn scheinbar verweigert. Siehe die offizielle Seite Packet filtering and firewalls.
Erfassen Sie die Veröffentlichungen:
sudo docker ps --format 'table {{.Names}}\t{{.Ports}}'
sudo ss -lntup
sudo iptables -S DOCKER-USER 2>/dev/null
Der entscheidende Unterschied:
# Auf allen Schnittstellen des VPS veröffentlicht
ports:
- "8080:80"
# Nur vom VPS aus erreichbar, zum Beispiel über Nginx
ports:
- "127.0.0.1:8080:80"
Binden Sie den Port für eine Datenbank, Redis, eine Verwaltungsoberfläche oder eine Anwendung hinter einem Reverse Proxy an 127.0.0.1 oder eine private Adresse, wenn kein öffentlicher Zugriff nötig ist.
Docker empfiehlt die Kette DOCKER-USER für Regeln, die vor den eigenen iptables-Regeln greifen müssen. Vom Abschalten der iptables/ip6tables-Verwaltung rät Docker ab, da dies das Containernetzwerk in der Regel zerstört. Die Installationsdokumentation hält zudem fest, dass Docker Engine iptables-nft und iptables-legacy unterstützt, nicht jedoch ein direkt mit nft erstelltes Regelwerk als Docker-Filtermechanismus. Mischen Sie das obige nftables-Modell daher nicht ohne getestete Architektur mit Docker. Unsere Anleitung zum Installieren von Docker auf einem Linux-VPS behandelt Installation und Daemon-Konfiguration.
Scannen Sie nach jeder Container-Bereitstellung erneut aus einem externen Netz. Die Compose-Datei beschreibt die Absicht; das beobachtbare Netz beschreibt die Wirklichkeit.
7. Dienste, Pakete und Rechte reduzieren
Listen Sie die aktiven Units und die Ports auf:
sudo systemctl --type=service --state=running --no-pager
sudo systemctl list-unit-files --state=enabled --no-pager
sudo ss -lntup
Fragen Sie zu jedem Dienst: Ist er unverzichtbar? Muss er automatisch starten? Muss er auf einer öffentlichen Schnittstelle lauschen? Läuft er unter einem eigenen, nicht privilegierten Konto? Welche Dateien, Linux-Capabilities und Netze braucht er? Werden Protokoll und Zustand überwacht?
Anhalten und deaktivieren ist umsichtiger als sofortiges Entfernen:
sudo systemctl disable --now DIENSTNAME
sudo systemctl status DIENSTNAME --no-pager
Entfernen Sie das Paket nach einer Beobachtungsphase und einer Abhängigkeitsprüfung, wenn seine Entbehrlichkeit bestätigt ist.
Die Anwendung nicht als root ausführen
Ein Anwendungsdienst sollte ein eigenes Systemkonto, begrenzte Verzeichnisse und keine interaktive Shell nutzen, sofern diese nicht erforderlich ist. Datenbanken sollten auf loopback oder einer privaten Adresse lauschen, außer bei ausdrücklichem und gefiltertem Bedarf.
Analysieren Sie mit systemd zunächst den Grad der Abschottung:
sudo systemd-analyze security --no-pager NAME.service
sudo systemctl cat NAME.service
Der Wert von systemd-analyze security misst ausschließlich die dem Werkzeug bekannten systemd-Schutzmechanismen. Ein hoher Wert ist kein Beleg für eine Schwachstelle, und ein niedriger Wert validiert den Anwendungscode nicht. Das systemd-analyze-Handbuch betont diese Grenze.
Für eine interne, nicht JIT-basierte Anwendung, die nur in zwei Verzeichnisse schreibt, kann ein Drop-in so aussehen:
[Service]
User=myapp
Group=myapp
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
LockPersonality=yes
CapabilityBoundingSet=
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
ReadWritePaths=/var/lib/myapp /var/log/myapp
Legen Sie es an mit:
sudo systemctl edit NAME.service
sudo systemd-analyze verify NAME.service
sudo systemctl daemon-reload
sudo systemctl restart NAME.service
sudo systemctl status NAME.service --no-pager
sudo journalctl -u NAME.service -n 100 --no-pager
Wenden Sie die Optionen einzeln an. MemoryDenyWriteExecute=yes, ProtectHome=yes, die Beschränkung der Adressfamilien oder der Entzug von Capabilities können eine JIT-Laufzeit, ein Modul ladendes Programm oder einen Dienst mit besonderem Zugriffsbedarf zerstören. Die vollständige Referenz ist systemd.exec.
8. AppArmor beibehalten und kontrollieren
AppArmor setzt eine verbindliche Zugriffskontrolle je Programm durch. Unter Ubuntu ist es standardmäßig installiert und geladen. Prüfen Sie den Zustand:
sudo aa-status
systemctl status apparmor --no-pager
Die AppArmor-Dokumentation von Ubuntu unterscheidet insbesondere den Modus enforce, der unerlaubte Operationen blockiert und protokolliert, den Modus complain, der zum Erlernen eines Profils ohne Blockade dient, sowie eingeschränkte und profillose Prozesse.
Unter Debian ist AppArmor verfügbar, doch Aktivierung und vorhandene Profile hängen vom Abbild und vom Kernel ab:
sudo apt install apparmor apparmor-utils
sudo systemctl enable --now apparmor
sudo aa-status
Deaktivieren Sie AppArmor nicht, um eine Anwendung zu „reparieren“. Analysieren Sie die Verweigerungen:
sudo journalctl -k -g 'apparmor="DENIED"' --since today
Erstellen oder passen Sie ein Profil in der Vorproduktion an, versetzen Sie das betroffene Profil bei Bedarf vorübergehend in den Lernmodus und kehren Sie danach zu enforce zurück. Ein zu freizügiges oder im Modus complain belassenes Profil bietet nicht den erwarteten Schutz.
9. Fail2ban ergänzen, wenn der Dienst es rechtfertigt
Fail2ban liest Fehlschlagereignisse und ergänzt vorübergehend eine Sperrregel. Es senkt das Rauschen und einige wiederholte Angriffe, behebt aber weder ein schwaches Passwort noch eine Softwarelücke noch gestohlene Zugangsdaten.
Installation:
sudo apt update
sudo apt install fail2ban
sudoedit /etc/fail2ban/jail.d/sshd.local
Konfiguration für ein System mit systemd-Journal:
[sshd]
enabled = true
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
Das Backend systemd liest das Journal und darf keinen logpath erhalten. Parameter und Zeiteinheiten beschreibt das Debian-Handbuch jail.conf.
Vor dem Start prüfen:
sudo fail2ban-client -t
sudo systemctl enable --now fail2ban
sudo fail2ban-client ping
sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo journalctl -u fail2ban -n 100 --no-pager
Eine Ausnahmeliste ist nur für eine wirklich stabile und kontrollierte Adresse sinnvoll. Ein zu weiter Bereich umgeht genau die Kontrolle, die Sie gerade ergänzt haben. Prüfen Sie bei Docker außerdem, ob die gewählte Aktion in der Kette wirkt, die der Verkehr tatsächlich durchläuft.
Unsere Anleitung zum Installieren und Konfigurieren von Fail2ban behandelt aktuelle Debian-Protokolle, die SSH-Jail, das Entsperren und Filtertests.
10. Einige Kernelparameter vorsichtig härten
sysctl-Werte sollten nicht zu Hunderten aus einer generischen Checkliste übernommen werden. Der Linux-Kernel warnt, dass manche Einstellungen ein System unbrauchbar machen können, und empfiehlt, jede Anpassung zu verstehen.
Erfassen Sie zunächst die Werte:
sysctl kernel.dmesg_restrict
sysctl kernel.kptr_restrict
sysctl fs.protected_hardlinks
sysctl fs.protected_symlinks
sysctl fs.protected_fifos
sysctl fs.protected_regular
sysctl net.ipv4.conf.all.accept_redirects
sysctl net.ipv6.conf.all.accept_redirects
Für einen gewöhnlichen VPS-Host, der kein Router ist, lässt sich dieses zurückhaltende Fragment prüfen:
sudoedit /etc/sysctl.d/60-local-hardening.conf
# Die Preisgabe von Kernelinformationen begrenzen
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
# Objekte in gemeinsam genutzten temporaeren Verzeichnissen haerten
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.protected_fifos = 2
fs.protected_regular = 2
# Ein VPS-Host muss ICMP-Umleitungen normalerweise nicht annehmen
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# Er muss normalerweise keine IPv4-Umleitungen senden
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
Laden und prüfen:
sudo sysctl -p /etc/sysctl.d/60-local-hardening.conf
sudo sysctl --system
Die Kerneldokumentation beschreibt die IP-sysctls und die Dateisystem-sysctls.
Diese Anleitung erzwingt bewusst weder net.ipv4.ip_forward=0, weil Docker, WireGuard oder ein Router darauf angewiesen sein können, noch rp_filter=1, weil asymmetrisches Routing, manche VPNs und Policy Routing eine Untersuchung erfordern, noch das Abschalten von IPv6, noch das unumkehrbare Deaktivieren von Modulen oder kexec, noch eine BPF- oder io_uring-Einstellung ohne Bestandsaufnahme der Anwendungen und Agenten.
11. Protokolle persistent und auswertbar machen
Lokale Protokolle helfen bei der Diagnose, doch ein Angreifer mit root-Rechten kann sie ändern oder löschen. Die Strategie muss begrenzte lokale Aufbewahrung, eine verlässliche Uhr, entferntes Weiterleiten und Alarme verbinden.
Persistenz und Platzgrenze von journald
Legen Sie ein Fragment an:
sudo install -d -m 755 /etc/systemd/journald.conf.d
sudoedit /etc/systemd/journald.conf.d/60-persistent.conf
Beispiel, an die Plattengröße anzupassen:
[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=30day
Dann:
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
sudo journalctl --flush
sudo journalctl --disk-usage
sudo journalctl --verify
sudo journalctl -p warning..alert --since today
SystemMaxUse, SystemKeepFree und die Persistenz sind in journald.conf dokumentiert. Eine feste Grenze muss System und Anwendung genügend Platz lassen.
Spuren außerhalb des VPS zentralisieren
Leiten Sie bei einem Produktivserver mindestens SSH- und sudo-Anmeldungen, Kernel- und Firewallereignisse, Identitätsänderungen, Protokolle des Reverse Proxy und der Anwendung sowie die Ausgaben automatischer Updates, Sicherungen und Sicherheitsagenten weiter.
Zwei gängige Lösungen sind systemd-journal-upload zu systemd-journal-remote oder rsyslog zu einem Collector. systemd-journal-upload überträgt Journaleinträge; das Modul omfwd von rsyslog unterstützt UDP, TCP oder TLS und empfiehlt für moderne Installationen TCP mit TLS.
Eine ernsthafte Umsetzung muss den Collector per Zertifikat authentifizieren, dessen Namen und Zertifizierungsstelle prüfen, TLS statt Klartext-Syslog über UDP im Internet verwenden, Ereignisse während einer Unterbrechung zwischenspeichern, den Quell-VPS am Löschen der Archive des Collectors hindern, bei Abriss des Datenstroms oder Heartbeats alarmieren und die Protokolle vor unbefugtem Zugriff schützen, da sie oft sensible Daten enthalten.
Die Uhrzeit synchronisieren
timedatectl status
timedatectl timesync-status 2>/dev/null || true
systemctl status systemd-timesyncd chrony --no-pager 2>/dev/null || true
Nutzen Sie genau einen, korrekt konfigurierten Synchronisationsmechanismus. Eine Zeitabweichung erschwert die Korrelation von Ereignissen, Zertifikate, Token und mitunter die Authentifizierung.
12. Änderungen und Integrität prüfen
Linux Audit
auditd sammelt Ereignisse des Audit-Subsystems im Kernel. Debian liefert die Werkzeuge zum Speichern und Durchsuchen dieser Einträge, dokumentiert in den auditd-Handbüchern von Debian 13.
sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd
sudoedit /etc/audit/rules.d/50-local.rules
Minimale Grundlage:
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k privilege
-w /etc/sudoers.d -p wa -k privilege
-w /etc/ssh/sshd_config -p wa -k ssh_config
-w /etc/ssh/sshd_config.d -p wa -k ssh_config
Laden und prüfen:
sudo augenrules --check
sudo augenrules --load
sudo auditctl -s
sudo auditctl -l
sudo ausearch -k ssh_config -ts today -i
sudo aureport --auth --summary
Passen Sie die Regeln an die tatsächlich kritischen Dateien an. Ein übermäßiges Audit füllt die Platte und macht das Signal unbrauchbar. Richten Sie Rotation, Sättigungsalarm und entfernte Weiterleitung ein.
Paketprüfung und AIDE
Geänderte Paketdateien ermitteln:
sudo dpkg -V
Eine Ausgabe bedeutet nicht automatisch eine Kompromittierung: Konfigurationsdateien werden berechtigterweise geändert. Gleichen Sie sie mit Ihrer Konfigurationsverwaltung und Ihren freigegebenen Änderungen ab.
AIDE baut eine Integritätsdatenbank auf:
sudo apt install aide
sudo aideinit
sudo aide --check
Initialisieren Sie die Datenbank nur auf einem als sauber geltenden Server und nach der Härtung. Lesen Sie die Ausgabe von aideinit, um zu bestätigen, welche Datenbank auf Ihrer Distribution aktiv ist. Kopieren Sie die Referenzdatenbank oder zumindest deren Prüfsumme an einen geschützten Ort außerhalb des VPS; sonst kann ein Angreifer mit root sowohl die Dateien als auch ihre Referenz verändern.
Weder auditd noch AIDE sind ein vollwertiges EDR. Sie liefern zusätzliche Spuren und Integritätsprüfungen, sofern die Ergebnisse gelesen und geschützt werden.
13. Dateien, Schlüssel und Geheimnisse schützen
Suchen Sie nach Auffälligkeiten, ohne sie automatisch zu korrigieren:
sudo find /etc -xdev -type f -perm -0002 -ls
sudo find / -xdev \( -perm -4000 -o -perm -2000 \) -type f -print
sudo find /root /home -path '*/.ssh/authorized_keys' -type f \
-exec stat -c '%a %U:%G %n' {} \;
sudo find /etc/cron.d /etc/cron.daily /etc/cron.hourly \
/etc/cron.monthly /etc/cron.weekly /var/spool/cron \
-maxdepth 2 -type f -ls 2>/dev/null
systemctl list-timers --all --no-pager
Eine ungewöhnliche Berechtigung ist nicht zwangsläufig bösartig. Klären Sie Paket, Eigentümer und Zweck, bevor Sie etwas ändern.
Grundregeln: kein Geheimnis in Git, in einem Docker-Abbild, in einem in der Historie sichtbaren Befehl oder in einer URL; Geheimnisdateien nur für das benötigte Konto lesbar; eigene Token je Dienst und Umgebung; minimale Rechte bei DNS, Sicherung, Datenbank und API; geplante Rotation und sofortige Rotation nach einer Preisgabe; Entfernen veralteter authorized_keys; private Schlüssel niemals in eine Dokumentation oder ein Ticket kopieren.
Prüfen Sie für moderne systemd-Dienste die systemd-Credentials anstelle globaler Umgebungsvariablen. Eine Variable bleibt mitunter für privilegierte Prozesse sichtbar und kann in einer Diagnoseausgabe landen.
14. Öffentliche Dienste mit TLS verschlüsseln
HTTPS schützt den Verkehr zwischen Client und Server; es behebt keine verwundbare Anwendung. Für eine Nginx- oder Apache-Website müssen der DNS-A-Eintrag und, falls vorhanden, der AAAA-Eintrag auf den richtigen Server zeigen; die TCP-Ports 80 und 443 müssen je nach ACME-Challenge offen sein; die Erneuerung muss automatisiert und getestet sein; ein Alarm muss dem Ablauf vorausgehen; und HSTS sollte erst nach dauerhafter Bestätigung von HTTPS auf den betroffenen Namen aktiviert werden.
Folgen Sie unserer Anleitung zum Installieren eines Let's-Encrypt-SSL-Zertifikats mit Certbot und prüfen Sie danach:
sudo certbot certificates
sudo certbot renew --dry-run
systemctl list-timers '*certbot*' --all
openssl s_client \
-connect example.com:443 \
-servername example.com \
-verify_return_error </dev/null
Eine Weiterleitung von HTTP auf HTTPS ist für den Browser sinnvoll, doch halten Sie Port 80 erreichbar, wenn die Erneuerung per HTTP-01 davon abhängt. DNS-01 ist für ein Wildcard nötig und kann diese Abhängigkeit vermeiden, um den Preis eines zu schützenden DNS-API-Geheimnisses.
15. Eine wirklich wiederherstellbare Sicherung einrichten
Die ANSSI hält fest, dass Sicherungen bei Zwischenfällen unverzichtbar sind, und empfiehlt insbesondere eine 3-2-1-Politik: drei Kopien auf zwei verschiedenen Medien, davon eine offline. Sie verlangt außerdem, den maximal hinnehmbaren Datenverlust und die maximal hinnehmbare Ausfalldauer festzuschreiben, in ihrem Maßnahmenkatalog und ihrem Leitfaden zur Sicherung von Informationssystemen.
Archiv, Snapshot und Sicherung unterscheiden
| Mechanismus | Nützlich für | Grenze |
|---|---|---|
| tar-Archiv auf derselben Platte | punktuelle Dateikopie | verschwindet mit dem VPS oder der Platte |
| VPS-Snapshot | schneller Rückweg vor einer Änderung | gleiches Anbieterkonto, Anwendungskonsistenz zu prüfen |
| Replikation oder Synchronisation | Verfügbarkeit oder schnelle Kopie | repliziert auch Löschung und Beschädigung |
| versionierte Sicherung außer Haus | Wiederanlauf nach Ausfall, Fehler oder Kompromittierung | muss verschlüsselt, überwacht und wiederhergestellt werden |
| Offline- oder unveränderliche Kopie | Widerstand gegen Löschung und Ransomware | erfordert Aufbewahrungsrichtlinie und Tests |
Unsere VPS bieten optional automatische externe Backups: eine vollständige Kopie des VPS, täglich erstellt, in einem separaten europäischen Rechenzentrum gespeichert, mit Wiederherstellung per Klick und einem rotierenden Verlauf, dessen Tiefe Sie wählen. Zehn gleichzeitige Backups ergeben somit einen Verlauf von zehn Tagen, wobei jede neue Kopie die älteste ersetzt. Diese Option deckt bereits die Kopie außerhalb des Servers, die tägliche Frequenz und die schnelle Wiederherstellung ab.
Sie macht die beiden folgenden Vorkehrungen dennoch nicht überflüssig. Erstens ist die vollständige Kopie eines laufenden VPS für eine Datenbank nicht zwingend konsistent: Erzeugen Sie weiterhin unmittelbar davor einen Dump, wie unten beschrieben. Zweitens wird sie weiterhin aus demselben Anbieterkonto gesteuert wie der Server; halten Sie für den Fall einer Kompromittierung zusätzlich eine Kopie in einem getrennten Verwaltungsbereich vor, je nach Risiko append-only oder offline. Und testen Sie in jedem Fall die Wiederherstellung: Ein Verlauf von zehn Tagen ist erst dann etwas wert, wenn Sie geprüft haben, dass eine Wiederherstellung die Anwendung tatsächlich wieder startet.
Das Ziel vor dem Werkzeug festlegen
| Daten | RPO | RTO | Aufbewahrung |
|---|---|---|---|
| Systemkonfiguration | 24 h | 4 h | 30 Tage |
| Kundendateien | 1 h | 2 h | 30 Tage und 12 Monate |
| transaktionale Datenbank | 15 min | 1 h | Journale und tägliche Sicherungen |
| Sicherheitsprotokolle | je nach Richtlinie | sofortige Einsicht | 90 Tage oder geltende Anforderung |
Diese Werte bestimmen Häufigkeit und Technik. Eine tägliche Sicherung erfüllt kein RPO von fünfzehn Minuten.
Beispiel mit restic auf ein entferntes Ziel
restic verschlüsselt und dedupliziert Sicherungen. Es unterstützt mehrere Backends; das Beispiel nutzt SFTP. Installieren Sie das Distributionspaket:
sudo apt update
sudo apt install restic
sudo install -d -m 700 /root/.config/restic
sudo touch /root/.config/restic/password
sudo chown root:root /root/.config/restic/password
sudo chmod 600 /root/.config/restic/password
sudoedit /root/.config/restic/password
sudo touch /etc/restic-vps.env
sudo chown root:root /etc/restic-vps.env
sudo chmod 600 /etc/restic-vps.env
sudoedit /etc/restic-vps.env
Inhalt von /etc/restic-vps.env:
RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/vps-01
RESTIC_PASSWORD_FILE=/root/.config/restic/password
Die Passphrase muss lang und zufällig sein, in einem getrennten Verwalter liegen und getestet werden. Ohne sie ist das verschlüsselte Depot nicht wiederherstellbar.
Initialisieren Sie manuell aus einer root-Sitzung, nachdem Sie den SSH-Fingerabdruck des Sicherungsservers geprüft haben:
sudo -i
set -a
. /etc/restic-vps.env
set +a
restic init
restic backup /etc /srv /var/www /var/backups/databases
restic snapshots
restic check
exit
Die Sicherung des Datenverzeichnisses einer laufenden Datenbank ist nicht zwingend konsistent. Erzeugen Sie einen Dump oder nutzen Sie die vom Datenbankmodul empfohlene physische Methode samt Journalen.
Für MariaDB, wenn die lokale root-Authentifizierung über Socket eingerichtet ist:
sudo install -d -m 700 /var/backups/databases
sudo sh -c 'mariadb-dump --single-transaction --routines --events --triggers --all-databases | gzip -9 > "/var/backups/databases/mariadb-$(date -u +%F-%H%M%S).sql.gz"'
Für PostgreSQL:
sudo install -d -m 700 -o postgres -g postgres \
/var/backups/databases/postgresql
sudo -u postgres sh -c 'pg_dumpall | gzip -9 > "/var/backups/databases/postgresql/all-$(date -u +%F-%H%M%S).sql.gz"'
Testen Sie die Wiederherstellung in einer isolierten Datenbank. --single-transaction verbessert die Konsistenz transaktionaler MariaDB/InnoDB-Tabellen, ist aber keine universelle Garantie für jedes Modul und jede Operation.
Mit einem systemd-Timer automatisieren
Legen Sie /etc/systemd/system/restic-backup.service an:
[Unit]
Description=restic-Sicherung des VPS
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic-vps.env
ExecStart=/usr/bin/restic backup /etc /srv /var/www /var/backups/databases
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
Legen Sie /etc/systemd/system/restic-backup.timer an:
[Unit]
Description=Taegliche restic-Sicherung des VPS
[Timer]
OnCalendar=*-*-* 02:30:00
RandomizedDelaySec=30m
Persistent=true
[Install]
WantedBy=timers.target
Aktivieren und prüfen:
sudo systemd-analyze verify \
/etc/systemd/system/restic-backup.service \
/etc/systemd/system/restic-backup.timer
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo systemctl status restic-backup.service --no-pager
sudo journalctl -u restic-backup.service -n 100 --no-pager
systemctl list-timers restic-backup.timer --all
Der Datenbank-Dump muss unmittelbar vor diesem Dienst entstehen, durch eine eigene, mit Requires und After geordnete Unit oder durch einen Sicherungsorchestrator. Ein alter, jede Nacht mitgesicherter Dump erzeugt nur den Anschein von Aktualität.
Schreiben und Löschen trennen
Ein kompromittierter VPS sollte alte Sicherungen nicht löschen können. Erlaubt das Backend es, geben Sie dem VPS einen Append-only-Zugang. Führen Sie die Aufbewahrung von einem getrennten Administrationsrechner aus, der die Löschrechte besitzt:
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--prune
restic check --read-data-subset=5%
Die restic-Dokumentation zu forget und prune weist darauf hin, dass prune lange dauern kann, das Depot sperrt und geplant werden sollte. Sie empfiehlt außerdem eine Prüfung nach dem Aufräumen. Untersuchen Sie bei einem Append-only-Depot die besonderen Risiken der Aufbewahrungsrichtlinien und trennen Sie den Wartungsclient tatsächlich ab.
Eine Wiederherstellung testen
Mindestens vierteljährlich, auf einer isolierten Maschine:
sudo -i
set -a
. /etc/restic-vps.env
set +a
restic snapshots
install -d -m 700 /mnt/restic-restore-test
restic restore latest --target /mnt/restic-restore-test
exit
Prüfen Sie anschließend Vorhandensein und Rechte der Dateien, die Entschlüsselung mit den dokumentierten Zugangsdaten, das Einspielen der Datenbanken in ein Testmodul, den Start der Anwendung, die fachliche Stimmigkeit, die tatsächliche Wiederherstellungsdauer im Vergleich zum RTO sowie das Verfahren zum Neuaufbau eines leeren VPS.
Eine „erfolgreiche“ Sicherung bedeutet, dass der Vorgang beendet wurde. Eine verlässliche Sicherung bedeutet, dass eine brauchbare Wiederherstellung nachgewiesen wurde.
16. Den VPS von außen überwachen
Lokale Überwachung kann einen ausgeschalteten, isolierten oder vollständig kompromittierten VPS nicht melden. Nutzen Sie einen externen Dienst für die Verfügbarkeit und einen vom Server getrennten Alarmkanal.
| Kontrolle | Zu überwachendes Signal |
|---|---|
| Verfügbarkeit | TCP/HTTPS, erwarteter Inhalt, Latenz |
| TLS | Ablaufdatum, Kette und Name |
| System | CPU, Arbeitsspeicher, Swap, Last |
| Speicher | Platz, Inodes, Wachstum der Protokolle |
| Dienste | fehlgeschlagene systemd-Units, Neustarts |
| Netzwerk | neue Ports, ungewöhnliche Verbindungen |
| Sicherheit | SSH- und sudo-Fehlschläge, AppArmor-Verweigerungen, auditd |
| Updates | letzter Lauf, Fehlschlag, erforderlicher Neustart |
| Sicherungen | Alter des letzten Snapshots, auffällige Größe, Fehlschlag |
| Zeit | Abweichung oder Verlust der Synchronisation |
Befehle zur täglichen Kontrolle:
systemctl --failed --no-pager
df -hT
df -ih
free -h
uptime
sudo ss -lntup
sudo journalctl -p warning..alert --since '-24 hours'
sudo journalctl -u ssh --since '-24 hours'
sudo fail2ban-client status sshd 2>/dev/null || true
sudo aa-status 2>/dev/null || true
Die Schwellenwerte müssen den Dienst abbilden. Ein Alarm bei 80 % Plattenbelegung nützt nur, wenn er im Verhältnis zur Wachstumsgeschwindigkeit früh genug kommt. Alarmieren Sie auch beim Ausbleiben von Daten: Ein stummer Agent kann ausgefallen sein.
Die ANSSI definiert Sicherheitsüberwachung als die Gesamtheit der Mittel, mit denen sich eine angemessene Reaktion erkennen, bewerten und auswählen lässt; ihr Leitfaden Ein Überwachungsprojekt steuern ordnet die Werkzeuge in diesen Prozess ein.
17. Das Ergebnis prüfen, statt der Konfiguration zu vertrauen
Lokale Kontrollen
# System und Korrekturen
cat /etc/os-release
apt list --upgradable
systemctl list-timers 'apt-daily*' --all
# Tatsaechliche SSH-Konfiguration
sudo sshd -t
sudo sshd -T | grep -E '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|authenticationmethods|allowgroups) '
# Netzexposition
sudo ss -lntup
sudo ufw status verbose 2>/dev/null || true
sudo nft list ruleset 2>/dev/null || true
# Sicherheitskontrollen
sudo aa-status 2>/dev/null || true
sudo fail2ban-client status 2>/dev/null || true
sudo auditctl -s 2>/dev/null || true
# Journal und Dienste
sudo journalctl --verify
systemctl --failed --no-pager
# Sicherung
sudo systemctl status restic-backup.service --no-pager
Externer Scan
Von einem Rechner, den Sie verwalten, und ausschließlich gegen Ihren eigenen VPS:
sudo nmap -Pn -sS -sV -p- VPS_IPV4_ADRESSE
sudo nmap -6 -Pn -sT -sV -p- VPS_IPV6_ADRESSE
Vergleichen Sie das Ergebnis mit der Liste der erlaubten Ports. Die Optionsreferenz steht im Nmap-Handbuch.
Scannen Sie nach der ersten Härtung, nach der Installation von Docker oder einer Verwaltungsoberfläche, nach einer Firewalländerung, nach einer Netzmigration und regelmäßig aus dem Internet.
Abnahmetabelle
| Test | Erwartetes Ergebnis | Aufzubewahrender Nachweis |
|---|---|---|
| SSH-Anmeldung per Schlüssel | Erfolg mit personenbezogenem Konto | anonymisiertes SSH-Protokoll |
| SSH-Anmeldung als root | abgelehnt | Auszug aus dem Test |
| SSH-Passwort | abgelehnt | Befehl und Ergebnis |
| sudo | Erfolg für den berechtigten Administrator | sudo-Protokoll |
| SSH-Syntax | sshd -t ohne Fehler | Datum und Version |
| externe Ports | nur die freigegebenen Datenflüsse | Nmap-Bericht für IPv4 und IPv6 |
| automatische Updates | gültiger Trockenlauf, aktiver Timer | Protokoll |
| Firewall | Politik und Regeln wie vorgesehen | UFW- oder nftables-Export |
| AppArmor | aktiv, kritische Profile in enforce | Ausgabe von aa-status |
| Sicherung | Lauf ohne Fehler | Protokoll und restic-Snapshot |
| Wiederherstellung | Anwendung und Daten lesbar | datiertes Protokoll |
| entfernte Protokolle | Ereignis empfangen und mit Zeitstempel | Suche auf der Collector-Seite |
| Notfallkonsole | Verbindung möglich | Datum des letzten Tests |
18. Was tun bei Verdacht auf Kompromittierung?
Symptome wie eine CPU-Spitze, ein unbekannter Prozess oder eine ungewöhnliche ausgehende Verbindung rechtfertigen eine Bewertung, beweisen für sich genommen aber keinen Einbruch. Umgekehrt beweist das Fehlen von Symptomen keine Integrität.
Erste Maßnahmen, der Schwere anzupassen:
- nutzen Sie einen vertrauenswürdigen Rechner und eröffnen Sie ein Vorfallprotokoll;
- isolieren Sie den VPS mit der Netzwerk-Firewall, sofern dies keine Spuren vernichtet;
- vermeiden Sie Neustarts oder „Aufräumen“ vor der Beweissicherung, wenn eine Untersuchung geplant ist;
- sichern Sie die entfernten Protokolle, den Zustand der Prozesse, die Verbindungen, die geplanten Aufgaben und einen forensischen Snapshot;
- widerrufen Sie von einem gesunden System aus die betroffenen SSH-Schlüssel, Passwörter, Token, Zertifikate und Anbieterzugänge;
- schützen Sie frühere Sicherungen und verhindern Sie deren Löschung;
- bestimmen Sie den Umfang: weitere VPS, Git-Depot, CI/CD, DNS, Konten und Datenbanken;
- bauen Sie aus einem als sauber geltenden Abbild und einer sauberen Konfiguration neu auf;
- stellen Sie ausschließlich geprüfte Daten wieder her;
- beheben Sie die Ursache vor der Wiederinbetriebnahme und verstärken Sie die Überwachung.
Ein Snapshot des verdächtigen Servers dient dazu, einen Zustand zu bewahren oder zu analysieren; er wird dadurch nicht automatisch zu einem sauberen Wiederherstellungspunkt. Das CERT-FR empfiehlt insbesondere, Beweise zu sichern, die Ausbreitung zu begrenzen, die Sicherungen in Sicherheit zu bringen und ein kompromittiertes System durch ein neues oder neu installiertes zu ersetzen. Siehe Die richtigen Reflexe bei einem Einbruch.
NIST SP 800-61 Revision 3, veröffentlicht im April 2025, bettet die Vorfallbehandlung in das gesamte Risikomanagement ein: Vorbereitung, Erkennung, Reaktion und Wiederherstellung beginnen nicht am Tag des Angriffs.
Empfohlener Betriebskalender
| Häufigkeit | Maßnahmen |
|---|---|
| fortlaufend | externe Verfügbarkeit, Metriken, Sicherheitsalarme, Sicherungsfehler |
| täglich | Sicherheitsupdates, Sicherung, Prüfung fehlgeschlagener Dienste |
| wöchentlich | Durchsicht von Alarmen, Ports, Speicherplatz, Konten und Änderungen |
| monatlich | Durchsicht von Depots, Paketen, Schlüsseln, Firewallregeln und Versionen |
| vierteljährlich | vollständig getestete Wiederherstellung, Notfallkonsole, Vorfallübung |
| halbjährlich | Durchsicht von Architektur, Rechten, RPO/RTO und externer Exposition |
| bei jeder Änderung | Sicherung, Validierung, externer Scan, Dokumentation und Rückweg |
Verwalten Sie diese Grundlage bei mehreren VPS mit Ansible, einem versionierten Depot und einer CI, die die Syntax prüft. Geheimnisse gehören nicht ins Depot. Eine deklarative Konfiguration ersetzt keine Tests in der realen Umgebung, macht Abweichungen und Rückwege aber besser beherrschbar.
Häufige Fehler
- SSH schließen, bevor der Schlüssel getestet ist. Halten Sie eine Sitzung und die Anbieterkonsole bereit.
- UFW für Port 22 öffnen, während SSH woanders lauscht. Prüfen Sie
sshd -T. - Ein SSH-Fragment so benennen, dass es spät greift. Meist gewinnt der erste Wert; prüfen Sie die tatsächliche Konfiguration.
- IPv6 vergessen. Scannen und filtern Sie IPv4 und IPv6 getrennt.
- Glauben, UFW filtere Docker automatisch. Veröffentlichte Ports erfordern eine eigene Kontrolle.
- Fail2ban ohne Prüfung der Jail installieren. Kontrollieren Sie
status sshdund die Protokolle. - Ein generisches sysctl aktivieren. Eine Netzeinstellung kann VPN, Routing oder Container zerstören.
- Auf dieselbe Platte sichern. Ein Ausfall oder eine Kompromittierung nimmt Original und Kopie zugleich mit.
- Nie wiederherstellen. Ein grüner Job garantiert weder Passwort noch Konsistenz noch Zeitrahmen.
- Alle Protokolle lokal halten. root kann sie löschen; leiten Sie kritische Ereignisse weiter.
- Die Anwendung als root ausführen. Eine Anwendungslücke wird sofort zur Systemkompromittierung.
- Upstream-Version und CVE-Status verwechseln. Prüfen Sie den Tracker der Distribution.
Häufige Fragen
Sichert ein anderer SSH-Port den VPS ab?
Er senkt das Rauschen opportunistischer Scans und die Protokollmenge, fügt aber keine Authentifizierungsbarriere hinzu. Ein geschützter Schlüssel, ein Nicht-root-Konto, die Netzbeschränkung und die Korrekturen haben Vorrang.
Ist Fail2ban noch nützlich, wenn SSH-Passwörter deaktiviert sind?
Es kann das Rauschen und einige wiederholte Versuche verringern. Seine Bedeutung sinkt, wenn SSH nur über VPN oder aus einer Adressliste erreichbar ist, doch es ersetzt keine dieser Maßnahmen.
Braucht Linux ein Antivirenprogramm?
Das hängt vom Dienst ab. ClamAV kann hochgeladene Dateien oder E-Mails prüfen. Ein EDR-Agent kann auf einem sensiblen Server Telemetrie und Reaktion liefern. Kein Antivirenprogramm gleicht ein ungepatchtes System, eine als root laufende Anwendung oder preisgegebene Geheimnisse aus.
UFW oder nftables?
UFW passt zu einer einfachen Politik und ist das von Ubuntu dokumentierte Standardwerkzeug. nftables ist das von Debian empfohlene native Framework und bietet mehr Kontrolle. Wählen Sie einen einzigen Eigentümer des Regelwerks und berücksichtigen Sie Docker.
Kann man IPv6 abschalten?
Das ist keine generische Härtungsmaßnahme. Filtern und überwachen Sie IPv6 wie IPv4. IPv6 abzuschalten kann Abhängigkeiten zerstören und ein mangelndes Netzverständnis verdecken.
Genügt ein Snapshot des Anbieters?
Ein Snapshot ist für einen schnellen Rückweg wertvoll, bleibt aber meist im selben Verwaltungsbereich, und seine Anwendungskonsistenz muss geprüft werden. Halten Sie zusätzlich eine versionierte Sicherung außer Haus vor, je nach Risiko mit einer Offline- oder unveränderlichen Kopie. Unsere optionalen externen Backups gehen weiter als ein bloßer Snapshot, da sie täglich erfolgen und in einem anderen Rechenzentrum liegen, werden aber weiterhin aus Ihrem Kundenkonto gesteuert: Halten Sie gegen das Kompromittierungsrisiko eine Kopie in einem getrennten Verwaltungsbereich vor.
Woran erkennt man eine Kompromittierung des VPS?
Es gibt keinen einzelnen Befehl. Korrelieren Sie Verbindungen, Prozesse, Konten, Schlüssel, geplante Aufgaben, entfernte Protokolle, Dateiänderungen, Verkehr und Alarme. Sichern Sie bei ernstem Verdacht die Beweise, widerrufen Sie die Geheimnisse und bauen Sie von einer sauberen Basis neu auf.
Können automatische Updates die Produktion zerstören?
Jede Änderung birgt ein Risiko. Das Risiko, eine Korrektur nicht einzuspielen, ist oft größer, doch eine kritische Anwendung verlangt Vorproduktion, Wartungsfenster, gezielte Sperren wo begründet, Überwachung und einen Rückweg. Ubuntu weist darauf hin, dass unattended-upgrades kein vollständiges Werkzeug zur Flottenverwaltung ist.
Macht diese Anleitung den VPS ANSSI- oder CIS-konform?
Nein. Sie stützt sich auf anerkannte Grundsätze und Quellen, doch Konformität verlangt Geltungsbereich, Niveau, Nachweise, Ausnahmen und ein Audit. Benchmarks müssen an die Rolle des Servers angepasst werden; ihre automatische Anwendung kann legitime Funktionen unterbrechen.
Abschließende Checkliste
Identitäten und SSH
- ein personenbezogenes Konto je Administrator;
- geschützte Ed25519- oder FIDO2-Schlüssel;
sudogetestet;PermitRootLogin nowirksam;- Passwort und keyboard-interactive deaktiviert, sofern ungenutzt;
- SSH-Gruppe ausdrücklich berechtigt;
- Konfiguration mit
sshd -tundsshd -Tgeprüft; - Notfallkonsole getestet.
System und Netzwerk
- Distribution weiterhin gepflegt;
- Korrekturen eingespielt und Automatisierung überwacht;
- Fremddepots erfasst;
- IPv4- und IPv6-Ports begründet;
- lokale Firewall aktiv;
- Netzwerk-Firewall konfiguriert, sofern verfügbar;
- Docker-Freigaben aus dem Internet geprüft;
- überflüssige Dienste deaktiviert.
Auswirkungen begrenzen
- Anwendungen unter eigenen Konten;
- AppArmor aktiv und Verweigerungen ausgewertet;
- systemd-Dienste bedarfsgerecht abgeschottet;
- Geheimnisse mit minimalen Rechten;
- Berechtigungen und Schlüssel geprüft;
- sysctl an die Rolle angepasst, ohne blindes Kopieren.
Erkennung und Wiederanlauf
- persistente Protokolle mit Platzgrenze;
- synchronisierte Uhr;
- kritische Ereignisse außerhalb des VPS;
- auditd und AIDE, wenn das Risiko es rechtfertigt;
- externe Überwachung und getrennter Alarmkanal;
- verschlüsselte, versionierte Sicherungen außer Haus;
- getrennte Löschrechte oder unveränderlicher Speicher;
- echte Wiederherstellung getestet und gemessen;
- Vorfallverfahren und Kontakte offline verfügbar.
Weiterführende Anleitungen
Diese Anleitung ist die übergreifende Grundlage. Die ausführlichen Verfahren stehen in unseren eigenen Leitfäden: einen SSH-Schlüssel konfigurieren, UFW konfigurieren, Fail2ban installieren, Docker installieren und ein Let's-Encrypt-Zertifikat mit Certbot installieren. Wenn Sie von einem Shared Hosting kommen, beschreibt unsere Anleitung zum Migrieren einer Website auf einen VPS den vollständigen Umzug.
Wichtigste Quellen
Allgemeine Empfehlungen
- ANSSI: Konfigurationsempfehlungen für ein GNU/Linux-System
- ANSSI: Sicherung von Informationssystemen
- CERT-FR: die richtigen Reflexe bei einem Einbruch
- NIST SP 800-61 Rev. 3: Incident Response Recommendations
Debian und Ubuntu
- Debian 13 „trixie“
- Debian Administrator's Handbook
- Debian: nftables
- Ubuntu: Lebenszyklus
- Ubuntu Server: OpenSSH
- Ubuntu Server: Firewalls
- Ubuntu Server: AppArmor
- Ubuntu Server: automatische Updates
