VPN на Mac сам переподключается сразу после нажатия «Отключить»
Монитор, который считает любое отключённое состояние сбоем, будет воевать с кнопкой «Отключить». Отделите намерение от наблюдаемого состояния и затем ограничьте повторы.
Нажатие «Отключить» срабатывает, и через десять секунд туннель всё равно возвращается. Этот цикл редко бывает неправильным поведением VPN-клиента; это скрипт восстановления, который всегда задавал только один вопрос, «он упал?», и отвечал на него подключением. Как только вы отделите вопрос, на который ответил пользователь, от вопроса, о котором сообщает система, исправление станет небольшим объёмом состояния вместо более долгого ожидания.
Два вопроса, а не один
Должен ли этот профиль быть подключён прямо сейчас, и что система сообщает в этот момент? Это разные вопросы с разными владельцами, и политике восстановления нужны оба, прежде чем действовать. Намерение — это то, что решает и запоминает ваш инструмент. Наблюдаемое состояние — это то, что сообщает платформа.
| Intent | What you observe | What to do |
|---|---|---|
| Wanted | Dropped unexpectedly | Allow one supported recovery attempt |
| Paused by the user | Disconnected | Do nothing until intent changes |
| Wanted | Already connecting | Wait instead of starting a rival attempt |
| Wanted | Authentication needs a person | Prompt, then stop replaying credentials |
Читайте строки как политику, а не как список случаев. Вторая строка — та, которую большинство скриптов упускают, и это единственная строка, отличающая монитор от машины, которая настаивает на своей правоте.
Наблюдаемое состояние — не предпочтение
Модель состояний Network Extension от Apple сообщает о состояниях connecting, connected, disconnecting, disconnected и recovery. Все пять описывают соединение. Ни одно из них не говорит «пользователь попросил, чтобы этот профиль оставался на паузе», потому что это вообще не состояние соединения. Клиенты, построенные не на этом фреймворке, предоставляют свои поддерживаемые элементы управления и вызовы состояния, и они проводят ту же границу на своём словаре.
Следствие в том, что отключённое состояние никогда нельзя толковать само по себе. Оно означает одно из как минимум трёх: туннель упал, пользователь остановил его или система находится между попытками. Только ваша собственная запись намерения может их различить. Запишите эту запись, сохраняйте её между перезапусками, если она должна пережить перезапуск, и обновляйте её в тот момент, когда действует пользователь, а не выводите позже из строки журнала.
scutil --nc list
scutil --nc status "Office VPN"
Кто ещё имеет право запускать этот профиль
Пауза, обещанная вашим помощником, сильна ровно настолько, насколько сильны другие владельцы того же профиля. Правило On Demand, управляемая конфигурация или второй клиент могут запросить соединение, и ваш помощник будет выглядеть сломанным, хотя ведёт себя точно так, как написано.
Найдите каждый механизм, который может запустить профиль прежде чем обещать уважать паузу, и запишите, какой из них побеждает. Когда управляемая служба намеренно не даёт личную опцию паузы, это решение администратора о политике, а не пробел, который скрипт должен заполнить, борясь с управлением.
Сделайте повторы скучными
Ограничьте число попыток и сделайте каждую чувствительной к чему-то изменившемуся: сеть вернулась, шлюз ответил, запрос учётных данных завершился. Недоступный шлюз, истёкшая идентичность и отклонённый второй фактор требуют трёх разных реакций, а плотный цикл даёт всем трём одну и ту же.
Посмотрите, что быстрый повтор на самом деле создаёт на экране. Повторяющиеся диалоги, которые пользователь закрывает, хуже одного ясного сообщения об ошибке, и они приучают людей пролистывать запросы, не читая их.
Пауза и политика трафика — разные обещания
Туннель, поставленный пользователем на паузу, часто намеренно оставляет трафик заблокированным, и в этом весь смысл политики в стиле kill switch. Это значит, что «Пауза» должна обещать ровно одно: восстановление останавливается. Она не должна тихо менять то, что разрешает сеть.
Решите поведение трафика отдельно, задокументируйте его рядом с элементом управления «Пауза» и сохраняйте согласованность независимо от того, стоит ли туннель на паузе, отказал или отсутствует. Иначе пользователь узнаёт, что нажатие «Отключить» делает что-то непредсказуемое, и следующий запрос в поддержку будет о сети, которая «иногда перестаёт работать» без видимой причины.