Jak zapobiec „Zapis nieudany: uszkodzona rura” na połączeniu SSH?

283

Co mogę zrobić, aby skonfigurować SSH na kliencie i serwerach, aby zapobiec Write Failed: broken pipebłędom? Często występuje, gdy komputer jest uśpiony i wznawiany później.

sorin
źródło
8
Nic takiego. Sesja została przerwana, a bezpieczeństwo sesji zostało naruszone. Jeśli nie przełączysz komputera w tryb uśpienia, możesz ustawić czas podtrzymania dla klienta, aby strzelił utrzymywać bicie serca na serwerze, ale jeśli system idzie spać, nic nie można zrobić.
darkdragn
3
W tym przypadku szukam czegoś, co pozwoliłoby mi ponownie zainicjować zerwane połączenie ssh (prawdopodobnie oparte na kodzie wyjścia) i przywrócić za pomocą screen?
sorin
4
Ludzie się mylą: mam DWIE komputery klienckie łączące się z SAMYM serwerem. Jednym z nich jest Ubuntu 12.10, Quantal, którego klient SSH działa dobrze i utrzymuje połączenie przez wiele godzin. Drugim jest Ubuntu 14.10, Utopic, oprócz drugiego w nowej instalacji; po kilku minutach blokuje się tym komunikatem. Pozostałe funkcje sieciowe w urządzeniu nie są przerywane. Więc nie, nie jest to ani problem z siecią, ani problem z serwerem, ale konkretny problem oprogramowania SSH CLIENT, który MOŻE zostać rozwiązany, w przeciwieństwie do tego, co ośmiela się powiedzieć „darkdragan”, że „nic nie da się zrobić”.
David L
2
I rzeczywiście, jak powiedziałem: ludzie mówią za dużo, mówiąc „nic nie da się zrobić”, tak jak odważył się @darkdragn. Przeczytałem odpowiedź Arama Kocharyana i zastosowałem ją: 20 minut temu ... Uświadomiłem sobie, że w moim starym Quantal Ubuntu 12.10 zastosowałem tę instrukcję w tym pliku [właśnie sprawdziłem] dwa lata temu i to było przyczyna stabilności tam. Zrobiłem to tutaj i przez ostatnie 20 minut połączenie było stabilne. Więc proszę, ludzie: powstrzymajcie się, odważając się myśleć, że „nic nie da się zrobić”, i powstrzymujcie się jeszcze bardziej, gdy próbuję przekazać to przesłanie innym ludziom.
David L,
11
@DavidL powinieneś przeczytać pytania lepiej przed rantingiem. Twój problem nie jest taki sam jak PO, który wyraźnie wspomina o uśpieniu komputera. Który przy okazji jest tylko jedną z odpowiedzi na adres („mosh”) i został opublikowany 2 lata po pytaniu. Jednak inne odpowiedzi robią następną najlepszą rzecz, czyli proponowanie rozwiązań spraw, które można rozwiązać łatwiej, jak twoje.
Wyluzuj, nie stresuj się

Odpowiedzi:

266

Próbowałem tego w /etc/ssh/ssh_configsystemach Linux i Mac:

Host *
ServerAliveInterval 120

Tak często, w ciągu kilku sekund, powinien wysyłać komunikat podtrzymujący na serwer. Jeśli to nie zadziała, wytrenuj małpę, aby naciskała Enter co dwie minuty podczas pracy.

Można ustawić zarówno ServerAliveIntervalw /etc/ssh/ssh_configmaszyny klienta lub ClientAliveIntervalw /etc/ssh/sshd_configmaszyny serwera. Spróbuj zmniejszyć interwał, jeśli nadal pojawia się błąd.

Konfigurację dla jednego użytkownika można ustawić w pliku ~/.ssh/configzarówno po stronie serwera, jak i klienta. Upewnij się, że plik ma prawidłowe uprawnienia chmod 644 ~/.ssh/config.

