Meine Verbindung prüfen

Ratgeber · Eine IP untersuchen

SSH-Anmeldeversuche im Log: Werde ich gehackt?

Du meldest dich auf deinem Server an, wirfst einen Blick in /var/log/auth.log, und da stehen Tausende Zeilen Failed password for root von Adressen aus aller Welt. Sieht aus wie eine Belagerung. Ist vor allem Wetter.

Port 22 ist die vorhersehbarste Tür im Internet, also klopfen automatisierte Skripte ständig an, überall, rund um die Uhr. Sie zielen nicht auf dich. Sie probieren eine kurze Liste von Benutzernamen (root, admin, oracle, ubuntu, test) mit den beliebtesten Passwörtern und ziehen weiter. Ein Fehlversuch kostet sie nichts und verrät dir nur, dass SSH erreichbar ist. Deine Aufgabe ist es, zwei Fragen zu beantworten: Hat ein Versuch geklappt, und könnte künftig einer klappen?

Wo du nachsiehst

Unter Debian und Ubuntu mit rsyslog schreibt SSH nach /var/log/auth.log. Unter Red Hat, Fedora, Rocky und Alma ist es /var/log/secure. Neuere Debian-Installationen schreiben diese Datei womöglich gar nicht und halten alles im systemd-Journal. Das Journal funktioniert überall, wo systemd läuft; der Dienst heißt ssh unter Debian und Ubuntu und sshd in der Red-Hat-Familie:

sudo journalctl -u ssh --since today        # Debian, Ubuntu
sudo journalctl -u sshd --since "1 hour ago" # Red Hat, Fedora, Rocky, Alma

Drei Zählungen erzählen den Großteil der Geschichte:

sudo grep -c "Failed password" /var/log/auth.log
sudo grep "Accepted" /var/log/auth.log
sudo grep "Failed password" /var/log/auth.log | grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn | head

Die erste misst das Rauschen. Die zweite ist die, die zählt: jeder erfolgreiche Login. Die dritte zeigt, welche Adressen es am hartnäckigsten versuchen.

Ein Praxisbeispiel: eine Nacht auf einem kleinen VPS

Zwölf Zeilen von einem Server namens web1. Die zwei Adressen von Menschen (der Angreifer, der es mit admin versucht, und der Besitzer, der sich am nächsten Morgen anmeldet) sind Dokumentationsadressen, damit hier keine echte Person auftaucht. Die übrigen sind öffentliche Infrastruktur.

Das Beispiel-Log (12 Zeilen)
Nov  6 03:12:41 web1 sshd[24811]: Invalid user admin from 203.0.113.77 port 51022
Nov  6 03:12:43 web1 sshd[24811]: Failed password for invalid user admin from 203.0.113.77 port 51022 ssh2
Nov  6 03:12:44 web1 sshd[24811]: Connection closed by invalid user admin 203.0.113.77 port 51022 [preauth]
Nov  6 03:12:50 web1 sshd[24815]: Failed password for root from 185.220.101.1 port 40122 ssh2
Nov  6 03:12:53 web1 sshd[24815]: Failed password for root from 185.220.101.1 port 40122 ssh2
Nov  6 03:12:55 web1 sshd[24815]: Disconnected from authenticating user root 185.220.101.1 port 40122 [preauth]
Nov  6 03:14:02 web1 sshd[24830]: Invalid user oracle from 3.5.140.1 port 33412
Nov  6 03:14:04 web1 sshd[24830]: Failed password for invalid user oracle from 3.5.140.1 port 33412 ssh2
Nov  6 03:14:04 web1 sshd[24830]: Received disconnect from 3.5.140.1 port 33412:11: Bye Bye [preauth]
Nov  6 03:20:17 web1 sshd[24902]: Connection closed by 167.94.138.35 port 49212 [preauth]
Nov  6 08:41:09 web1 sshd[25510]: Accepted publickey for deploy from 198.51.100.20 port 52814 ssh2: ED25519 SHA256:k3X0exampleexampleexampleexampleexampleexa
Nov  6 08:41:09 web1 sshd[25510]: pam_unix(sshd:session): session opened for user deploy(uid=1001) by (uid=0)

Im Log-Checker von iplover sortieren sich die fünf Adressen so:

IP-AdresseZeilenKategorieNetzwerktyp
203.0.113.773Privat oder reserviertPrivate oder reservierte Adresse (nicht geprüft)
185.220.101.13Tor-Exit-NodesTor-Exit-Node
3.5.140.13Cloud und HostingHosting, Cloud oder Rechenzentrum
167.94.138.351Internet-ScannerNicht erkannt
198.51.100.201Privat oder reserviertPrivate oder reservierte Adresse (nicht geprüft)

(Die zwei Dokumentationsadressen erscheinen als reserviert; in deinem eigenen Log würden echte Adressen geprüft.) Jetzt lies die Zeilen, denn die Kategorien sagen nur, wer geklopft hat, nicht ob die Tür aufging.

Fazit: ein akzeptierter Login, und er stammt vom Besitzer. Niemand ist reingekommen. Aber root akzeptiert noch Passwörter, das Raten aus Zeile vier könnte also eines Tages klappen, wenn das root-Passwort schwach ist. Genau das gilt es zu beheben.

Ist wirklich jemand reingekommen?

