reliable ssh via unreliable link

Mar 12, 2024 16:36

Мне довольно часто приходится работать в ssh через ненадёжное соединение или переключаясь между сетями или сотами или точками доступа.
В этом случае ssh-соединение падает, приходится логиниться заново, это неудобно.

Есть разные способы смягчения проблемы. Наиболее распространённый - использование screen или tmux. Это позволяет сохранить контекст сессии, но всё равно нужно перелогиниваться после обрыва соединения.
mosh сохраняет сессию даже при смене IP, но у него собственный эмулятор терминала, и это ломает scrollback buffer. Для того, чтобы сохранить scrollback, советуют совместить mosh и screen, но полного решения проблемы это всё равно не даёт.
Пробовал ещё quicssh, Eternal Terminal и другие утилиты, но такой, чтобы удовлетворила, не нашёл, поэтому написал свою. Возможно, такая ситуация не только у меня, поэтому публикую как opensource - вдруг кому-то пригодится.

udp-link: устанавливается с обеих сторон линка (рут необязателен, можно и в свой homedir), прописывается в .ssh/config как "ProxyCommand udp-link %h %p". Первоначально поднимает обычное ssh-соединение (поэтому работает обычная авторизация паролем или ключом), потом генерирует случайный ключ, запускает udp-link на стороне сервера, поднимает udp-линк между клиентом и сервером на верхних портах, после чего первоначальное ssh-соединение (tcp) завершается, и остаётся ssh-линк через udp, который переживает временный даун интерфейса, смену IP и пр. Это подобно тому, как работает mosh, с той разницей, что udp-link не эмулирует собственный терминал, а сохраняет привычный ssh workflow. И, соответственно, не нужно вместо ssh запускать mosh или что-то другое - запускается тот же ssh, просто для него меняется транспортный уровень с tcp на udp.
Может работать через IP NAT. По умолчанию используются udp-порты 43200-44000, так что нужно открыть этот диапазон на вход в файерволе, если по умолчанию всё закрыто. Кроме того, полезно на стороне сервера отключить опции ClientAlive* and TCPKeepAlive или сделать их значения достаточно большими, иначе при проблемах с линком сервер будет дропать соединение по неактивности, и udp-link с этим ничего поделать не сможет.

Если у вас используется jump-server, получается ещё удобнее: udp-линк можно установить только на этом jump-server, а в конфиге прописать "ProxyCommand udp-link --target %h:%p your-jump.server". В этом случае соединение от клиента до jump-сервера будет через udp, а дальше, от jump-сервера до сервера назначения - tcp, как обычно, и на сервере назначения ничего дополнительно ставить не нужно.

Установить можно либо из deb-пакета (собрано под Ubuntu), либо собрать из исходников.

This entry was originally posted at https://gul-kiev.dreamwidth.org/71071.html.
Previous post
Up