Bewährte Verfahren zur Vermeidung von SSH-Timeout-Problemen

Verhindern Sie frustrierende SSH-Sitzungsabbrüche, indem Sie robuste Keep-Alive-Konfigurationen implementieren. Dieser essentielle Leitfaden beschreibt den Unterschied zwischen Client-seitigen (`ServerAliveInterval`) und Server-seitigen (`ClientAliveInterval`) Konfigurationen und bietet schrittweise Anweisungen zur Anpassung Ihrer `~/.ssh/config`-Datei. Erfahren Sie, wie Sie praktische Werte verwenden, um aggressive Firewall- und NAT-Timeouts zu umgehen und so eine stabile, dauerhafte Verbindung auch in instabilen Netzwerken zu gewährleisten. Enthält auch Empfehlungen zur Nutzung von Multiplexern wie `tmux` für ultimative Sitzungsresilienz.

32 Aufrufe

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.

  1. Öffnen Sie die SSH-Daemon-Konfigurationsdatei:

    bash sudo nano /etc/ssh/sshd_config

  2. 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.

  1. Starten Sie den SSH-Dienst neu, damit die Änderungen wirksam werden:

    ```bash
    sudo systemctl restart sshd

    oder

    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:

  1. Stellen Sie eine Verbindung zum Server her:
    bash ssh user@remote_host
  2. Starten Sie eine neue tmux-Sitzung auf dem Server:
    bash tmux new -s my_session
  3. Arbeiten Sie innerhalb der tmux-Sitzung.
  4. Wenn die Verbindung abbricht oder Sie gehen müssen, trennen Sie die Sitzung (Strg+B, dann D).
  5. Stellen Sie die Verbindung zum Server über SSH wieder her.
  6. 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:

  1. Portabilität: SSH-Direktiven funktionieren unabhängig von der zugrunde liegenden Kernel-Abstimmung des Betriebssystems konsistent.
  2. Applikationsebene: SSH Keep-Alives arbeiten auf der Applikationsebene und stellen sicher, dass der SSH-Daemon reaktionsfähig bleibt.
  3. 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.