Best Practices zur Vermeidung von SSH-Timeout-Problemen
SSH (Secure Shell) ist das Rückgrat der Remote-Systemadministration und bietet verschlüsselte und sichere Konnektivität. Wenige Dinge sind jedoch frustrierender als eine Sitzung, die aufgrund eines Timeouts unerwartet abbricht. Diese Probleme treten besonders häufig in instabilen Netzwerken, bei Verbindungen, die über aggressive NAT-Geräte geleitet werden, oder wenn Sitzungen über einen längeren Zeitraum inaktiv bleiben, auf.
Diese Anleitung untersucht die wesentlichen Konfigurationsanpassungen – sowohl auf dem Client als auch auf dem Server –, die Systemadministratoren und Entwickler proaktiv umsetzen können, um stabile SSH-Sitzungen aufrechtzuerhalten. Durch die Nutzung integrierter Keep-Alive-Mechanismen stellen Sie sicher, dass Ihre kritischen Aufgaben nicht unterbrochen werden, selbst bei Netzwerkschwankungen oder Inaktivität.
Die Ursache von SSH-Timeouts verstehen
Ein SSH-Timeout tritt auf, wenn die Kommunikationsverbindung zwischen Client und Server unterbrochen wird, weil keine Seite innerhalb einer bestimmten Dauer Aktivität erkannt hat. Dies liegt in der Regel nicht an der SSH-Software selbst, sondern an zwischengeschalteten Netzwerkgeräten (Firewalls, Router und NAT-Tabellen), die inaktive Verbindungen aggressiv abschneiden, um Ressourcen zu schonen.
Wenn eine Firewall einige Minuten lang keinen Datenverkehr auf einer bestimmten TCP-Verbindung gesehen hat, geht sie davon aus, dass die Sitzung tot ist, und verwirft den Verbindungsstatus. Wenn der SSH-Client das nächste Mal versucht, Daten zu senden, empfängt der Server diese nie, was zu einem Einfrieren der Sitzung und schließlich zu einem Timeout-Fehler führt.
Die Lösung besteht darin, SSH so zu konfigurieren, dass regelmäßig Keep-Alive-Signale (kleine Pakete ohne Daten) gesendet werden, um sicherzustellen, dass zwischengeschaltete Geräte die Verbindung als aktiv erkennen.
1. Lösungen auf Client-Seite: Das ServerAliveInterval
Die häufigste und einfachste Lösung zur Vermeidung von Timeouts ist die Konfiguration des SSH-Clients, um periodisch eine Keep-Alive-Nachricht an den Server zu senden. Dies wird durch die Direktive ServerAliveInterval gesteuert.
Funktionsweise von ServerAliveInterval
ServerAliveInterval gibt die Zeit in Sekunden an, nach der der Client ein Nullpaket an den Server sendet, wenn keine Daten vom Server empfangen wurden. Dieser Wert stellt sicher, dass die Client-Seite den Verbindungsstatus aufrechterhält.
Konfiguration über ~/.ssh/config
Diese Methode wird empfohlen, da sie es Ihnen ermöglicht, die Konfiguration global oder pro Host festzulegen, was bei Neustarts und verschiedenen Terminalsitzungen erhalten bleibt.
Erstellen oder bearbeiten Sie Ihre Client-Konfigurationsdatei, die sich normalerweise unter ~/.ssh/config befindet:
nano ~/.ssh/config
Um die Einstellung global anzuwenden (für alle Hosts):
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Erklärung der Werte:
ServerAliveInterval 60: Der Client sendet alle 60 Sekunden ein Keep-Alive-Paket, wenn die Verbindung inaktiv ist.ServerAliveCountMax 3: Wenn der Client 3 aufeinanderfolgende Keep-Alive-Nachrichten sendet, ohne eine Antwort vom Server zu erhalten, beendet der Client die Verbindung. (Gesamte Timeout-Dauer: 60 Sekunden * 3 Versuche = 180 Sekunden).
Konfiguration über die Kommandozeile
Wenn Sie eine temporäre Lösung benötigen oder die Einstellung nur für eine einzige Sitzung anwenden möchten, verwenden Sie die Option -o während der Verbindung:
ssh -o "ServerAliveInterval 60" user@remote_host
Tipp: Ein Wert von 30 bis 60 Sekunden ist normalerweise ideal, da er häufig genug ist, um die meisten Firewall-Regeln zu umgehen (die oft bei etwa 5 Minuten eingestellt sind), aber nicht so häufig, dass er übermäßigen Netzwerk-Overhead erzeugt.
2. Lösungen auf Server-Seite: Erzwingen von Keep-Alives
Obwohl die Lösung auf Client-Seite (ServerAliveInterval) normalerweise ausreichend ist, möchten Administratoren, die Server verwalten, auf die viele Benutzer zugreifen, Keep-Alive-Einstellungen zentral durchsetzen oder harte Limits für inaktive Verbindungen festlegen. Dies geschieht in der SSH-Daemon-Konfigurationsdatei, /etc/ssh/sshd_config.
Verwendung von ClientAliveInterval und ClientAliveCountMax
Diese Direktiven sind die Gegenstücke auf Serverseite zu den Client-Einstellungen. Sie weisen den Server an zu prüfen, ob der Client noch verbunden ist.
-
Öffnen Sie die SSH-Daemon-Konfigurationsdatei:
bash sudo nano /etc/ssh/sshd_config -
Fügen Sie die folgenden Zeilen hinzu oder ändern Sie sie:
```config
Server sendet ein Nullpaket, wenn 300 Sekunden (5 Minuten) lang keine Daten vom Client empfangen wurden
ClientAliveInterval 300
Wenn ClientAliveInterval 0 Mal ohne Antwort ausgelöst wird, wird die Verbindung getrennt.
Das Setzen auf 0 bedeutet, dass der Server sofort nach dem ersten fehlgeschlagenen Check die Verbindung trennt.
ClientAliveCountMax 0
```
Hinweis zu ClientAliveCountMax:
Wenn Sie ClientAliveCountMax auf einen niedrigen Wert (wie 0 oder 1) setzen, erzwingt der Server ein striktes Timeout bei Inaktivität. Zum Beispiel bedeuten ClientAliveInterval 300 und ClientAliveCountMax 0, dass der Server die Verbindung als tot ansieht und eine Trennung erzwingt, wenn ein Benutzer 5 Minuten lang völlig inaktiv ist. Dies ist aus Sicherheitsgründen nützlich, kann aber für Benutzer frustrierend sein. Wenn Ihr Ziel darin besteht, zu verhindern, dass Firewalls die Verbindung trennen, ist das Festlegen eines Wertes hier oft zweitrangig gegenüber dem ServerAliveInterval auf Client-Seite.
-
Starten Sie den SSH-Dienst neu, damit die Änderungen wirksam werden:
```bash
sudo systemctl restart sshdoder
sudo service sshd restart
```
3. Erweiterte Resilienzstrategien
Obwohl SSH Keep-Alives kurze Zeiträume der Inaktivität abdecken, führt eine vollständige Netzunterbrechung (z. B. Wechsel des WLANs oder kurzzeitiger Signalverlust) immer noch zum Abbruch der TCP-Verbindung. Für echte Resilienz sollten Sie Sitzungsverwaltungstools verwenden.
Terminal-Multiplexer nutzen (tmux oder screen)
Terminal-Multiplexer sind die ultimative Verteidigung gegen Verbindungsabbrüche. Sie führen eine Sitzung auf dem Remote-Server aus, die bestehen bleibt, selbst wenn Ihre Client-Verbindung getrennt wird. Sie können die Sitzung trennen, sich später (von demselben oder einem anderen Client) wieder verbinden und sich wieder anhängen, um genau dort fortzufahren, wo Sie aufgehört haben.
Grundlegender tmux-Workflow:
- Stellen Sie eine Verbindung zum Server her:
bash ssh user@remote_host - Starten Sie eine neue
tmux-Sitzung auf dem Server:
bash tmux new -s my_session - Arbeiten Sie innerhalb der
tmux-Sitzung. - Wenn die Verbindung abbricht oder Sie gehen müssen, trennen Sie die Sitzung (Strg+B, dann D).
- Stellen Sie die Verbindung zum Server über SSH wieder her.
- Hängen Sie sich wieder an Ihre vorhandene Sitzung an:
bash tmux attach -t my_session
Unterscheidung zwischen SSH Keep-Alives und TCP Keep-Alives
Es ist möglich, den zugrunde liegenden TCP Keep-Alive-Mechanismus des Betriebssystems zu verwenden, der oft über die Direktive TCPKeepAlive yes in sshd_config konfiguriert wird. SSH-Level-Keep-Alives (ServerAliveInterval) werden jedoch im Allgemeinen bevorzugt, weil:
- Portabilität: SSH-Direktiven funktionieren unabhängig von der zugrunde liegenden Kernel-Abstimmung des Betriebssystems konsistent.
- Applikationsebene: SSH Keep-Alives arbeiten auf der Applikationsebene und stellen sicher, dass der SSH-Daemon reaktionsfähig bleibt.
- Firewall-Bewusstsein: TCP Keep-Alives können manchmal von Firewalls oder NAT-Geräten, die nur die Payload-Aktivität überprüfen, stillschweigend blockiert werden, während SSH Keep-Alives speziell dafür entwickelt wurden, diese Ebenen erfolgreich zu durchqueren.
Wenn Sie sich für die Verwendung von TCPKeepAlive yes entscheiden, denken Sie daran, dass das tatsächliche Intervalltiming vom Betriebssystem gesteuert wird (z. B. net.ipv4.tcp_keepalive_time von Linux) und nicht von der SSH-Konfiguration.
Zusammenfassung der Best Practices
| Problem | Konfigurationsdirektive | Speicherort | Empfohlener Wert | Zweck |
|---|---|---|---|---|
| Client-Timeouts | ServerAliveInterval |
~/.ssh/config (Client) |
30 - 60 Sekunden | Sendet Nullpakete vom Client zum Server, um ein Firewall-Drop zu verhindern. |
| Client-Trennungs-Schwelle | ServerAliveCountMax |
~/.ssh/config (Client) |
3 - 5 | Anzahl der verpassten Antworten, bevor der Client die Verbindung trennt. |
| Server-Inaktivitäts-Erzwingung | ClientAliveInterval |
/etc/ssh/sshd_config (Server) |
300 Sekunden (5 Min) | Sendet Prüfungen vom Server an den Client, um die Aktivität zu überwachen. |
| Verbindungsresilienz | N/A | Serversitzung | tmux oder screen |
Ermöglicht das Fortbestehen der Sitzung trotz Netzwerkausfall. |
Durch die Implementierung der Direktive ServerAliveInterval auf Ihren Client-Rechnern werden die allermeisten SSH-Timeout-Probleme, die durch Netzwerk-Inaktivität verursacht werden, behoben. Für geschäftskritische Aufgaben bietet die Kombination dieser Konfiguration mit einem Sitzungsmultiplexer nahezu vollständige Immunität gegen Verbindungsunterbrechungen.