SSH-соединение зависает на точке доступа 4G, но не на любом Wi-Fi

SSH-соединение зависает на точке доступа 4G, но не на любом Wi-Fi

Краткое описание

Я наблюдал странное поведение моего SSH-подключения в течение многих лет, но никогда не думал поднимать вопрос до сегодняшнего дня. Я пытался много искать об этом, но не мог найти никакой причины.

Среда

  1. По сути, у меня есть несколько экземпляров AWS EC2, работающих в разных регионах (например, в Ирландии, Мумбаи и т. д.).
  2. У меня Mac.
  3. И я нахожусь в Индии (если это кого-то удивит).

Постановка проблемы 1

Когда мой Mac подключен к персональной точке доступа (с устройства Samsung или с iPhone) через сеть 4G, мое SSH-соединение зависает через несколько минут (не более 3), если я не работаю над сеансом SSH (в принципе, SSH-соединение прошло идеально). Поэтому мне приходится постоянно нажимать клавишу со стрелкой, чтобы поддерживать его в рабочем состоянии.

Утверждение проблемы 2 (которое не является проблемой)

Но когда мой Mac подключен к широкополосному Wi-Fi-соединению, эта проблема никогда не возникает. Мое SSH-соединение остается подключенным в течение нескольких часов, даже после того, как я вывожу свой Mac из спящего режима (открываю крышку).

Сегодня, снова погуглив, я нашел различные статьи, в которых предлагается решение с использованием таких опций, как TCPKeepAliveили ServerAliveInterval:

  1. Что именно делают параметры `ServerAliveInterval` и `ClientAliveInterval` в sshd_config?
  2. Как работает tcp-keepalive в ssh?
  3. https://raspberrypi.stackexchange.com/questions/8311/ssh-connection-timeout-when-connecting
  4. https://patrickmn.com/aside/how-to-keep-alive-ssh-sessions/

Но я не смог найти ни одного поста, который бы указывал на эту проблему. Есть ли у кого-нибудь из вас какие-либо идеи по поводу этого поведения? Я буду рад предоставить вам любые возможные подробности моего подключения к точке доступа 4G.

решение1

Я бы предположил, что причиной этого является отслеживание (и забывание) системой соединений с сохранением состояния. Когда используется NAT (а это очень часто бывает, когда не используется IPv6), то обычно системе, выполняющей NAT, нужна память, чтобы помнить, куда отправлять ответы. Для вашего широкополосного Wi-Fi система, выполняющая NAT, может иметь более длинную память, чтобы помнить активные соединения (например, Linuxсетевой фильтр'sconntrackпо умолчанию запоминает TCP-соединения в течение 5 дней, а UDP-потоки — в течение 2 или 3 минут. Эквивалентная система, выполняющая NAT на вашем 4G-маршруте, вероятно, имеет более короткую память, чуть меньше 3 млн.

Чтобы обойти это, как вы обнаружили и указали в своем вопросе, вы можете установить определенный параметр sshServerAliveInterval который будет периодически отправлять пустые данные (как протокол SSH), когда нет активности, аналогичноTCP KeepAlive. Это сделает соединение всегда видимым как активное для системы, выполняющей NAT, и она не забудет его. Так что в вашем ~/.ssh/configфайле вы можете добавить:

ServerAliveInterval 115

со значением 115, выбранным немного меньше 2 мин, чтобы оставаться консервативным: значение ниже предполагаемой продолжительности отслеживания активных соединений на невидимом устройстве NAT в пути, но и не слишком низкое (см. далее). Так что в худшем случае, когда состояние отслеживания находится в 5 с от того, чтобы быть удаленным, оно возвращается к предполагаемому сроку службы в 120 с.

Недостаток в том, что (по крайней мере, на вашем широкополосном Wi-Fi-доступе) если вы потеряете соединение на некоторое время, а затем восстановите его, это может заставить клиента подумать, что удаленный сервер упал, и он закроет соединение. Вы также можете настроитьServerAliveCountMaxдля этого, но в любом случае, если значение по умолчанию равно 3, это потребует около 3*115=345 секунд потери соединения, более 5 минут, прежде чем возникнет вероятность возникновения этой проблемы.

На стороне сервера есть эквивалентClientAliveIntervalчто вы можете установить его в sshd_configфайле вместо этого, для той же цели. Это имело бы дополнительное преимущество, поскольку не сохраняло бы призрачные клиентские соединения ssh, которые бы рассматривались как все еще подключенные в течение некоторого времени, когда клиентская сторона в любом случае теряла соединение.

Связанный контент