Екран або подібне для автоматичного відновлення нестійкого ssh-з'єднання


18

Мені часто доводиться підключатися до сервера через ssh у ненадійному середовищі wifi. На сервері я запускаю екран, тому якщо я відключаюсь, я можу знову підключитися та відновити сеанс на екрані та вибрати місце, де я припинився, але втрата з’єднання все ще є основною затримкою часу: якщо з'єднання припиняється, поки я я на сервері, вікно терміналу має тенденцію до замерзання. Мені потрібно вбити цю вкладку, відкрити нову, знову сш на сервер і відновити сеанс екрана. Я спробував це з запущеним екраном на сервері та локальним екраном. У будь-якому випадку вона, як правило, замерзає, коли з'єднання припиняється.

Чи є у мене спосіб мати щось подібне до екрана чи, можливо, сам екран, який автоматично спробує знову підключитися та тримати сеанс роботи, тому мені не доведеться продовжувати повторне з'єднання вручну? Часто, коли я втрачаю зв’язок, я думаю, що це лише дуже короткий період - можливо, менше секунди.

Я використовую Ubuntu 14.04 LTS, MATE видання. Спасибі


4
Повторно "Вікно оболонки має тенденцію до замерзання": Це тому, що ваш локальний ssh ​​не знає, що з'єднання мертве. Натисніть <Enter>та введіть, ~.щоб сказати вашій стороні перервати з'єднання, і ви можете просто повторити останню команду ssh для повторного з'єднання (наприклад, зі стрілкою вгору чи !!).
alexis

@alexis, це здається швидшим способом відновлення зв'язку, дякую! Я хотів би, щоб це сталося автоматично, хоча ...
Макс Вільямс,

Відповіді:


23

Ви можете подивитися за допомогою mosh: https://mosh.org/

Ви можете налаштувати «стрибаючий» сервер із надійним підключенням до Інтернету, до якого ви використовуєте moshдля підключення, а потім провести sshсеанси на кожному сервері, яким ви керуєте. Причина, яку я пропоную використовувати стриб-сервер, полягає в тому, що ви, можливо, не бажаєте встановлювати moshна серверах, якими ви керуєте.

Ще однією перевагою moshє те, що він базується на UDP, а не на TCP, і ваш сеанс може пережити зміну IP-адреси, наприклад, перехід від WiFi до мобільного Інтернету.

Просто, щоб зрозуміти, moshце не заміна screen, а навпаки ssh. Це все-таки хороша ідея використовувати screenз нею, оскільки moshсам по собі не дає способу знову підключитися до сеансу, якщо клієнт помирає з якихось причин.


Дякую, що це лише один сервер (більшість часу), і ми ним володіємо, тому я повинен мати можливість встановити Mosh. Я перевірю це.
Макс Вільямс

