Linux29. August 2026 66 Aufrufe

Einen Linux-VPS in 2026 absichern: Härtungsleitfaden für Debian und Ubuntu

Einen Linux-VPS in 2026 absichern: Härtungsleitfaden für Debian und Ubuntu

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.

SystemStand am 31. August 2026Empfohlene Entscheidung
Debian 13aktuelle Stableempfohlene Debian-Wahl für eine Neuinstallation
Debian 12LTS, je nach Architektur eingeschränkter SupportMigration auf Debian 13 planen
Ubuntu 26.04 LTSaktuelle LTSempfohlene Ubuntu-Wahl nach Prüfung der Anwendungskompatibilität
Ubuntu 24.04 LTSStandardpflege bis 2029ausgezeichnete Wahl für einen bereits qualifizierten Stack
Ubuntu 22.04 LTSStandardpflege bis 2027Versionswechsel einplanen
Version außerhalb des Supportskeine regulären Korrekturen mehrmigrieren; 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

StufeMindestmaßnahmenEinsatz
GrundlageInventar, Updates, personenbezogenes Konto, SSH-Schlüssel, root und SSH-Passwort deaktiviert, Firewall, entfernte Sicherungjeder exponierte VPS
Produktionüberwachte Updates, AppArmor, Fail2ban je nach Risiko, persistente und entfernte Protokolle, externe Alarme, getestete WiederherstellungWebsite oder Dienst im Produktivbetrieb
VerstärktAdministration über VPN oder Bastion, FIDO2-Schlüssel oder MFA, durchdachte ausgehende Filterung, auditd/AIDE, Append-only-Sicherungsdepot, deklarative Konfigurationsensible 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:

  1. prüfen Sie, ob die Notfallkonsole des Anbieters funktioniert;
  2. lassen Sie die aktuelle SSH-Sitzung offen;
  3. öffnen Sie ein zweites Fenster, um jede Änderung zu testen;
  4. notieren Sie die tatsächliche SSH-Adresse und den Port;
  5. erstellen Sie vorsorglich einen Snapshot, sofern die Plattform das erlaubt;
  6. sichern Sie die geänderten Dateien;
  7. 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:

ElementZu erfassender Wert
Distribution und VersionAusgabe von /etc/os-release
Kernel und ArchitekturAusgabe von uname -a
öffentliche IPv4 und IPv6tatsächlich geroutete Adressen
HauptschnittstelleName, Adresse, Gateway
erwartete Portszum Beispiel TCP 22, 80 und 443
erwartete DiensteSSH, Nginx, Anwendung, Überwachungsagent
berechtigte Administratorenpersonenbezogene Konten, Schlüssel und Netzherkunft
kritische DatenDateien, Datenbanken, Geheimnisse und Konfigurationen
RPOmaximal hinnehmbarer Datenverlust
RTOmaximal 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 no und AllowAgentForwarding no sind 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-interactive in 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:

KontextEmpfohlene Wahl
Ubuntu, einfache RegelnUFW
Debian, native und fortgeschrittene Politiknftables
Docker Enginezuerst Docker-Ketten und -Grenzen studieren
Infrastruktur mit Anbieter-FirewallNetzfilterung 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

MechanismusNützlich fürGrenze
tar-Archiv auf derselben Plattepunktuelle Dateikopieverschwindet mit dem VPS oder der Platte
VPS-Snapshotschneller Rückweg vor einer Änderunggleiches Anbieterkonto, Anwendungskonsistenz zu prüfen
Replikation oder SynchronisationVerfügbarkeit oder schnelle Kopierepliziert auch Löschung und Beschädigung
versionierte Sicherung außer HausWiederanlauf nach Ausfall, Fehler oder Kompromittierungmuss verschlüsselt, überwacht und wiederhergestellt werden
Offline- oder unveränderliche KopieWiderstand gegen Löschung und Ransomwareerfordert 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

DatenRPORTOAufbewahrung
Systemkonfiguration24 h4 h30 Tage
Kundendateien1 h2 h30 Tage und 12 Monate
transaktionale Datenbank15 min1 hJournale und tägliche Sicherungen
Sicherheitsprotokolleje nach Richtliniesofortige Einsicht90 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.

KontrolleZu überwachendes Signal
VerfügbarkeitTCP/HTTPS, erwarteter Inhalt, Latenz
TLSAblaufdatum, Kette und Name
SystemCPU, Arbeitsspeicher, Swap, Last
SpeicherPlatz, Inodes, Wachstum der Protokolle
Dienstefehlgeschlagene systemd-Units, Neustarts
Netzwerkneue Ports, ungewöhnliche Verbindungen
SicherheitSSH- und sudo-Fehlschläge, AppArmor-Verweigerungen, auditd
Updatesletzter Lauf, Fehlschlag, erforderlicher Neustart
SicherungenAlter des letzten Snapshots, auffällige Größe, Fehlschlag
ZeitAbweichung 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

