Как долго OpenConnect должен повторять попытки подключения к оборванному VPN?
Тайм-аут переподключения OpenConnect ограничивает повторные попытки после потери канала или после мёртвого партнёра. Это не надзор за процессом, не обновление учётных данных и не блокировка трафика.
--reconnect-timeout отвечает на один узкий вопрос: после падения туннеля сколько времени этот клиентский процесс продолжает пытаться, прежде чем сдаться и завершиться. Страница руководства OpenConnect фиксирует этот параметр с документированным значением по умолчанию 300 секунд для повторных попыток после потерянного канала или партнёра, переставшего отвечать, и число это срок для одного работающего клиента, а не доказательство того, что VPN остаётся доступным. Это и не политика поддержания процесса живым, и именно отсюда начинается большая часть путаницы.
Путаница растёт, когда сверху сидит второй механизм. Супервизор, перезапускающий клиента, проверяльщик, пингующий шлюз, и встроенное окно повторных попыток могут все реагировать на один сбой, и тогда инцидент даёт три временные шкалы, которые никто не может согласовать.
Что на самом деле ограничивает окно переподключения
Представьте, что сеть доступа исчезает на несколько секунд. Клиент видит обрыв канала или перестаёт слышать ответы мёртвого партнёра и начинает заново устанавливать сессию, удерживая столько состояния, сколько может. Попытки продолжаются, пока шлюз снова не примет или пока окно не исчерпается, а исчерпанное окно заканчивается выходом с ненулевым кодом. Именно этот выход, а не значение тайм-аута, — место, где владение жизненным циклом переходит к тому, кто наблюдает за процессом.
Окно ничего не говорит о том, как часто запускается проверка, и не может продлить аутентификацию. Если шлюз отозвал сессию или учётная запись теперь требует новый второй фактор, более долгое ожидание не сделает старую сессию снова действительной. Повторная попытка удаётся только тогда, когда путь возвращается, шлюз по-прежнему узнаёт сессию и запрошенные учётные данные остаются пригодными, поэтому читайте это число как срок, а не как интервал живучести.
Окно также не регулирует, что делают приложения, пока оно идёт. В зависимости от платформы и от того, насколько далеко зашёл сбой, клиент может переподключаться, когда маршруты ещё установлены, или после того, как их убрали. Поэтому запрос, выданный посреди перерыва, обычно висит до истечения тайм-аута вместо быстрого отказа.
Перезапуски супервизора и повторные попытки клиента — два слоя
Пусть работающий клиент потратит своё окно, а менеджер служб отреагирует на выход. Клиент на переднем плане под systemd с политикой перезапуска даёт именно такое разделение: попытки в течение ограниченного периода, затем одно решение о перезапуске. Результат — одна временная шкала, которую потом всё ещё можно восстановить.
Клиент в фоне плюс независимый опрашивающий, который запускает ещё одну копию, когда не видит интерфейса, — это та схема, которая ломается. Тогда оба процесса борются за один и тот же узел устройства, маршруты и настройки резолвера. Если вам действительно нужен демон, поставьте параметр в ту командную строку, с которой клиент действительно запускается:
sudo openconnect --background --pid-file=/run/openconnect/vpn.pid \
--reconnect-timeout=180 \
--user=<account> https://vpn.example.eduДве детали в этой строке имеют вес. --background отсоединяет процесс, поэтому файл pid становится единственной надёжной ручкой на него, а тайм-аут расходуется только пока этот же процесс жив; супервизор, который его убьёт, не оставляет бюджета на продолжение.
Намеренные отключения нуждаются в собственном сигнале. Плановая пауза и настоящий сбой выглядят одинаково для наивного наблюдателя, и оба читаются как «не подключено». Управляйте паузой через операцию остановки супервизора или через маркер, который понимает обёртка, чтобы намеренная остановка не вызвала перезапуск, которого никто не просил.
Как не дать передаче обогнать цикл повторных попыток
Автоматическое восстановление зависит от учётных данных, которые обновляются без присутствия человека. Связка ключей, открывающаяся только в интерактивном сеансе рабочего стола, или токен, всегда требующий введённого кода, оставят клиента застрявшим на этапе аутентификации, как только путь вернётся. Уладьте этот рабочий процесс до того, как удлинять окно, потому что более длинное окно лишь даёт тому же заблокированному запросу больше времени на неудачу.
Проверку сервера не следует ослаблять ради уменьшения запросов. Именно закрепление или якорь доверия, проверяющий шлюз, делает автоматическое переподключение безопасным, а его отключение ради избегания вопроса о сертификате меняет видимый перерыв на невидимый. Сохраняйте проверенную личность и вместо этого чините запрос; клиент, готовый подключаться к любому шлюзу, хуже того, который останавливается и ждёт.
Наличие интерфейса тоже не сигнал здоровья. Туннельное устройство может существовать с мёртвой сессией позади, а процесс запуска может существовать вообще без туннеля. Ни одно из этих наблюдений не выдерживает реального запроса. Здоровье должно исходить из того, что нужно пользователю, например из запроса, проходящего через туннель к известной внутренней службе.
Что проверять во время и после перерыва
Проведите четыре события как отдельные тесты: перерыв короче окна, сбой длиннее него, ошибку аутентификации и намеренную остановку. Каждое должно заканчиваться в разном, предсказуемом состоянии, и граница между первыми двумя — это вся причина выбора значения.
Держите проверки обращёнными наружу, потому что таблица процессов сама по себе доказывает очень мало. Следите, остаётся ли pid стабильным во время короткого обрыва, затем подтвердите, что после длинного он исчез и был заменён один раз:
curl -sS --max-time 5 -o /dev/null -w '%{http_code}\n' https://intranet.example.internal/health
cat /run/openconnect/vpn.pid
ps -o pid,etime,cmd -p "$(cat /run/openconnect/vpn.pid)"Во время короткого перерыва подтвердите, что клиент действительно повторил попытку, а не вышел раньше, и что маршруты и записи резолвера вернулись без дубликатов. Для более длинного сбоя подтвердите чистый выход и ровно один перезапуск после него. Для ошибки аутентификации подтвердите, что клиент не крутится против шлюза, который продолжит его отклонять. Добавьте проверку, что pid возвращается к одному значению, а не накапливается.
Для намеренной остановки URL здоровья должен оставаться недоступным, а процесс — остановленным. Затем замкните цикл со стороны приложения: тот же запрос должен терпеть неудачу, пока туннеля нет, и должен успешно проходить после его возвращения, с адреса источника, которого ожидает ваша политика. Зелёный значок туннеля не доказательство, а выполненный запрос — доказательство.