Prüf jede Accepted-Zeile. Frag dich bei jeder: Ist das mein Benutzername, mein Schlüssel oder Passwort, und eine Adresse, die ich kenne (zu Hause, Büro, VPN)? Dann gleich mit den Anmeldeprotokollen ab:

last -a | head -20     # letzte erfolgreiche Logins, mit der entfernten Adresse
sudo lastb | head -20  # letzte fehlgeschlagene Logins (auf Systemen, die sie speichern)
who                     # wer gerade angemeldet ist

Einige neuere Distributionen haben last und lastb durch andere Werkzeuge ersetzt; fehlen sie, enthalten das Journal und auth.log dieselben Informationen.

Eine Zeile Accepted password oder Accepted publickey, die du nicht erklären kannst, ist das eine Ergebnis, das alles ändert. Dann geh davon aus, dass das Konto kompromittiert ist:

Wenn du das siehst, tu das

Was du siehstWas es bedeutetWas zu tun ist
Invalid user … für Namen, die es bei dir nicht gibtRaten, das nicht klappen kannNichts Dringendes. Es verschwindet, sobald Passwörter abgeschaltet sind.
Failed password for root oder für ein anderes echtes KontoRaten gegen ein existierendes KontoPasswort-Logins abschalten (siehe unten), mindestens für root.
Connection closed by … [preauth] ohne PasswortversuchEin Scanner, der dein SSH-Banner liestNichts.
Tausende Fehlversuche am Tag von wenigen AdressenHartnäckige Botsfail2ban einrichten oder SSH nur von deinen eigenen Adressen erlauben.
Accepted …-Zeilen, die alle von dir stammenSonst ist niemand reingekommenNichts, außer härten.
Accepted … von einer Adresse oder einem Benutzer, den du nicht erklären kannstWahrscheinlich ein EinbruchFolge den Schritten oben, angefangen bei authorized_keys.

Raten sinnlos machen: nur Schlüssel

Ein Passwort lässt sich erraten, ein SSH-Schlüssel praktisch nicht. Sobald nur noch Schlüssel akzeptiert werden, können die Bots ewig weiterprobieren.

Erzeuge zuerst auf deinem eigenen Rechner einen Schlüssel und kopiere ihn auf den Server. macOS und Linux bringen den OpenSSH-Client mit. Unter Windows ist er ein optionales Feature und oft schon installiert; wird ssh nicht erkannt, erklärt Microsofts Anleitung Erste Schritte mit OpenSSH für Windows, wie du ihn hinzufügst:

ssh-keygen -t ed25519
ssh-copy-id du@dein-server     # unter Windows: ~/.ssh/id_ed25519.pub in ~/.ssh/authorized_keys auf dem Server einfügen

Dann setzt du auf dem Server diese Zeilen in /etc/ssh/sshd_config:

PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password

prohibit-password lässt root nur mit Schlüssel herein; mit no bleibt root ganz draußen. Prüf vor dem Neustart, was SSH tatsächlich verwenden wird. Dateien in /etc/ssh/sshd_config.d/ werden ebenfalls gelesen, und manche Cloud-Images bringen eine mit, die Passwörter wieder einschaltet. Bei den meisten Einstellungen gewinnt der erste Wert, den sshd liest:

sudo sshd -T | grep -Ei "passwordauthentication|kbdinteractive|permitrootlogin"

Starte SSH neu (sudo systemctl restart ssh, in der Red-Hat-Familie sshd) und lass deine aktuelle Sitzung offen, während du in einem zweiten Fenster eine neue Anmeldung testest. Schlägt die neue fehl, kannst du in der alten noch alles reparieren.

Rauschen reduzieren: fail2ban und Firewalls

Schlüssel machen das Raten harmlos. fail2ban macht das Log lesbar: Es beobachtet wiederholte Fehlversuche und sperrt diese Adressen eine Weile in der Firewall. Unter Debian und Ubuntu sudo apt install fail2ban, dann /etc/fail2ban/jail.local anlegen:

[sshd]
enabled  = true
maxretry = 5
findtime = 10m
bantime  = 1h
# Ohne /var/log/auth.log (neuere Debian-Versionen) das Journal lesen:
# backend = systemd

Neustarten mit sudo systemctl restart fail2ban, prüfen mit sudo fail2ban-client status sshd.

Brauchst nur du SSH, ist der stärkste Filter eine Firewall-Regel, die Port 22 nur von deinen Adressen erlaubt, oder ein VPN vor dem Server. SSH auf einen anderen Port zu legen reduziert das Rauschen deutlich, ist aber Tarnung, kein Schutz: Ein Scanner findet ihn trotzdem.

Was die Adressen nicht verraten

Die Adressen in auth.log sind die Herkunft der Verbindungen: oft ein Tor-Exit, ein gemieteter Cloud-Server oder der gekaperte Rechner von jemand anderem. Sie identifizieren keine Person, und sie einzeln zu sperren hält nicht Schritt. Hartnäckige Angriffe beim Abuse-Kontakt des Netzes zu melden (die IP-Abfrage zeigt ihn) ist sinnvoll bei einem Cloud-Server, der tagelang auf dich einhämmert; für ein paar fehlgeschlagene Logins lohnt sich die Mühe nicht.

Quellen

Offizielle Dokumente, mit denen wir die Fakten in diesem Ratgeber geprüft haben.