Fünf Tage. So lange hat es gedauert, bis ein frischer Ubuntu-Server mit offenem SSH-Port von knapp 19.000 Login-Versuchen pro Tag getroffen wurde. Nicht weil jemand gezielt mein Portfolio angreifen wollte — sondern weil automatisierte Scanner das gesamte IPv4-Internet kontinuierlich nach offenen SSH-Ports absuchen.
Dass es passiert, war erwartbar. Wie schnell es eskaliert und welche konkreten Auswirkungen es hat, war trotzdem aufschlussreich. Dieser Artikel dokumentiert den Verlauf anhand realer Logs — und die drei Maßnahmen, die das Problem gelöst haben.
Der Auslöser
Eine GitHub Actions Pipeline, die seit Tagen zuverlässig lief, schlug plötzlich fehl:
kex_exchange_identification: read: Connection reset by peer
Connection reset by 10.0.0.2 port 22
SSH war erreichbar, der Server lief, keine Firewall-Regel blockierte. Trotzdem wurden Verbindungen abgelehnt. Ein Blick in die sshd-Logs zeigte die Ursache:
error: beginning MaxStartups throttling
drop connection #10 from [167.99.38.221]:53320 past MaxStartups
sshd hat das Default-Limit von 10 gleichzeitigen unauthentifizierten Verbindungen erreicht — und danach wahllos neue Verbindungen gedropt. Darunter die von GitHub Actions.
Die Eskalation
Ein Blick in die Journal-Logs der ersten Woche zeigt, wie schnell das eskaliert:
| Tag | Fehlgeschlagene Versuche | Anmerkung |
|---|---|---|
| 26.02. | 1.367 | Server geht ans Netz, Scanning beginnt |
| 27.02. | 10.341 | IP in Scan-Listen aufgenommen |
| 28.02. | 13.449 | Anstieg |
| 01.03. | 18.948 | Peak — fast 19.000 Versuche an einem Tag |
| 02.03. | 9.193 | fail2ban ab 10:36 aktiv, danach stark reduziert |
Innerhalb von zwei Tagen nach dem ersten öffentlichen SSH-Port war die IP in den Scan-Listen. Am vierten Tag knapp 19.000 Versuche. Das ist kein Ausnahmefall — das ist der Normalzustand für jeden Server mit offenem Port 22 im Internet.
Die Angreifer
Am Tag des fehlgeschlagenen Deployments habe ich die Logs im Detail analysiert:
- 20+ verschiedene Angreifer-IPs aktiv
- 213 MaxStartups-Throttling Events — so oft wurden legitime Verbindungen gedropt
- Peaks von 40 Versuchen pro Minute in der Nacht
Herkunft
| IP | Versuche | Herkunft |
|---|---|---|
| 134.199.157.148 | 2.332 | DigitalOcean |
| 46.225.10.160 | 1.833 | Hetzner Cloud |
| 165.245.137.142 | 1.360 | DigitalOcean |
| 134.199.156.126 | 855 | DigitalOcean |
| 209.97.130.120 | 715 | DigitalOcean |
Fast ausschließlich Cloud-VMs von DigitalOcean und Hetzner. Kompromittierte oder eigens für Scanning gemietete Instanzen. Eine IP kam sogar aus demselben Hetzner-Rechenzentrum wie mein Server.
Versuchte Usernamen
3.531 root (38%)
792 admin
410 postgres
408 test
369 oracle
308 ubuntu
230 hadoop
216 git
200 mysql
Klassisches Wörterbuch-Scanning gegen Standard-Dienste-User. root, admin, postgres, mysql, jenkins, docker, elasticsearch — die Bots probieren jeden Usernamen, der bei einer typischen Serverinstallation existieren könnte. Kein gezielter Angriff, reines Spray-and-Pray. Aber in der Masse reicht das, um einen ungeschützten sshd lahmzulegen.
Die Gegenmaßnahmen
1. Password-Authentifizierung deaktiviert
PasswordAuthentication no
Die offensichtlichste Maßnahme: Brute-Force-Angriffe mit Passwörtern laufen ins Leere. Nur Public-Key-Authentifizierung ist erlaubt. Die Angreifer verschwenden ihre Zeit — aber sie belasten trotzdem den sshd-Prozess mit der Verbindungsaufnahme. Deshalb reicht diese Maßnahme allein nicht.
2. fail2ban
fail2ban überwacht die sshd-Logs und bannt IPs nach wiederholten fehlgeschlagenen Versuchen per Firewall-Regel:
[sshd]
enabled = true
backend = systemd
maxretry = 3
findtime = 600
bantime = 86400
3 fehlgeschlagene Versuche innerhalb von 10 Minuten → IP wird für 24 Stunden komplett blockiert. Nicht nur für SSH, sondern auf Firewall-Ebene — die Pakete werden gedropt, bevor sie sshd erreichen.
Die Wirkung war sofort messbar: Von ~30 fehlgeschlagenen Versuchen pro Minute auf unter 5. Innerhalb der ersten Minuten wurden 15 IPs gebannt. Nach einer Stunde war der SSH-Traffic auf ein Zehntel des vorherigen Niveaus gefallen.
3. MaxStartups erhöht
MaxStartups 30:50:100
Das Format bedeutet: Ab 30 unauthentifizierten Verbindungen beginnt sshd mit einer Wahrscheinlichkeit von 50%, neue Verbindungen abzulehnen. Ab 100 wird jede neue Verbindung abgelehnt. Der Default von 10:30:100 war zu niedrig — selbst ein moderater Scan hat das Limit erreicht.
In Kombination mit fail2ban wird dieses Limit in der Praxis nicht mehr erreicht. Die Angreifer werden gebannt, bevor sie genug gleichzeitige Verbindungen aufbauen können.
Die Wirkung
Nach der Aktivierung aller drei Maßnahmen:
- Fehlgeschlagene Versuche: Von ~30/Minute auf unter 5/Minute
- MaxStartups-Throttling: Null Events seit Aktivierung
- Gebannte IPs: Steigt kontinuierlich, aktuell über 15 pro Server
- Legitime Verbindungen: Kein einziger Drop mehr
Die CI/CD-Pipeline läuft seitdem zuverlässig. Das eigentliche Problem — der fehlgeschlagene Deploy — war innerhalb von Minuten gelöst.
Fazit
Ein Server mit offenem Port 22 wird angegriffen. Nicht vielleicht, nicht irgendwann — sofort und permanent. Die Frage ist nicht ob, sondern wie schnell die Scan-Bots die IP finden. In meinem Fall: zwei Tage.
Die drei Maßnahmen — Password-Auth deaktivieren, fail2ban, MaxStartups erhärten — kosten zusammen weniger als fünf Minuten Einrichtungszeit. Ohne sie wäre mein Deploy-Workflow weiterhin unzuverlässig, und sshd würde einen relevanten Teil seiner Ressourcen für die Verarbeitung von Bot-Traffic verschwenden.
SSH-Hardening gehört nicht auf die “Mach ich irgendwann”-Liste. Es gehört in die erste Stunde nach der Serverinstallation.