Aram Kocharyan
źródło
4
Nie jestem na komputerze Mac, ale Ubuntu 12.04 i plik dla tego systemu operacyjnego również wydaje się być ~ / .ssh / config.
H2ONaCl,
5
OS X 10.8.4 podaje błądBad configuration option: ClientAliveInterval
ohho
3
Otrzymuję ten sam Bad configuration optionbłąd w OSX 10.8.4.
Nick Heiner
10
Zasadniczo umieszczasz te dwa polecenia w różnych częściach systemu. Tylko ServerAliveInterval po stronie klienta OSX ... i tylko ClientAliveInterval w pliku konfiguracyjnym sshd ...
ftrotter
2
Moja małpa powiedziała do mnie: „Dlaczego nie
piszesz
85

Sesje SSH mogą przerwać się z wielu i być może nieuniknionych przyczyn.

Nazywa się przydatne narzędzie, które można wykorzystać w celu złagodzenia spowodowanych przez to problemów screen. Screen to potężne narzędzie, które pozwala kontrolować wiele terminali, które pozostaną przy życiu niezależnie od sesji ssh. Na przykład, jeśli uruchomisz screensesję ssh, zobaczysz nowy terminal otwarty i możesz go użyć do uruchamiania zadań. Powiedzmy, że sesja ssh w tym procesie umiera. Uruchamianie screen -dnastępnie screen -rbędzie ponownie otworzyć ostatnią sesję i będzie można kontynuować stamtąd. Przed użyciem zapoznaj się z dokumentacją .

Eltommo
źródło
5
To prawdopodobnie najlepsza odpowiedź, nie jestem pewien, dlaczego nie głosowano wyżej. Inne „poprawki” są pomocne w szczególnym przypadku, w którym naprawdę zależy ci na utrzymaniu połączenia SSH, ale w większości przypadków użytkowania wydaje mi się, że prawdziwym problemem jest to, że zamierzone procesy będą działały bez względu na jakiekolwiek problemy z połączeniem klient / serwer .
Paul McMurdie,
16
Dodałbym również Tmux jako alternatywę dla screena . Uważam, że jest bardziej wszechstronny i stabilny niż ekran.
piątek
2
pozostawiając to tutaj na przyszłość - możesz wygodnie uruchomić, screen -d -raby odzyskać ostatnią sesję.
doplumi,
2
Lub po prostu screen -dr. Lub w screen -xzależności od tego, co planujesz robić. Chodzi o to, że należy wiedzieć, co robią wszystkie te przełączniki, aby można było użyć odpowiednich, a nie ślepo stosować się do sugestii internautów. Ładne kompaktowe podsumowanie jest dostępne tutaj: ss64.com/bash/screen.html
flith
To nie jest odpowiedź na problem
użytkownik3728501
46

Konfiguracja klienta

Spróbuj utworzyć plik:

~/.ssh/config

Dodaj zawartość:

Host *
  ServerAliveInterval 30
  ServerAliveCountMax 5

Teraz ssh na serwerze i sprawdź, czy problem został rozwiązany. Opcja ClientAliveInterval jest użyteczna tylko podczas konfigurowania serwera ssh (alias sshd), nie zmienia niczego po stronie klienta ssh, więc nie używaj go w powyższym pliku konfiguracyjnym.

Spowoduje to wysłanie do serwera sygnału „witaj, jesteś tam”, jeśli w ciągu ostatnich 30 sekund nie otrzymano żadnych pakietów (jak określono powyżej). Jeśli jednak liczba kolejnych sygnałów „witaj, jesteś tam” dociera do ServerAliveCountMax, ssh rozłączy się z serwerem. Wartość domyślna to 3 (więc 3 * 30 = 90 sekund bez aktywności serwera), zwiększ ją, jeśli odpowiada twoim potrzebom. Plik .ssh / config zawiera wiele innych opcji konfiguracji i można przeczytać:

