← Alle Beiträge
Sicherheit & Infrastruktur

Sicherheit geht vor. Oder doch eher nach?

24. Mai 2026 9 Min. Lesezeit

Es war ein ganz normaler Dienstagmorgen. Kaffee, Laptop aufgeklappt, und dann das: Verbindung fehlgeschlagen. Timeout. Nochmal versuchen. Wieder nichts. Mein gewohnter ssh root@<IP> hing einfach in der Luft, als würde die Anfrage ins Nichts verschwinden.

Ich war zu dem Zeitpunkt im Urlaub in Kroatien, entspannt irgendwo zwischen Adriaküste und kroatischer Sommerküche und das letzte, womit ich mich beschäftigen wollte, war ein nicht erreichbarer Server. Meine erste Vermutung war naheliegend: Hotel-WLAN. Wer kennt es nicht? Diese merkwürdigen Captive-Portal-Geschichten, Application-Layer-Firewalls, die selektiv bestimmte Ports blocken, irgendwelche Deep-Packet-Inspection-Spielereien, die ein Hotelnetzwerk gelegentlich zur Blackbox machen. SSH auf Port 22 ist durchaus das, was manche Netzwerkadmins in öffentlichen Netzen sperren. Ich schob das Problem zur Seite und genoss den Rest des Urlaubs.

Aber dann kam ich nach Hause. Gleiche IP, gleicher Befehl, gleicher Timeout. Das war kein Hotel-WLAN mehr. Das war mein Heimnetz. Das war mein übliches Setup. Und es funktionierte trotzdem nicht.

Notlösung mit Hindernissen

Was bleibt, wenn SSH versagt? Der Umweg über die Remote-Konsole meines Hosting-Anbieters IONOS. Wer damit schon gearbeitet hat, weiß: Es ist kein Vergnügen.

Die Konsole ist browserbasiert, die Tastatureingaben laufen über eine Art virtuelle Maschine, und zusätzlich ist das Tastaturlayout amerikanisch (QWERTY), was gerade bei Bash-Befehlen super ätzend ist, da die Sonderzeichen oft an anderen Stellen liegen als gewohnt. Das Schmerzhafteste daran: kein Einfügen per Strg+V. Jeder Befehl, jede IP-Adresse, jeder lange Konfigurationspfad muss Zeichen für Zeichen getippt werden. Bei kurzen Befehlen noch erträglich, bei längeren Konfigurationsblöcken eine echte Geduldsprobe. Dennoch war es das einzige Werkzeug, das mir in dieser Situation zur Verfügung stand. Also ran an die Arbeit.

Was die Logs erzählten

Schon der erste Blick in die Auth-Logs war ernüchternd und gleichzeitig aufschlussreich. systemctl status sshd zeigte schnell, dass etwas nicht stimmte. Ein Blick in die Logs bestätigte den Verdacht: grep "Failed password" /var/log/auth.log spuckte Hunderte, wenn nicht Tausende von Einträgen aus. Bots. Zahllose Bots. Automatisierte Skripte, die systematisch Nutzernamen und Passwörter durchprobieren: root, admin, ubuntu, pi, test, deploy. Ein klassischer Brute-Force-Angriff auf SSH.

Das ist kein ungewöhnliches Phänomen. Jeder Server, der mit einer öffentlichen IP-Adresse im Internet hängt und SSH auf dem Standardport 22 laufen hat, wird innerhalb weniger Minuten nach dem ersten Start von Bots gefunden und attackiert. Suchmaschinen wie Shodan indizieren offene Ports kontinuierlich, und Botnetze nutzen diese Daten, um automatisiert Login-Versuche zu starten. Mein Server war also nicht gezielt angegriffen worden, er war einfach Teil der täglichen Grundrauschen im Internet.

Das Gute: Mein Root-Passwort war kein root123. Das Schlechte: Alles andere war noch ziemlich nah an den Standardeinstellungen.

Aber zurück zum ursprünglichen Problem: dem Timeout. Während ich mich durch Firewall-Regeln und Log-Dateien wühlte, lag das eigentliche Problem noch im Dunkeln. Ich hatte mittlerweile schon mehrere Stunden in die Fehlersuche investiert, diverse KI-Modelle befragt, Forensik auf den UFW-Regeln betrieben und die IONOS-Firewall-Konfiguration mehrfach überprüft. Nichts.

Nach etwa sechs Stunden kam mir eine Idee, die im Nachhinein so offensichtlich war, dass ich kurz über mich selbst lachen musste: Statt der numerischen IP-Adresse gab ich einfach die Domain ein. root@nicohartmann.dev Verbunden. Sofort. Ohne Verzögerung.

