Jak działa tcp-keepalive w ssh?

84

Próbuję napisać skrypt powłoki, który używa połączenia ssh do wykonywania „uderzeń serca”. Chcę zakończyć połączenie po stronie klienta i serwera po pewnym czasie (po zerwaniu połączenia).

Co znalazłem do tej pory:

  • TCPKeepAlive tak / nie dla ssh i sshd
  • ClientAliveCountMax dla sshd
  • ClientAliveInterval dla sshd
  • ServerAliveCountMax dla ssh
  • ServerAliveInterval dla ssh

Aby zmienić „ClientAliveCountMax” musiałbym zmodyfikować sshd_config na każdym komputerze docelowym (ta opcja jest domyślnie wyłączona).

Więc moje pytanie brzmi - czy mogę używać „TCPKeepAlive” również do moich celów (bez zmiany czegokolwiek na maszynach źródłowych / docelowych)?

Docelowym systemem operacyjnym jest SLES11 SP2 - ale nie sądzę, żeby miało to tutaj znaczenie.

Nils
źródło
Wszystkie te parametry są przeznaczone do sytuacji, w których zapora lub urządzenie pośrednie wzdłuż połączenia zakończy połączenie. Parametry te służą do wysyłania okresowych danych w celu utrzymania połączenia przy życiu, a także do zamykania połączenia, gdy pojawi się X zaległych odpowiedzi. Czy możesz podać trochę więcej szczegółów tego, co robisz? Czy korzystasz z ControlMasteropcji i korzystasz z połączeń slave?
Patrick
Chcę tylko zbudować sposób na określenie, czy inny węzeł jest „wyłączony” przy użyciu kilku połączeń ssh-network z kilkoma liniami fizycznymi. Robię to po prostu otwierając sesję ssh (która mniej więcej robi nieskończoną pętlę). Chcę, aby sesja została zakończona, jeśli połączenia zostaną zerwane. Zastanawiam się, jaki jest interwał / liczba dla TCPKeepalive.
Nils

Odpowiedzi:

103

Prawdopodobnie chcesz do tego użyć ustawień ServerAlive. Nie wymagają one żadnej konfiguracji na serwerze i można je ustawić w wierszu poleceń.

ssh -o ServerAliveInterval=5 -o ServerAliveCountMax=1 $HOST

Spowoduje to wysłanie komunikatu podtrzymującego ssh co 5 sekund, a jeśli przyjdzie czas, aby wysłać kolejny komunikat podtrzymujący, ale odpowiedź na ostatnią nie została odebrana, połączenie zostanie przerwane.

Krytyczną różnicą między warstwą ServerAliveIntervali TCPKeepAlivejest warstwa, na której działają.

  • TCPKeepAlivedziała na warstwie TCP. Wysyła pusty pakiet TCP ACK. Zapory można skonfigurować tak, aby ignorowały te pakiety, więc jeśli przejdziesz przez zaporę, która zrzuca bezczynne połączenia, mogą one nie utrzymywać połączenia.
  • ServerAliveIntervaldziała na warstwie ssh. W rzeczywistości wyśle ​​dane przez ssh, więc pakiet TCP ma zaszyfrowane dane, a zapora ogniowa nie może stwierdzić, czy jest to pakiet podtrzymujący, czy legalny, więc działają one lepiej.
Patrick
źródło
1
Myślę, że to jest właściwy kierunek. Wstępne testy wykazały, że to zadziała - przerwie wysyłanie i odbieranie podprocesów ssh / sshd najpóźniej 5 sekund po zerwaniu połączenia. Mam na myśli, że TCPKeepalive po prostu używa wartości domyślnych stosu TCP - więc trudniej jest również skonfigurować.
Nils,
To także rozwiązuje problem użytkownika-ducha. Wierzę, że można to również zrobić w ustawieniach PuTTY , zmieniając Seconds between keepalivesna 1800 w Ustawieniach | Połączenie.
Bob Stein
7

Ta TCPKeepAliveopcja jest w rzeczywistości zupełnie inną metodą utrzymywania połączeń przy życiu niż opcje podobne do ClientAlive lub ServerAlive.

Są na stronie podręcznika BSD SSH , możemy przeczytać, że:

Żywe wiadomości klienta są wysyłane zaszyfrowanym kanałem i dlatego nie będą sfałszowane. Włączona opcja TCP keepalive TCPKeepAlivejest sfałszowana. Żywy mechanizm klienta jest cenny, gdy klient lub serwer zależą od wiedzy, kiedy połączenie staje się nieaktywne.

TCPKeepAliveUpewnić się, czy system powinien wysyłać wiadomości keepalive TCP na drugą stronę. Domyślna opcja jest zawsze włączona.

Jeśli używasz ClientAliveInterval, możesz wyłączyć TCPKeepAlive. Ta opcja wyśle ​​wiadomość przez zaszyfrowany kanał z prośbą o odpowiedź od klienta (domyślnie jest to 0, więc żadne wiadomości nie są wysyłane do klienta) i ClientAliveCountMaxustawia liczbę aktywnych wiadomości klienta, zanim sshd rozłączy klienta, kończąc sesja.

kenorb
źródło