Більшість порад про те, як утримати SSH-сеанс живим, зупиняються на «додайте ServerAliveInterval 30» і пропускають корисні деталі. Ключове слово — таймер на боці клієнта, який спрацьовує лише коли канал мовчить, він рахує невідповіджені проби, а не секунди, і живе у файлі, де перемагає перше знайдене значення. Помиліться в цих трьох властивостях, і здоровий VPN-сеанс усе одно обірветься, а мертвий висітиме.

Два напрямки належать різним демонам

ServerAliveInterval читає ваш клієнт ssh. ClientAliveInterval читає sshd на дальньому боці й опитує у зворотному напрямку, від сервера до клієнта. Це не синоніми, і вони не взаємодіють, тому налаштування одного не впливає на поведінку іншого боку. Їхнє плутання — звичайна причина того, що виправлення начебто працює на одному хості й не працює на наступному.

Обидва приймають нуль. При нулі клієнт не надсилає взагалі нічого, а на боці сервера ClientAliveCountMax, що дорівнює нулю, вимикає розрив, який інакше настав би після невідповіджених перевірок.

Що доводить проба, а що ні

Після того як заданий інтервал минув без даних від сервера, клієнт надсилає невеликий запит наявним зашифрованим каналом і чекає на відповідь. ServerAliveCountMax визначає, скільки з них можуть залишитися без відповіді, перш ніж сеанс буде розірвано. При інтервалі 60 і числі 3 клієнт здається приблизно після трьох хвилин тиші, і ця цифра — властивість вашої конфігурації, а не мережевий стандарт. Залиште інтервал на типовому значенні 0, і проба не надсилатиметься ніколи, тому стандартний клієнт може нескінченно сидіти на мертвому з'єднанні.

Оскільки обмін відбувається всередині транспорту SSH, відповідь доводить, що процес SSH на тому боці все ще читає й пише. Про програму, яку ви запустили в цьому сеансі, вона не говорить нічого: клієнт бази даних, перенаправлений порт або довгостроковий скрипт можуть зависнути, поки транспорт бадьоро відповідає на проби.

TCPKeepAlive — окремий механізм на рівень нижче. Ним опікується ядро, він не шифрується, і сторона, у якої завис демон SSH, усе одно може його задовольнити. Тому проба на рівні SSH — більш значущий сигнал, коли вам важливий сеанс, а не сокет.

Порядок вирішує, яке значення виживе

OpenSSH застосовує перше отримане значення для кожного параметра, тому конкретний блок Host має стояти перед будь-яким ширшим блоком, який теж підійшов би. Ставте типові значення з підстановчими символами в кінці файлу, а не на початку, і пам'ятайте, що блок Match нижче не може скасувати вже задане значення. Довідник з конфігурації клієнта OpenSSH прямо формулює правило першого значення, і його варто прочитати один раз перед перебудовою спільної конфігурації.

Параметри командного рядка перемагають файл, що робить тимчасовий експеримент дешевим:

ssh -o ServerAliveInterval=15 -o ServerAliveCountMax=4 office-shell

Щоб побачити, що клієнт насправді вирішив, а не те, що ви думаєте, що написали, попросіть його вивести чинну конфігурацію. У виводі є об'єднані значення для цього імені хоста, і це найшвидший спосіб упіймати заблукалий попередній блок:

ssh -G office-shell | grep -i alive

Що роблять keepalive через тунель

Періодичний трафік не дає прив'язці NAT або міжмережевого екрана зі станом спливти, що є справжньою перевагою для VPN, чий шлюз скидає простої потоки через кілька хвилин. Проби, що надходять кожні 60 секунд, оновлюють цю прив'язку, не несучи жодних прикладних даних.

Вони не можуть відбудувати шлях, який зник. Коли інтерфейс тунелю зникає, проби зазнають невдачі, як і все інше, і сеанс завершується, щойно лічильник вичерпано. Виявлення живості та відновлення шляху — різні задачі, і лише перша налаштовується в ssh_config. Те, що інтервал і лічильник справді дають, — це швидкість, з якою клієнт помічає, і саме це користувач відчуває як зависання.

Мультиплексовані з'єднання додають складку. Коли задіяний ControlMaster, проби належать головному з'єднанню, і новий сеанс через наявне головне успадковує те, про що те головне домовилося. Якщо головне mux зависло, відкриття іншого вікна не перевірить шлях знову.

Підтвердження налаштування від початку до кінця

На сервері виведіть чинну конфігурацію демона, а не читайте файл і не вгадуйте, який include переміг:

sshd -T | grep -i clientalive

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

Варто додати дві перевірки для будь-якого хоста, до якого ви дістаєтеся лише через тунель: переконайтеся, що розв'язаний інтервал — саме той, який ви задумали, і що цей інтервал, помножений на лічильник, коротший за тайм-аут простою на шлюзі VPN. Коли друге число більше, шлюз спершу мовчки скидає потік, і проба SSH так і не отримує шансу щось повідомити.

Схожі статті