Der Grund lag in der Art, wie IONOS intern DNS und Routing handhabt. Die direkte IP-Adresse des Servers wurde offenbar anders geroutet als die über den DNS-Namen aufgelöste Adresse, ein subtiler Unterschied in der Netzwerkkonfiguration, der sich als der eigentliche Übeltäter hinter meinen Timeouts entpuppte. Nicht die Bots, nicht die Firewall, nicht das Hotel-WLAN. Einfach ein Routing-Problem, das sich hinter der Domain-Auflösung versteckte. Sechs Stunden Debugging. Eine Lösung mit 24 Zeichen.

Härtung: Jetzt erst recht

Jetzt, mit funktionierender SSH-Verbindung, konnte ich das nachholen, was ohnehin längst überfällig gewesen wäre: den Server ordentlich absichern. Und der Blick in die Logs hatte die Dringlichkeit noch einmal deutlich unterstrichen. Firewall aufräumen war der erste Schritt. UFW (Uncomplicated Firewall) bietet eine angenehm übersichtliche Abstraktionsschicht über iptables. Ich überprüfte die bestehenden Regeln, entfernte unnötige offene Ports und beschränkte den eingehenden Traffic auf das Notwendige. Parallel dazu passte ich auch die IONOS-eigene Firewall an, die eine zusätzliche Schicht vor dem eigentlichen Server sitzt und auf der Infrastrukturebene greift. Doppelte Absicherung schadet nie.

Fail2Ban kam als nächstes. Das Tool überwacht Log-Dateien und sperrt automatisch IP-Adressen, die durch wiederholte fehlgeschlagene Login-Versuche auffallen. Nach drei fehlgeschlagenen SSH-Logins innerhalb kurzer Zeit landet eine IP im Jail und kommt für eine definierte Zeitspanne nicht mehr durch. Das reduziert nicht nur die Angriffsfläche, sondern auch den Lärmpegel in den Logs erheblich. Die Konfiguration für SSH ist dabei denkbar einfach. Fail2Ban bringt entsprechende Filter bereits mit, sie müssen nur aktiviert und auf die eigenen Bedürfnisse angepasst werden.

Unattended Upgrades schloss eine weiter Lücke, die ich schlicht nie aktiv adressiert hatte: automatische Sicherheitsupdates. Ungepatchte Pakete sind einer der häufigsten Einfallstore für Angreifer, und manuell daran zu denken, einen Server regelmäßig zu aktualisieren, ist auf Dauer unzuverlässig. Mit unattended-upgrades lädt und installiert das System sicherheitsrelevante Updates selbstständig, ohne mein Zutun, ohne dass ich nachts um drei daran denken muss.

Schlösser wechseln

Der Server lief, die Verbindung stand, und Fail2Ban wachte bereits über die eingehenden Login-Versuche. Aber wer einmal in die Auth-Logs geschaut hat und gesehen hat, wie unermüdlich diese Bots arbeiten, Sekunde für Sekunde, Stunde für Stunde, der weiß: Reaktive Maßnahmen reichen nicht. Die eigentliche Angriffsfläche muss verkleinert werden. Und die größte Angriffsfläche war noch SSH selbst.

Die Standardkonfiguration von OpenSSH ist funktional, aber nicht sicherheitsorientiert. Port 22 ist weltweit bekannt, Passwort-Authentifizierung ist standardmäßig aktiv, und Root-Login ist in vielen Distributionen direkt erlaubt. Das ist eine Kombination, die Bots regelrecht einlädt.

Der erste Schritt war ein Portwechsel auf 2222. Das ist kein Sicherheitsmechanismus im eigentlichen Sinne. Security through Obscurity gilt zu Recht als keine echte Verteidigung. Wer gezielt sucht, findet den Port. Aber im Alltag filtert ein nicht-standardmäßiger Port den absoluten Großteil des automatisierten Traffics heraus, weil die meisten Bots ausschließlich Port 22 scannen. Die Logs werden ruhiger, Fail2Ban hat weniger zu tun, und die Signalstärke bei echten Angriffsversuchen steigt. Ein pragmatischer Kompromiss.

Der zweite und deutlich wichtigere Schritt war die Abschaltung der Passwort-Authentifizierung zugunsten von SSH-Key-Authentifizierung. Passwörter können erraten, geleakt oder durch Brute-Force kompromittiert werden. Ein kryptografisches Schlüsselpaar nicht, zumindest nicht mit vertretbarem Aufwand.

Der Ablauf ist dabei überschaubar: ssh-keygen -t ed25519 Ed25519 ist der moderne Standard für SSH-Schlüssel: kompakt, schnell und kryptografisch deutlich robuster als das ältere RSA mit kurzen Schlüssellängen. Der erzeugte Schlüssel muss anschließend auf den Server übertragen werden. Ein wichtiger Punkt, den ich anfangs fast übersehen hätte: Dieser Schritt muss auf allen Rechnern durchgeführt werden, von denen aus ich auf den Server zugreife. Wer nur auf einem Gerät den Key hinterlegt und dann Passwort-Auth deaktiviert, sperrt sich selbst von allen anderen Geräten aus. Eine unangenehme Erfahrung, die ich mir durch rechtzeitiges Nachdenken ersparen konnte.