Насправді виявляється, що оскільки наш сервер досить старий (або працює старий Ubuntu, я мушу сказати), його важко встановити. :(
Макс Вільямс

@MaxWilliams скільки років? Навіть LTS 12.4 вийшов із підтримки. І чому б просто не спробувати скласти його самостійно
phuclv

Коли я читаю документи mosh, вам потрібен mosh-сервер на кожному хості, яким ви збираєтесь віддалено керувати. Все-таки, безумовно, цікаво.
Wildcard

1
Підключення до терміналу tmux через mosh - для мене найбільш стабільне рішення.
Немо

3

Я використовую tmuxвже декілька років, і за моїм досвідом, вона автоматично підключається. Принаймні, коли з'єднання виходить з ладу лише порівняно короткий час. Зауважте, що я фактично використовую byobuз tmux як бекенд. Я не знаю , якщо це надійність є ознакою tmuxабо byobuнавіть комбінації з двох, але я пропоную вам як спробувати.

Я підключаюсь з локальної установки Arch до різних віддалених серверів Ubuntu через VPN. Я перевірив це зараз, відключивши мережевий кабель під час підключення до пульта. Сесія зависла, але як тільки мій кабель був підключений знову, він відновився без проблем.

Однак, коли я перевірив перезапуск маршрутизатора, з'єднання не повернулося. Я припускаю, що це має щось спільне з тим, як довго працювала мережа, але, здається, вона знову підключиться, якщо буде лише кілька секунд.

У випадку, якщо це доречно, я роблю все це, використовуючи terminatorмій емулятор терміналу.

Усі три доступні у сховищах Ubuntu:

sudo apt-get install tmux terminator byobu

Однак я зовсім не впевнений, що tmuxабо byobuкраще справлятися з відключеннями ssh. Я знаю лише, що, на моєму досвіді, вони часто повертаються з коротких втрат підключення. Це, можливо, зводиться до інших аспектів моєї конфігурації.


1
При перезапуску маршрутизатора вам може бути надана інша загальнодоступна IP-адреса, яка порушила tcpз'єднання. З мого досвіду sshможе бути дуже стійким до переривчастої виходу з мережі, я не думаю, що це має нічого спільного з тим, що ви використовуєте tmuxвсередині sshвікна.
іржавий Шеклфорд

3
Я збирався сказати те саме: навіть із звичайним SSH, ви можете мати справу з коротким відключенням, доки TCP-з'єднання не вмирає. Що це може, якщо ваш інтерфейс вимкнеться, або якийсь надмірний роутер вбиває його (NAT-маршрутизатори можуть забути стан NAT при перезавантаженні та розірвати наявні з'єднання), або ClientAlive/ ServerAliveтригери, або ... Я не маю уявлення, що byobuробить, хоча .
ilkkachu

Так, але ОП, здається, відчуває замерзання при будь-якому зриві з’єднання, в той час як я цього не роблю. Але так, ти маєш рацію, я також бачу це з простим ssh і без tmux. Тим не менш, може, екран не може з цим впоратися?
terdon

2
@MaxWilliams tmux- це в основному більш сучасна альтернатива screen, так. Коли я вперше почав працювати так, як я зараз, і мені потрібна була така річ, моє побіжне читання припустило, що tmuxнайкращий вибір у наші дні. Я також не на 100% впевнений, що він покращує управління втраченими з'єднаннями, і все, що я знаю, це те, що він справді відновлюється після коротких перебоїв у моєму досвіді. Чи то це, tmuxчи щось інше, я не знаю. Але, схоже, варто спробувати :). Byobu - це в основному інтерфейс для екрана / tmux, а не емулятор терміналу GUI. Це надзвичайно корисно, хоча: byobu.org
terdon

2
tmux нічого не робить з приводу переривань зв’язку. Він працює з термінальним пристроєм, наданим ssh. Це все стоїть і падає за допомогою ssh-з'єднання.
Jonas Schäfer

2

Використовуйте ServerAliveпараметри ssh, щоб виявити, коли з'єднання не вдалося.

ServerAliveCountMax
Встановлює кількість активних повідомлень сервера (див. Нижче), які можуть бути відправлені без ssh (1) отримання будь-яких повідомлень назад із сервера. Якщо цей поріг буде досягнуто під час надсилання активних повідомлень сервера, ssh відключиться від сервера, припинивши сеанс. Важливо відзначити, що використання живих повідомлень сервера дуже відрізняється від TCPKeepAlive (нижче). Живі повідомлення сервера надсилаються через зашифрований канал і тому не підлягають підробці. Параметр TCP keepalive, включений TCPKeepAlive, можна підключити. Механізм "живий сервер" є цінним, коли клієнт або сервер залежать від того, коли відомо, коли з'єднання стало неактивним.

Значення за замовчуванням - 3. Якщо, наприклад, ServerAliveInterval (див. Нижче) встановлено 15, а ServerAliveCountMax залишено за замовчуванням, якщо сервер не відповідає, ssh відключиться приблизно через 45 секунд.

