Классический SSH замечателен до тех пор, пока соединение стабильно. Метро, поезд, мобильный интернет на трассе - и сеанс виснет, переподключение заново, история рабочего tmux на удалённой стороне хоть и спасает работу, но терпение плавится. Mosh строит соединение иначе: вместо TCP поверх unreliable прокладывается UDP с собственным протоколом синхронизации экрана, и сессия переживает обрывы, смены сети и даже смену IP-адреса клиента. В статье разбираем практику применения: где выигрыш очевиден, как настроить firewall, чего ждать от интерактивного набора и какие ограничения важно знать заранее.

Как mosh отличается от SSH под капотом

SSH держит TCP-сеанс: разорвался канал - сеанс умер окончательно, хотя tmux на сервере и спасает содержимое, вы всё равно заходите заново. Mosh же работает через UDP и протокол State Synchronization Protocol: клиент и сервер постоянно синхронизируют состояние экрана, пережидая потери пакетов и таймауты. Сессия привязана не к адресу, а к ключевой паре, и когда ваш ноутбук вылез из метро в домашний Wi-Fi, mosh само собой продолжает с полуслова, без перелогина и задержек.

Второе отличие - честное эхо. SSH показывает набранное, когда до сервера дошёл ответ; при RTT в 400 миллисекунд набор превращается в пытку. Mosh предсказывает результат набора мгновенно и подчёркивает неподтверждённые символы: при плохом канале вы печатаете в полном темпе, а подчёркнутый текст сам догоняет серверное проявление по мере доставки пакетов. Для людей с плохим интернетом это тот момент, после которого возвращаться не хочется.

Установка и первое подключение

На обеих сторонах ставится пакет mosh: apt install mosh на Debian и Ubuntu, dnf install mosh, brew install mosh - инструмент давно устоялся. Подключение выглядит как mosh user@host, но под капотом происходит трюк: сначала открывается обычное SSH-соединение, которое запускает mosh-server, распечатывает ключ и порт, и только затем клиент переходит на UDP-сеанс. Поэтому SSH-доступ остаётся обязательным: mosh не заменяет аутентификацию, а опирается на неё.

Firewall в связи с этим настраивается в двух местах: стандартный SSH на TCP 22, плюс диапазон UDP-портов для сеансов - обычно открывают 60000-61000. На ufw это ufw allow 60000:61000/udp, на security groups в облаке аналогичное правило UDP. Совсем блокировать лишнее не стоит и намеренно сужать диапазон разумно: каждый живой сеанс занимает один порт, и тысячей одновременных mosh-сессий пусть мучается кто-то другой.

Типовые сценарии, где выигрыш максимален

Первый сценарий был уже обозначен: мобильная связь. Дежурный инженер в дороге подправляет конфиг и читает логи так, как будто сидит в офисе. Второй - странствующий рабочий день между домом и коворкингом: ноутбук закрывается, перемещается, открывается в новой сети, а сессия не заметила эмиграции. Третий - удалённые площадки с неровными каналами: спутниковые и LTE-модемы на объектах дают потери и таймауты, и mosh сглаживает их до вполне рабочего состояния.

Четвёртый - долгие интерактивные процессы на flaky-каналах: вы запустили прогон тестов на сервере и свернули ноутбук, а после сна просто продолжили смотреть логи. Пятый - обучение и pair-коммуникация по слабым каналам, где стабильность важнее красоты: наблюдение тянется часами и не падает.

Ограничения и границы применимости

Честный разговор не может обойти ограничения. Mosh не умеет scp и sftp: передача файлов по-прежнему делается через SSH-инструменты, и на практике рядом живёт второе подключение для чисто файловых задач или rsync поверх ssh. Полноэкранные программы работают, но прокрутка истории терминала не такая, как в локальном скроллбэке: mosh отдаёт текущее состояние экрана, и для long-scroll-back его сочетают с tmux на сервере, где scrollback надёжен. Третье - поддержка X11-forwarding отсутствует: GUI-приложения по сети остаются территорией SSH.