Korzystanie z pliku konfiguracyjnego SSH

Aby uzyskać więcej informacji na temat innych opcji. Możesz nie chcieć stosować tego do każdego serwera, z którym się łączysz, z którym to zrobisz. Lub powstrzymać go tylko do danego serwera przez zastąpienie linii Host *z Host <IP>(zastąpienie przez adres IP, patrz strona ssh_config Man).

Konfiguracja serwera

Podobnie możesz powiedzieć serwerowi, aby był łagodny wobec swoich klientów. Plik konfiguracyjny to /etc/ssh/sshd_config.

ClientAliveInterval 20
ClientAliveCountMax 5

Można też wyłączyć przez ustawienie ClientAliveIntervalsię 0lub uszczypnąć ClientAliveIntervali ClientAliveCountMaxustawić maksymalną ssh bezczynność klient nie odpowiadając na sondach. Jedną z zalet tych ustawień w porównaniu z TCPKeepAlive jest to, że sygnały są przesyłane zaszyfrowanymi kanałami, więc jest mniej prawdopodobne, że będzie sfałszowane.

Matt
źródło
To nie działa Znów mam ten sam błąd.
user997704,
3
Spróbuj bezpośrednio z wiersza poleceń i zejdź niżej: ssh -o ServerAliveInterval = 5 użytkownik @ host
Matt
Próbowałem to też ... nie działa. Naprawdę nie wiem, co się dzieje z moim systemem
użytkownik997704,
2
To ClientAliveCountMax, NOT ClientAliveMaxCount
David G
@DavidG Edytuj odpowiedź z poprawkami.
CivMeierFan
23

Zdalnie aktualizuję serwer Ubuntu z przejrzystego do precyzyjnego i straciłem połączenie ssh w trakcie aktualizacji z komunikatem „Zapis nieudany. Brocken potok”. ClientAliveInterval i ServerAliveInterval nic nie zrobiły. Rozwiązaniem jest włączenie opcji TCPKeepAlive w ssh klienta:

TCPKeepAlive yes

w

/etc/ssh/ssh_config
Alexey Sviridov
źródło
20

W przypadku klienta edytuj plik ~/.ssh/config(lub /etc/ssh/ssh_config) w następujący sposób:

Host *
  TCPKeepAlive yes
  ServerAliveInterval 120

TCPKeepAlive - określa, czy system powinien wysyłać komunikaty podtrzymujące TCP na drugą stronę. Jeśli zostaną wysłane, śmierć połączenia lub awaria jednego z urządzeń zostanie odpowiednio zauważona. Oznacza to jednak, że połączenia umrą, jeśli trasa będzie chwilowo nieczynna, a dla niektórych osób będzie to denerwujące (domyślnie „tak”).

ServerAliveInterval - Ustawia limit czasu w sekundach, po którym, jeśli nie otrzymano żadnych danych z serwera, ssh (1) wyśle ​​wiadomość przez zaszyfrowany kanał z prośbą o odpowiedź z serwera. Wartość domyślna to 0, co oznacza, że ​​te wiadomości nie będą wysyłane na serwer.


Na serwerze edytuj swój /etc/ssh/sshd_configjako:

ClientAliveInterval 600
ClientAliveCountMax 0

Jeśli chcesz, aby klient ssh wychodził automatycznie (limit czasu) automatycznie po 10 minutach (600 sekundach).

ClientAliveCountMax - wskazuje całkowitą liczbę komunikatów kontrolnych wysłanych przez serwer ssh bez uzyskiwania odpowiedzi od klienta ssh. Domyślnie jest to 3.

ClientAliveInterval - wskazuje limit czasu w sekundach. Po x liczbie sekund serwer ssh wyśle ​​do klienta wiadomość z prośbą o odpowiedź. Niesłyszący ma wartość 0 (serwer nie wyśle ​​wiadomości do klienta w celu sprawdzenia).