TestErwartetes ErgebnisAufzubewahrender Nachweis
SSH-Anmeldung per SchlüsselErfolg mit personenbezogenem Kontoanonymisiertes SSH-Protokoll
SSH-Anmeldung als rootabgelehntAuszug aus dem Test
SSH-PasswortabgelehntBefehl und Ergebnis
sudoErfolg für den berechtigten Administratorsudo-Protokoll
SSH-Syntaxsshd -t ohne FehlerDatum und Version
externe Portsnur die freigegebenen DatenflüsseNmap-Bericht für IPv4 und IPv6
automatische Updatesgültiger Trockenlauf, aktiver TimerProtokoll
FirewallPolitik und Regeln wie vorgesehenUFW- oder nftables-Export
AppArmoraktiv, kritische Profile in enforceAusgabe von aa-status
SicherungLauf ohne FehlerProtokoll und restic-Snapshot
WiederherstellungAnwendung und Daten lesbardatiertes Protokoll
entfernte ProtokolleEreignis empfangen und mit ZeitstempelSuche auf der Collector-Seite
NotfallkonsoleVerbindung möglichDatum 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:

  1. nutzen Sie einen vertrauenswürdigen Rechner und eröffnen Sie ein Vorfallprotokoll;
  2. isolieren Sie den VPS mit der Netzwerk-Firewall, sofern dies keine Spuren vernichtet;
  3. vermeiden Sie Neustarts oder „Aufräumen“ vor der Beweissicherung, wenn eine Untersuchung geplant ist;
  4. sichern Sie die entfernten Protokolle, den Zustand der Prozesse, die Verbindungen, die geplanten Aufgaben und einen forensischen Snapshot;
  5. widerrufen Sie von einem gesunden System aus die betroffenen SSH-Schlüssel, Passwörter, Token, Zertifikate und Anbieterzugänge;
  6. schützen Sie frühere Sicherungen und verhindern Sie deren Löschung;
  7. bestimmen Sie den Umfang: weitere VPS, Git-Depot, CI/CD, DNS, Konten und Datenbanken;
  8. bauen Sie aus einem als sauber geltenden Abbild und einer sauberen Konfiguration neu auf;
  9. stellen Sie ausschließlich geprüfte Daten wieder her;
  10. 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äufigkeitMaßnahmen
fortlaufendexterne Verfügbarkeit, Metriken, Sicherheitsalarme, Sicherungsfehler
täglichSicherheitsupdates, Sicherung, Prüfung fehlgeschlagener Dienste
wöchentlichDurchsicht von Alarmen, Ports, Speicherplatz, Konten und Änderungen
monatlichDurchsicht von Depots, Paketen, Schlüsseln, Firewallregeln und Versionen
vierteljährlichvollständig getestete Wiederherstellung, Notfallkonsole, Vorfallübung
halbjährlichDurchsicht von Architektur, Rechten, RPO/RTO und externer Exposition
bei jeder ÄnderungSicherung, 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

  1. SSH schließen, bevor der Schlüssel getestet ist. Halten Sie eine Sitzung und die Anbieterkonsole bereit.
  2. UFW für Port 22 öffnen, während SSH woanders lauscht. Prüfen Sie sshd -T.
  3. Ein SSH-Fragment so benennen, dass es spät greift. Meist gewinnt der erste Wert; prüfen Sie die tatsächliche Konfiguration.
  4. IPv6 vergessen. Scannen und filtern Sie IPv4 und IPv6 getrennt.
  5. Glauben, UFW filtere Docker automatisch. Veröffentlichte Ports erfordern eine eigene Kontrolle.
  6. Fail2ban ohne Prüfung der Jail installieren. Kontrollieren Sie status sshd und die Protokolle.
  7. Ein generisches sysctl aktivieren. Eine Netzeinstellung kann VPN, Routing oder Container zerstören.
  8. Auf dieselbe Platte sichern. Ein Ausfall oder eine Kompromittierung nimmt Original und Kopie zugleich mit.
  9. Nie wiederherstellen. Ein grüner Job garantiert weder Passwort noch Konsistenz noch Zeitrahmen.
  10. Alle Protokolle lokal halten. root kann sie löschen; leiten Sie kritische Ereignisse weiter.
  11. Die Anwendung als root ausführen. Eine Anwendungslücke wird sofort zur Systemkompromittierung.
  12. 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;
  • sudo getestet;
  • PermitRootLogin no wirksam;
  • Passwort und keyboard-interactive deaktiviert, sofern ungenutzt;
  • SSH-Gruppe ausdrücklich berechtigt;
  • Konfiguration mit sshd -t und sshd -T geprü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

Debian und Ubuntu

Komponenten