Ещё один граничный случай - крайне низкие MTU и строгие middlebox, которые трогают UDP агрессивнее, чем TCP. Большинство сетей пропускают, но на путях с жёстким DPI Mosh иногда заметно хуже себя чувствует, и там остаётся запасной вариант. И уж совсем формальная мелочь: mosh не лечит от перезагрузки сервера, потому что mosh-server живёт на нём; для переживания ребутов пользуйтесь tmux, как и прежде.

Связка с tmux, практический эталон

Высший пилотаж выглядит так: на сервере tmux постоянен, а клиент mosh подключается к нему с attach: создаём alias mserv='mosh user@host -- tmux attach -t main || mosh user@host -- tmux new -s main'. Получается устойчивость многослойная: любые сетевые бури переживает mosh, а смерть клиента или перезагрузку ноутбука переживает tmux; серверная сторона вообще не тревожится ни при каком сценарии. Именно так сидят с админского поезда до офисного свитча, не теряя состояния работы.

Отладка самой связки несложная: при проблемах перво-наперво проверяется, что на сервере установлены и SSH, и mosh, затем что UDP-диапазон принял firewall; полезна и опция mosh --ssh="ssh -p 2222" для нестандартного порта SSH. Логи mosh-server временно падают в домашний каталог, и их легко прочитать при редких проблемах с кодировкой или локалью, которых можно избежать заранее, наведя порядок в LANG и LC_ALL на обеих сторонах.

Итог для практиков

Держите рамку простой: если интернет у вас дома толстый и стабильный, mosh вам не нужен. Если работаете из поездов, кафе, с объектов и с мобильного модема - mosh это другое качество жизни, а не просто замена SSH. Настройка занимает вечер, включая firewall, зато годы эксплуатации после этого посыплются избавлением от мелочей вроде оборванной сессии посреди vim, а это уже из категории привычек, за которые благодарит даже память мышц.

Конфигурация сервера, прописываем навсегда

Разовый опыт это хорошо, но mosh заслуживает стабильной прописки. На сервере проверяется пакет, открывается диапазон UDP, и в sshd_config ничего менять не надо: mosh заходит по тому же SSH-входу, что и раньше, и отдельной службы на постоянной основе не существует - mosh-server стартует при каждом подключении автоматически и умирает вместе с последним сеансом. С точки зрения systemd ничего не прибавилось, и это приятно.

Клиентская сторона тоже настраивается один раз: alias-обёртки в bashrc для частых хостов сразу с tmux attach, отдельный профиль в ssh config для портов и имён захода. Клиенты mosh существуют не только для Linux: iOS-пользователи давно пользуются его реализацией в Blink Shell, на macOS ставится пакет через brew, на Windows проще всего работать через WSL, где живёт родная сборка. Локаль бывает капризничает на старых серверах: если хост собран с древним набором библиотек, экспортируйте LC_ALL=C на сессию с mosh, и странности исчезнут.

Отдельного абзаца достоин запуск через цепочку переходов: если SSH не доступен напрямую, но поднят jump-хост, mosh уважает настройки ssh - пересадочные хосты и прочие секции ssh_config работают прозрачно. Всё, что вы уже умеете в своём SSH-конфиге, применимо и здесь: имена, ключи, пересадочные хосты и таймауты.

Производительность под плохой сетью, ожидания и замеры

Задержка при интерактивной печати меняется принципиально: локальное эхо убирает паузу между нажатием и проявлением символа, поэтому при латентности в полсекунды и потерях вы печатаете в полном темпе. Смена окружения тоже щадит нервы: переход между Wi-Fi и LTE случается прозрачно, а сеанс живёт дальше. Честный замер устраивается просто: на фоне тикает ping до сервера, вы работаете, пока пакеты гуляют в обрывах; mosh переносит такую качку заметно спокойнее привычного SSH, который давно бы впал в ожидание.

Секрет живучести в том, что mosh не изображает гарантированный транспорт: протокол допускает потери и догоняет текущее состояние экрана самым коротким путём. На практике это означает, что подтверждения могут запаздывать, а сеанс при этом продолжает честно работать, и текст выравнивается без вашего вмешательства. Для оперативной командной строки это роскошь, сравнимая с переездом из дозвона в широкополосную эпоху.