Erst nachdem die Key-Authentifizierung auf beiden Maschinen getestet und bestätigt funktionsfähig war, wurde PasswordAuthentication no in der Konfigurationsdatei gesetzt und der SSH-Dienst neu gestartet. Ab diesem Moment ist ein Login ohne passenden privaten Schlüssel schlicht nicht mehr möglich, egal wie viele Passwörter ein Bot durchprobiert.

Den Deployment-Prozess nicht vergessen

Ein Detail, das leicht in Vergessenheit gerät, wenn man seinen SSH-Port ändert: automatisierte Prozesse, die ebenfalls über SSH kommunizieren. In meinem Fall betrifft das die GitHub Actions Pipeline, die bei jedem Push auf den Hauptbranch automatisch meine Portfolio-Website auf den Server deployed.

Diese Pipeline verbindet sich per SSH mit dem Server und versuchte das bisher über Port 22. Nach dem Portwechsel auf 2222 lief das Deployment ins Leere. Die Lösung ist simpel, aber man muss daran denken: In der Action-Konfiguration den Port entsprechend anpassen. Ein port: 2222 in den SSH-Parametern der Action, ein neuer Commit und der Deployment-Prozess lief wieder reibungslos.

Der vergessene Nachbar

Neben dem eigentlichen Server läuft auf meiner Maschine auch Mailcow, eine selbstgehostete Mailserver-Lösung, die ich für meine eigene Domain betreibe. Und während ich mich intensiv um SSH gekümmert hatte, war Mailcow in der Zwischenzeit etwas vernachlässigt worden.

Das Admin-Passwort war eines jener Passwörter, die ich zwar einmal gesetzt, dann aber aus den Augen verloren hatte. Also: Zurücksetzen und durch ein neues, merkbares, aber sicheres, Passwort ersetzen. Klingt trivial, ist aber eine der häufigsten Sicherheitslücken im Selbsthosting-Bereich: Standardpasswörter oder vergessene, nie geänderte Initialpasswörter.

Mailcow bringt eigene Sicherheitsmechanismen mit, die aber aktiv eingeschaltet werden müssen. Fail2Ban ist auch in Mailcow integrierbar und überwacht dort fehlgeschlagene Login-Versuche auf das Webinterface und die Mailprotokolle. Die Einrichtung orientiert sich an der allgemeinen Fail2Ban-Logik, ist aber über das Mailcow-Interface direkt konfigurierbar.

Besonders wichtig war die Einrichtung von Zwei-Faktor-Authentifizierung, sowohl auf dem Admin-Konto als auch auf dem eigentlichen Postfach. 2FA ist inzwischen der Minimalstandard für jeden Account, bei dem eine Kompromittierung echten Schaden anrichten kann. Ein Mailserver-Admin-Konto fällt definitiv in diese Kategorie: Wer dort einbricht, kann nicht nur Mails lesen, sondern den gesamten Mailfluss kontrollieren, Weiterleitungen einrichten und im schlimmsten Fall über Passwort-Reset-Mechanismen Zugriff auf verknüpfte Dienste erlangen.

Wissen, was auf dem Server passiert

Mit den akuten Sicherheitsmaßnahmen erledigt, kam eine Frage auf, die schon länger im Hinterkopf geschwelt hatte: Wie bekomme ich mit, wenn wieder etwas schiefläuft, bevor ich es zufällig bemerke?

Die Antwort war ein eigenes Monitoring-Setup. Und weil ich schon dabei war, wollte ich die gesammelten Daten nicht nur intern nutzen, sondern direkt zugänglich machen: als öffentliche Statuspage auf meiner Portfolio-Website. Das Ergebnis ist das Projekt sysstats. eine Übersicht, die mir jederzeit zeigt, wie es meinem Server geht: CPU-Auslastung, Speicherverbrauch, und auch eine Auflistung der durch Fail2Ban gebannten IP-Adressen. Letztere wird mit den neuen Sicherheitsmaßnahmen voraussichtlich deutlich kürzer werden, was ich als Erfolg werte, auch wenn die lange Liste gebannter IPs ihren eigenen morbiden Charme hatte.

Fazit

Was als nerviges Timeout an einem Dienstagmorgen in Kroatien begann, endete mit einem Server, der erheblich robuster dasteht als zuvor. Portwechsel, Key-Authentifizierung, Fail2Ban, automatische Updates, gehärteter Mailserver, 2FA und Monitoring. Das ist kein übertriebener Aufwand. Das ist das Fundament, das jeder selbstgehostete Server haben sollte.

Der eigentliche Lerneffekt aber war ein anderer: Wie viel Grundrauschen im Internet herrscht, wie aktiv und automatisiert die Angriffe auf jeden öffentlichen Server sind und wie wenig es braucht, um sich dagegen wirksam zu schützen. Die Bots werden nicht aufhören. Aber sie werden an meinem Server ab jetzt deutlich weniger Freude haben.

← Zurück zur Startseite