Відмова від відповідальності
Якщо ваш SSH-з'єднання не переживає коротких відключень мережі, то відбувається щось інше, що не дозволяє sshTCP робити нормальну справу.
Детальніше дивіться нижче. У будь-якому випадку:
Найшвидше і найбрудніше рішення про незалежність
Створіть такий сценарій оболонки:
#!/bin/sh -
# Tune these numbers depending on how aggressively
# you want your SSH session to get reconnected.
timeout_options='-o ServerAliveInterval=4 -o ServerAliveCountMax=2'
# 255 is the status OpenSSH uses to signal SSH errors, which
# means we want to connect. All other exit statuses suggest
# an intentional exit.
status=255
# Keep opening the SSH connection and immediately dropping into
# `screen` until an intentional exit happens.
while [ "$status" = 255 ]
do
ssh $timeout_options -t "$@" screen -dR
status=$?
# You can add a `sleep` command here or a counter or whatever
# you might need as far as rate/retry limiting.
done
exit "$status"
Це просто запустить тупо-простий цикл, який продовжує намагатися з'єднатися sshі приєднатися до нього screen. Передайте хост або будь-що інше, що ви зазвичай переходите до sshвиклику як аргументи командного рядка.
Повторне підключення ґрунтується лише на тому, чи повідомляє SSH про помилку підключення, а це означає, що він не має інтелекту для виявлення помилок, що не належать до SSH, типу "у вас буквально не ввімкнено WiFI" або будь-якого іншого, але це, ймовірно, не має значення для ти.
Я припускаю, що у вас є ssh-agentключ SSH або без парольної фрази, який дозволить повторно підключатися до роботи без додаткового введення від вас.
Там буде крихітна гонка, коли, якщо ви потрапите ^Cпротягом лише потрібної непомітної для людини частки секунди під час повторного підключення, ви можете в кінцевому підсумку вбити сценарій замість того, щоб передавати пропуск ^Cдо клієнтського терміналу, тому, якщо ви підозрюєте, що з'єднання повіситься не збивайте ^Cзанадто ревно.
Найпростіше додаткове програмне рішення
Ви можете спробувати програму autossh , яка повинна бути доступна у вашому сховищі пакетів Ubuntu.
Якщо вам потрібно побудувати з джерела або перевірити його, це єдина програма C, яка збирається без додаткових бібліотек як залежностей, схоже, має більше інтелекту щодо перевірки життєздатності з'єднання, ніж мій злом вище, і він також постачається зі зручною rscreenкомандою сценарію, яка автоматично -приєднується до screen.
Деталі
Як sshнормально одужує
Просто для перевірки, оскільки мені не подобається говорити речі, не перевіряючи себе, я пройшов невеликий тест, перш ніж відповісти:
Я потрапив на свій WiFi з пристроєм Linux, зробив з’єднання SSH з іншим пристроєм у своїй локальній мережі, перевірив, що я працював sshна іншому кінці (міг запускати команди тощо), потім на клієнті відключив WiFi (викликаючи інтерфейс де-конфігуровано: більше IP-адрес), набрав ще більше символів у сеанс ssh (без відповіді, звичайно), а потім знову підключився до мого Wi-Fi - відновлення фактично не вдалось хоча б раз через поганий сигнал та інші фактори , потім нарешті знову підключились: я зачекав близько семи секунд, щоб sshсеанс відновився, нічого не сталося, тому я натиснув ще одну клавішу, і sshсеанс одразу ожив знову, при цьому всі ключі, які я набрав під час відключення, з’явились у командному рядку.
Дивіться, sshпросто записує / читає в мережевий сокет TCP, поки ОС не каже, що щось пішло не так, а TCP насправді дуже терпимий до тривалих перепадів з'єднання.
Залишивши власні пристрої з налаштуваннями ядра за замовчуванням, стек TCP в Linux буде радісно терпіти, коли з'єднання буде повністю безшумним протягом багатьох хвилин, перш ніж оголосити про з'єднання мертвим і повідомити про помилку ssh- до моменту, коли він остаточно відмовиться, ми говоримо в бальній частині приблизно 30 хвилин, або, принаймні, звичайно, досить довгий, щоб перетримати гикавку на зв’язку тривалістю секунди або хвилини.
Під обкладинками стек Linux TCP поступово повторює повідомлення з більш довгими та тривалими затримками, але це означає, що до моменту, коли ваше з'єднання повернеться, ви можете переглядати додаткові відставання до того, як ваш sshсеанс, здається, знову "оживе".
Чому це іноді ламається
Часто щось активно призводить до припинення з'єднання після деякого значно коротшого періоду бездіяльності, ніж сума, яку буде терпіти стек TCP, а потім не повідомляє про стан з'єднання своєму sshклієнту.
Ймовірно, кандидати включають:
Брандмауери або NAT-маршрутизатори, яким потрібно використовувати пам'ять для запам’ятовування кожного прямого TCP-з'єднання - як оптимізація та деяке пом’якшення проти DOS-атак, вони іноді просто забудуть ваше з'єднання, а потім мовчки ігнорують послідовні пакети для нього, тому що пакети в в середині з'єднання, коли ви не пам’ятаєте, що існуюче з'єднання виглядає недійсним.
Брандмауери / маршрутизатори, які краще ведуть себе, вводять пакет TCP RST, який зазвичай проявляється як connection reset by peerповідомлення про помилку, але пакет скидання - це затримка та забуття, тому якщо підключення до вашого клієнта все ще має проблеми в цей момент і скидає скиньте пакет також, ваш клієнт подумає, що з'єднання все ще живе.
Сервер сам може мати політику брандмауера мовчазно опускаєте несподівані пакети, які будуть ламаються спроби підключення відновлення клієнта щоразу , коли сервер вважає , що з'єднання закрито , але покупець не буде : ваш клієнт продовжує намагатися продовжити з'єднання, а сервер просто ігноруючи це, оскільки немає жодного живого з'єднання, до якого ці пакети належать у брандмауері сервера.
Оскільки ви працюєте з Linux, уважно перевірте iptables/ ip6tablesабо ( nftякщо ви використовуєте новий матеріал) на саме те, що ви дозволяєте, порівняно з випаданням. Дуже часто дозволити нові / встановлені / пов’язані пакети на порту TCP SSH, але не "недійсні" - якщо ви мовчки скидаєте все, що заборонено, ця звичайна установка може викликати подібні заморозки після коротких проблем з підключенням .
Сам ваш SSH-сервер може бути налаштований на закриття з'єднання після періоду бездіяльності, використовуючи один з параметрів OpenSSH для пакетів зберігання клієнтів TCP або SSH. Це само по собі не призведе до невизначеного зависання, але воно може поставити вас в один з описаних вище станів.
Можливо, ви просто не даєте йому достатньо часу, щоб самостійно "розчепитися" після того, як ви перейдете до стану, в якому засідає sshсеанс.
<Enter>та введіть,~.щоб сказати вашій стороні перервати з'єднання, і ви можете просто повторити останню команду ssh для повторного з'єднання (наприклад, зі стрілкою вгору чи!!).