Connection refused und Connection timed out sehen aus wie Geschwister – SSH hat sich so oder so nicht verbunden –, aber sie sind gegensätzliche Befunde und zeigen auf unterschiedliche Hälften des Stacks. Zu wissen, welchen du vor dir hast, halbiert die Verdächtigenliste, bevor du einen einzigen Diagnosebefehl tippst. Das ist die Zwei-Minuten-Routine: was jeder Fehler beweist, der eine Test, der sie von allem anderen trennt, und eine Checkliste pro Zweig. (Für die Fehler, die nach der geglückten TCP-Verbindung auftreten – Auth-Fehler, Host-Key-Warnungen, sterbende Sitzungen – siehe den Fehler-Decoder.)
| Fehler | Was er beweist | Wahrscheinliche Ursache | Erster Befehl |
|---|---|---|---|
Connection refused | Der Host ist oben und hat aktiv Nein gesagt (ein RST kam zurück) | Nichts lauscht auf diesem Port, oder eine REJECT-Firewall-Regel | ss -tlnp | grep sshd von der Konsole |
Connection timed out | Es kam gar nichts zurück – Stille auf dem Weg | Falsche IP, Host aus oder ein stilles DROP (Cloud-Security-Group / Firewall) | nc -vz host 22, dann die Cloud-Firewall prüfen |
Was jeder Fehler tatsächlich beweist
Connection refused heißt, die Maschine hat dir geantwortet. Dein TCP-SYN erreichte einen lebenden Host, und der Host sagte aktiv Nein – ein RST-Paket oder ein ICMP-Port-unreachable kam zurück. Das ist erstaunlich viel gute Nachricht: Die IP stimmt, die Route funktioniert, der Host ist oben, und nichts auf dem Weg frisst deine Pakete. Das Problem ist eng: Auf diesem Port lauscht nichts, oder eine Firewall-Regel weist ihn ab (verwirft ihn nicht).
Connection timed out heißt Stille. Deine Pakete gingen raus und nichts kam je zurück. Das beweist fast nichts über den Server – er mag aus sein, die IP mag falsch sein, oder (am häufigsten) etwas zwischen dir und ihm verwirft Pakete stillschweigend: eine Cloud-Security-Group, eine Firewall mit DROP-Policy, ein NAT- oder VPN-Schwarzes-Loch.
Eine Eselsbrücke: refused = die Maschine hat mit dir geredet; timed out = sie hat es nie getan. Refused ist ein Host-Problem. Timed out ist meist ein Wegproblem.
Schritt 1: den Port testen, nicht den Host
Lass ping als ersten Schritt weg – es testet in beiden Richtungen das Falsche. Ein Host, der auf Ping antwortet, kann Port 22 trotzdem verwerfen (Cloud-Firewalls filtern pro Port), und ein Host, der Ping ignoriert, kann fröhlich SSH anbieten (ICMP wird überall geblockt). Ping beweist nichts, was du brauchst.
Teste den tatsächlichen Port:
nc -vz example.com 22
(Kein netcat? telnet example.com 22 geht auch – jede Ausgabe, die mit SSH-2.0-... beginnt, heißt, sshd hat geantwortet.) Drei Ausgänge:
Connection refused– nimm den Refused-Zweig unten.- Hängt, dann Timeout – nimm den Timed-out-Zweig.
- Klappt – TCP ist in Ordnung und dein Problem steckt in SSH selbst: falscher Benutzer oder Schlüssel (
Permission denied (publickey)hat seinen eigenen Leitfaden (auf Englisch)), ein Host-Key-Mismatch oder etwas, dasssh -vklar beim Namen nennt.
Der Refused-Zweig: finde, was (nicht) lauscht
Du brauchst einen anderen Weg auf die Kiste – die Web-Konsole des Anbieters gibt es für genau diesen Moment.
Läuft sshd?
systemctl status sshd # the unit is "ssh" on Debian/Ubuntu
Wenn er tot ist, starte ihn nicht einfach neu – prüfe warum: journalctl -u sshd (oder -u ssh) zeigt, wie er beendet wurde. Eine häufige Ursache ist eine Config-Änderung, die nicht parst; sshd -t validiert die Datei und nennt die schlechte Zeile, bevor du in denselben Fehler neu startest.
Lauscht er, wo du denkst?
sudo ss -tlnp | grep sshd
Zwei Tücken verstecken sich in dieser Ausgabe. Der Port: Jemand hat SSH auf 2222 verschoben und du klopfst an 22 – verbinde mit ssh -p 2222, dann leg ihn pro Host in ~/.ssh/config (auf Englisch) fest, damit du ihn nie wieder herleiten musst. Die Adresse: Eine ListenAddress-Zeile kann sshd an ein einzelnes Interface binden, sodass er auf der privaten IP antwortet und auf der öffentlichen abweist.
Weist die lokale Firewall ab? sudo ufw status, sudo iptables -L -n oder nft list ruleset – such nach REJECT-Regeln für deinen Port. Eine REJECT-Regel erzeugt genau diesen Fehler: Der Host ist oben, sshd lauscht vielleicht sogar, und die Firewall antwortet an seiner Stelle.
Bist du gesperrt worden? Die Standardaktion von fail2ban weist ab, eine Sperre sieht also aus wie Connection refused – nur von deiner IP. Das Erkennungszeichen: Es geht von einem Handy-Hotspot, aber nicht aus deinem Netz. Von der Konsole: fail2ban-client status sshd, dann fail2ban-client unban <your-ip> – und behebe, was auch immer so oft falsche Zugangsdaten wiederholt hat, dass es die Sperre verdient hat.
Der Timed-out-Zweig: finde, wo Pakete sterben
Bestätige zuerst die Adresse. Das ist genau einmal peinlich. ssh -v gibt die IP aus, die es tatsächlich anwählt – gleich sie mit dem Dashboard des Anbieters ab. Veraltetes DNS nach einer Migration und die Elastic IP, die einen Instanz-Stopp nicht überlebt hat, sind beides Klassiker.
Prüfe als Nächstes die Cloud-Firewall, denn sie ist meistens die Antwort. Security Groups (AWS), NSGs (Azure) und VPC-Firewall-Regeln (GCP) verwerfen eingehenden Verkehr standardmäßig – stillschweigend, was genau ein Timeout ist. Such nach einer eingehenden Regel, die TCP 22 von deiner Adresse erlaubt. Die heimtückische Variante: eine Regel, die vor Monaten auf „Meine IP“ festgelegt wurde, und deine IP hat sich seitdem geändert. Netzwerk-ACLs auf Subnetz-Ebene sind eine zweite, seltener besuchte Schicht, die einen Blick wert ist, wenn die Security Group richtig aussieht.
Verfolge den Weg, wenn die Cloud-Regeln passen:
traceroute example.com # mtr example.com for a live view
sudo traceroute -T -p 22 example.com # TCP to the actual port — closest to the truth
Normales traceroute nutzt UDP oder ICMP, was Firewalls anders behandeln als TCP 22 – die Form -T -p 22 testet, was SSH tatsächlich erlebt. Wo die Hops aufhören zu antworten, ist ungefähr, wo deine Pakete sterben.
Verdächtige deine eigene Seite. Hotel-, Café- und Büro-Gästenetze blocken ausgehenden Port 22 routinemäßig, und Firmen-VPNs leiten ihn um oder verwerfen ihn. Der Isolationstest ist der Handy-Hotspot: Wenn SSH dort funktioniert, ist dein Server in Ordnung und das Netz, in dem du warst, ist das Problem.
Eine Firewall mit DROP-Policy auf dem Host selbst sieht von außen identisch aus wie ein Drop auf Cloud-Seite – wenn du Konsolenzugriff hast, prüfe auch iptables/nftables auf der Kiste.
Die exotische Variante: Port-Knocking. Ein Server mit knockd verwirft alles, bis er eine geheime Folge von Verbindungsversuchen auf anderen Ports sieht. Wenn ein Vorgänger die Kiste eingerichtet hat und jeder Port von überall ein Timeout liefert, frag herum, bevor du einen Nachmittag mit Routing-Theorien verbrennst.
Behalte die Zwei-Minuten-Fassung
Die ganze Routine lässt sich gut verdichten: Teste den Port mit nc -vz. Refused → per Konsole rein, sshd prüfen, den lauschenden Port, REJECT-Regeln, fail2ban. Timed out → die IP bestätigen, die Cloud-Security-Group prüfen, dann traceroute und dein eigenes Netz. Ping taucht darin nirgends auf.
Die wiederkehrenden Fakten – welcher Port, welcher Benutzer, welcher Host braucht Keepalives – gehören in die ~/.ssh/config (auf Englisch), nicht in dein Gedächtnis. Und ein Teil der Diagnose kann feststehender Zustand sein statt eines Gewusels mitten im Vorfall: Termalin speichert Port, Benutzer, Schlüssel und Keepalive-Einstellungen bei jedem gespeicherten Host und zeigt den Live-Status pro Host – sodass „läuft die Kiste überhaupt?“ und „welcher Port war das noch?“ beantwortet sind, bevor du dich verbindest, und der Server, der nur auf 2222 lauscht, aufhört, etwas zu sein, das du quartalsweise neu entdeckst.
Termalin ist ein kostenloser, plattformübergreifender SSH-Client, der Ports, Benutzer, Schlüssel und Keepalives pro Host beim Host behält und den Live-Host-Status zeigt – lade es herunter oder stöbere in der vollständigen Funktionsliste.