Что делать, если оно не поднимается

Короткая диагностическая памятка закрывает большинство проблем. Первое: mosh user@host не прошёл - проверьте обычный SSH на тот же хост: если и он не пашет, mosh ни при чём. Второе: SSH работает, а mosh не стартует - проверьте, установлен ли mosh на сервере и открыт ли UDP-диапазон; tcpdump udp portrange 60000-61000 на сервере покажет, доходят ли пакеты вообще. Третье: странные символы на экране - сверьте локали LANG и LC_* на обеих сторонах. Четвёртое: сеанс замирает без причины - посмотрите, не режет ли middlebox UDP на пути, и попробуйте резервный SSH.

Финал, кому это надо прямо сейчас

Если вы регулярно работаете по SSH из машин, которые живут далеко и нестабильно - дойдите до пакетного менеджера и оформите этот инструмент уже сегодня. Двадцать минут конфигурации купят вам годы спокойного набора текста в любой точке карты, и это та редкая сделка, где выгода превышает цену в несколько порядков.

Длительные сессии и автоматизация на мобильном канале

Отдельный практический вопрос: как быть с автоматизированной работой и долгими наблюдениями. mosh изначально интерактивен, и пакетная работа внутри mosh-сессии вполне возможна, но для регулярной автоматики стоит оставить классику: скрипты ходят по SSH, потому что им нужна надёжная передача данных, а не интерактивность. Разделение ролей на практике выглядит естественно: люди сидят через mosh, роботы ходят через SSH. Конфликт тут невозможен, потому что задачи ортогональны.

Для наблюдений в движении выручает привычный tmux: вы подключились с телефона, запустили наш давешний watch или tail -f в окне tmux, и можете спокойно выключить экран до конца поездки; сеанс mosh переживёт питание, а tmux всё помнит. Такой "ленивый дежурный" сценарий работает годами в местах, где даже ноутбук открывать неудобно: современные терминалы на телефоне рендерят UTF-8 и 256 цветов не хуже десктопа.

Идея последней привычки

После недели с mosh происходит забавная вещь: вы перестаёте замечать качество канала как фактор планирования работы. Раньше правка конфига на удалённом сервере могла не состояться из-за того, что "сейчас мы в тоннеле", а теперь вы просто работаете, и тоннели существуют где-то вне вашей головы. Инструменты, которые делают такое с мозгом, это и есть настоящие ценные находки - они не просто экономят секунды на переподключение, а освобождают внимание, и внимание это единственная валюта, которую операционный инженер тратит каждый день безвозвратно.

Итоговая памятка для внедрения за один вечер

Подведём практический итог буквально в плане на вечер. Поставьте пакет mosh на клиент и сервер, откройте UDP 60000-61000 на серверной стороне и в облачной группе безопасности, сделайте пробное подключение mosh user@host, затем заверните его в привычный attach к tmux и сохраните команду алиасом. После этого проверьте нестандартный порт SSH через механизм конфигурации mosh --ssh, если он у вас нестандартный. На этом всё: профилактика закончена, и мобильная работа впредь перестанет быть подвигом, требующим нервов и терпения.

Отдельной строкой заметим, что mosh и SSH не враждуют: они прекрасно живут бок о бок на одном хосте, и никто не мешает вам выбирать транспорт под задачу. Файлы - через rsync по SSH, интерактив - через mosh, долгоживущие сеансы - в tmux поверх него же. Такое расслоение это не путаница, а зрелость рабочего места, где у каждого средства своя конюшня.

Пусть ваш следующий вечерний запуск из вагона будет такой же рутиной, как из офисного кресла, - именно для этого этот протокол и написали почти пятнадцать лет назад, а он до сих пор впереди многих молодых.
Попробуйте один раз - и возвращаться не захочется.
Пусть ваши сессии живут дольше, чем соединения под ними.
Спокойный ключ в кармане!