Zobacz także: Czym dokładnie są opcje ServerAliveIntervali ClientAliveIntervalw sshd_config?

kenorb
źródło
Ustawienie ServerAliveCountMax na wartość wyższą niż domyślna na kliencie powinno również pomóc w utrzymaniu połączenia na żywo w przypadku wolnych połączeń.
jonnyjandles
17

Absolutnie kocham Mosha. Często ssh do serwera, zamykam laptopa i idę do kawiarni, otwieram i kontynuuję, jakby nic się nie zmieniło.

Mosh (mobilna powłoka)

Aplikacja zdalnego terminala, która umożliwia roaming , obsługuje przerywane połączenia oraz zapewnia inteligentne lokalne echo i edycję linii klawiszy użytkownika.

Mosh zastępuje SSH. Jest bardziej niezawodny i responsywny, szczególnie w przypadku połączeń Wi-Fi, komórkowych i dalekobieżnych.

Mosh to darmowe oprogramowanie, dostępne dla systemów GNU / Linux, FreeBSD, Solaris, Mac OS X i Android.

Jake
źródło
6

Dla mnie robiłem to Write failed: Broken pipenawet wtedy, gdy aktywnie pisałem w vimie lub po poleceniu powłoki. Nie mogłem też przez jakiś czas przeglądać Internetu lokalnie. (Łączyłem się zdalnie z Ubuntu za pomocą terminala).

Inni w mojej sieci przesyłają strumieniowo wiele filmów z serwisu Netflix i innych miejsc. Nie mogę tego udowodnić, ale podejrzewam, że jest to problem z usługodawcą internetowym lub routerem. Na przykład Verizon i Netflix wskazują na siebie nawzajem ze względu na problemy z siecią klienta.

Jeśli masz połączenie dial-up i przesyłasz strumieniowo wideo lub muzykę z jednoczesnym połączeniem SSH lub telnet, w pewnym momencie nieuchronnie pojawi się komunikat zepsutej potoku. Aktualizacja mojego pakietu szerokopasmowego ISP sprawiała, że ​​moje zerwane połączenie było rzadsze.

Parag
źródło
3

Mam skrypt na zdalnym serwerze, który nigdy nie wydaje się zawodzić, niezależnie od klienta lub serwera konfiguracji SSH.

#!/bin/bash
while true; do date; sleep 10; done;

Zapisz go w pliku dummy.sh i szybko uruchom, zanim zminimalizujesz okno lub odejdziesz od niego. Będzie drukował bieżący znacznik czasu na serwerze i utrzyma połączenie przy życiu, dopóki połączenie nie zostanie zerwane z jakiegokolwiek innego powodu. Kiedy wrócisz do tego terminala, po prostu naciśnij CTRL + C i kontynuuj pracę.

JulioHM
źródło
9
lub po prostu przestań topdziałać
Eben Geer,
1

Możesz dodawać te argumenty za każdym razem, gdy wywołujesz ssh: -o ServerAliveInterval=15 -o ServerAliveCountMax=3

Nie musisz edytować plików konfiguracyjnych / etc / ssh / *.

Możesz utworzyć alias bash lub funkcję lub skrypt, aby to ułatwić.

Np. Te funkcje bash, możesz dodać do swojego .bashrc, do_ssh służy ręcznie do włączania keepalives. Do_ssh_pty jest używany w skryptach do ustawiania pty i unikania monitów.

do_ssh() {
    ssh -o ServerAliveInterval=15 -o ServerAliveCountMax=3 $*
}

do_ssh_pty() {
    ssh -tt -o "BatchMode=yes" -o "StrictHostKeyChecking=no" -o ServerAliveInterval=15 -o ServerAliveCountMax=3 $*
}

Teraz do_ssh user@hostmożna go użyć, lub do_ssh user@host <args> <command>aktywowane będą Keepalives.

gaoithe
źródło