ServerAliveInterval
Встановлює інтервал тайм-ауту в секундах, після якого, якщо дані від сервера не отримано, ssh (1) надішле повідомлення через зашифрований канал, щоб запитати відповідь від сервера. За замовчуванням 0, що вказує на те, що ці повідомлення не надсилаються на сервер.

Тож якщо ви встановите ServerAliveInterval5, sshавтоматично відключається, якщо мережа відшаровується протягом 15 секунд.


Щоб насильно перервати сеанс SSH, я натискаю ~.(або спочатку Enter, потім ~.), що складається з: символу втечі ~та команди перервати сеанс.
imz - Іван Захарящев

@ imz - ІванЗахарящев Це означає, що ви можете сказати, що зв’язок висів. Використання ключів SSH виявить несправність автоматично.
Бармар

Це звучить дуже корисно, дякую, я обов'язково спробую, що наступного разу я опинюсь у «лускатій зоні».
Макс Вільямс

@Barmar Так, правда. Я також замислювався над проблемою визначення того, чи дійсно з'єднання висіло, або я натиснувши щось, може випадково надіслати ці клавіші на віддалений бік ... І я не знаю хорошого рішення.
imz - Іван Захарящев

2

У подібних умовах я, як правило, використовую eshellTRAMP (понад ssh) всередині Emacs. TRAMP піклується про повторне підключення при необхідності, не створюючи мені особливих проблем, даючи потрібні команди для віддаленої оболонки.

Однак eshell не є хорошим як термінал, тобто для запуску команд, які роблять щось особливе з терміналом, або які виконуються протягом значного періоду часу, постійно (поступово) друкуючи щось.

В основному, почати використовувати його в Emacs з TRAMP: досить просто:

M-x eshell
cd /user@host:

1

Відмова від відповідальності

Якщо ваш 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клієнту.

Ймовірно, кандидати включають:

  1. Брандмауери або NAT-маршрутизатори, яким потрібно використовувати пам'ять для запам’ятовування кожного прямого TCP-з'єднання - як оптимізація та деяке пом’якшення проти DOS-атак, вони іноді просто забудуть ваше з'єднання, а потім мовчки ігнорують послідовні пакети для нього, тому що пакети в в середині з'єднання, коли ви не пам’ятаєте, що існуюче з'єднання виглядає недійсним.

  2. Брандмауери / маршрутизатори, які краще ведуть себе, вводять пакет TCP RST, який зазвичай проявляється як connection reset by peerповідомлення про помилку, але пакет скидання - це затримка та забуття, тому якщо підключення до вашого клієнта все ще має проблеми в цей момент і скидає скиньте пакет також, ваш клієнт подумає, що з'єднання все ще живе.

  3. Сервер сам може мати політику брандмауера мовчазно опускаєте несподівані пакети, які будуть ламаються спроби підключення відновлення клієнта щоразу , коли сервер вважає , що з'єднання закрито , але покупець не буде : ваш клієнт продовжує намагатися продовжити з'єднання, а сервер просто ігноруючи це, оскільки немає жодного живого з'єднання, до якого ці пакети належать у брандмауері сервера.

    Оскільки ви працюєте з Linux, уважно перевірте iptables/ ip6tablesабо ( nftякщо ви використовуєте новий матеріал) на саме те, що ви дозволяєте, порівняно з випаданням. Дуже часто дозволити нові / встановлені / пов’язані пакети на порту TCP SSH, але не "недійсні" - якщо ви мовчки скидаєте все, що заборонено, ця звичайна установка може викликати подібні заморозки після коротких проблем з підключенням .

  4. Сам ваш SSH-сервер може бути налаштований на закриття з'єднання після періоду бездіяльності, використовуючи один з параметрів OpenSSH для пакетів зберігання клієнтів TCP або SSH. Це само по собі не призведе до невизначеного зависання, але воно може поставити вас в один з описаних вище станів.

  5. Можливо, ви просто не даєте йому достатньо часу, щоб самостійно "розчепитися" після того, як ви перейдете до стану, в якому засідає sshсеанс.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.