Дата и время публикации:
Проблемы и решение
1. Суть проблемы
Выставить на стороне клиента и сервера SSH адекватные настройки чем те, которые установлены в листинге 1.1
Листинг 1.1
host * ServerAliveInterval 600 TCPKeepAlive yes IPQoS throughput Protocol 2
Использование широко рекомендуемых в "сети" настроек на стороне клиента SSH приводит к преждевременному разрыву соединения, потому что многие пакеты могут теряться,по моему опыту, в неустойчивых средах передачи данных, к которым относятся, например, ипользующие транспорт UDP соединения VPN, а также в силу фильтрации пакетов на уровне маршрутизаторов.
Это происходит потому, что между параметрами TCPKeepAlive и ServerAliveInterval существует значительная разница на каком уровне они применяются [3.1], так
Параметр TCPKeepAlive
Оперирует на уровне TCP, отправляя пустые пакеты TCP ACK, называемые сообщениями поддержки активности (keepalive message) и которые могут быть потеряны на уровне маршрутизатора или из неустойчивости VPN тунеля, что приведет к завершению SSH-сессии со стороны клиента или сервера [3.4].
Параметр ServerAliveInterval <nsecs>
Оперирует на уровне ServerAliveInterval, потому что фактически ssh отправляет пакеты с шифорванными данными, которые не подлежат фильтрации на уровне маршрутизатора, а тем более не зависят от качества VPN соединения. Отсылая пакет подтверждения активности (alive message) клиент тем самым подтверждает свою готовность к дальнейшему приему сообщений с данными.
Дополнительно к параметру ServerAliveInterval на стороне ssh клиента, на самом серевер SSHD может быть выставленн параметр ClientAliveInterval в файле /etc/ssh/sshd_config . В этом параметре выставляется максимальный порог количества потерянных, оставшихся без ответа от клиента, пакетов подтверждения активности, при достяжении которого SSH-сессия будет завершена на стороне сервера [3.5].
Параметр IPQoS throughput
Поле Differentiated Services Code Point (DSCP, Точка кода дифференцированных услуг) в заголовке IP служит для классификации сетевых данных и обеспечения Качества Услуг (Quality of Service, QoS). По умолчанию ssh выставляет CS1, который может быть потерян внутри OSL сетей, к которым относится VPN. Поэтому, для повышения производительности рекомендуется на стороне клиента устанавливать throughput [3.8], если используется VPN
2. Решение
Как показано в листинге 2.1, на клиентской стороне сконфигурирован SSH, в файле ~/.ssh/config, для этого используйте редактор, например, nano или vim, который создаст это файл автоматически, если он не существует.
Листинг 2.1
Host * TCPKeepAlive no ServerAliveInterval 30 ServerAliveCountMax 4800 IPQoS=throughput port 22
Или для наиболее неблагоприятной среды, как в случае VPN соединения, см. Листинг 2.2
Листинг 2.2
Host * TCPKeepAlive no ServerAliveCountMax 3600 ServerAliveInterval 30 Protocol 2 IPQoS=throughput
Эти параметры работают только на протоколе версии 2, поэтому на клиентской стороне нужно явно установить параметр Protocol 2 : наличие этого параметра включает механизм, позволяющий отправлять каждые 30 секунд и перестает отправлять пустые пакеты TCP ACK, а если превышен порог, указанный в ServerAliveCountMax
При этом, похоже, что счетчик ServerAliveCountMax не сбрасываетcя, а недолетевшие до сервера пустых пакетов TCP ACK будут только увеличиваться вполоть до закрытия сессии SSH, поэтому на плохих соединениях нужно выставлять как можно больше, например, как показано в листинге 2.3
Листинг 2.3
Host * ServerAliveInterval 20 ServerAliveCountMax 32000 ...
Так, клиент SSH будет пытаться высылать каждые 20 секунд пустой пакет TCP ACK в сторону сервера, что составит $(20*32000)/(3600.0) ~= 177$ часов открытой сессии, что важно, например, при работе с большими GIT репозитраиями. Тутже не забывем IPQoS=throughput , что дает большую устойчивость в работе SSH сессии по VPN соединению, которое может представлять собой неустойчивую среду передачи данных.
На серверной стороне в файле /etc/ssh/sshd_config , если конечно такое возможно, выставляем теже самые значения плюс небольшой запас по счетчику, что и для ClientAliveInterval и ClientAliveCountMax, как показано в листинг 2.4
Листинг 2.3
#TCPKeepAlive ClientAliveInterval 20 ClientAliveCountMax 32010
3. Библиография
3.1 Unix&Linux -- How does tcp-keepalive work in ssh?
3.2 Medium -- Keep SSH Connections Alive
3.3 How to Keep SSH Connection Alive for Longer Durations
3.4 TCP Keepalive HOWTO -- TCP keepalive overview
3.5 sshd_config — OpenSSH daemon configuration file
3.6 OpenSSH Config File Examples For Linux / Unix Users