Блокировка SSH: подозрительная локальная проблема, а не удаленная

На моем рабочем компьютере я регулярно SSH на два несвязанных сервера. Иногда сеанс SSH блокируется (не реагирует на ввод клавиатуры). Когда я заблокирован, я могу использовать SSH через второй открытый терминал, который работает, но не размораживает замороженный терминал. Нажатие кнопки ~. требуется некоторое время, прежде чем терминал отключится и даст мне локальный CLI. Я регулярно нахожу SSH на обоих серверах из дома без проблем, поэтому я подозреваю, что проблема связана с моим локальным рабочим компьютером.

Возникает ли проблема с другими терминалами? Да, проблема возникает как с Konqueror, так и с Terminator.

Возникает ли проблема одновременно на обоих удаленных серверах? нет

Возникает ли проблема с каким-либо конкретным приложением, запущенным на сервере? Как с GNU Screen, так и без него, как на CLI, так и в VIM.

Чтобы проверить, я просто открыл четыре терминала: два терминала Konqueror, по одному на каждый сервер; и два терминатора Terminator, по одному на каждый сервер. Примерно через час только один терминал (Терминатор) заблокирован. Другой терминал на том же сервере не блокировался, и ни один терминал на другом сервере не был заблокирован. Конечно, я попробовал Ctrl-Q в заблокированном терминале, чтобы увидеть, был ли отправлен ошибочный Ctrl-S, но это не решило проблему. Экран не был запущен в закрытом терминале (ни в собственном сеансе, где работает SSH, ни в сеансе SSH).

UPDATE: через час сервер, запертый в Terminator, наконец отключился с «Ошибка записи: Broken pipe», и у меня есть рабочий локальный CLI, и оба сервера в Konsole также заблокированы.

Что-то вдоль цепочки выдает время бездействующего соединения, поскольку SSH обычно не отправляет ничего при простоях. Но вы можете заставить его отправлять сообщения периодически в режиме ожидания. В OpenSSH версии 3.8 и выше:

 $ ssh -oServerAliveInterval=60 myremotebox 

Если вы часто отправляете ssh вручную на этот хост, скорее всего, вы захотите поместить его в свой файл ~/.ssh/config :

 Host myremotebox ServerAliveInterval=60 

Это говорит ему отправить нулевой пакет каждые 60 секунд после того, как ничего не отправлено. Я нашел в широком спектре инфраструктуры, что этого достаточно, чтобы поддерживать связь.

В pre-3.8 версиях OpenSSH у вас нет этой опции, но есть слабый запас. Вы можете установить параметр KeepAlive , который использует TCP keepalives . Способ, которым это работает, зависит от ОС, и часто изменение его поведения влияет на все приложения. Хуже того, сетевые стеки обычно по умолчанию отправляют TCP keepalives каждые 2 часа по умолчанию, поэтому вам почти нужно изменить значение по умолчанию, если вы собираетесь использовать его таким образом, так как время ожидания вашего соединения SSH, вероятно, имеет простаивающий порог намного ниже чем 2 часа.

Обратите внимание, что если вы читаете документы версии 3.8+, это то же самое, что и параметр TCPKeepAlive . Когда они добавили опцию «сервер в живом» в 3.8, они переименовали KeepAlive в TCPKeepAlive чтобы отличить их.