Сервер перезагружается, OpenVPN запускается, а RRAS поднимается, пока адаптер или маршрут, от которых он зависит, ещё отсутствуют. Ручной перезапуск RRAS через минуту это исправляет, из-за чего проблема выглядит решённой, а настоящая скрывается. Здесь смешиваются два разных условия: предварительная служба работает, и сетевой ресурс, который RRAS действительно нужен, стал доступен. Зависимость службы Windows может выразить первое условие и никогда второе, поэтому добавление зависимости без определения ресурса даёт более аккуратную на вид загрузку и ту же ошибку.

Как выглядит симптом при холодной загрузке

Признак — разница между холодным запуском и перезапуском. При холодном запуске RRAS сообщает, что работает, хотя адаптер туннеля отсутствует, маршрут пропал или адрес партнёра ещё не разрешается. Ручной перезапуск затем удаётся, потому что к этому моменту ресурс существует, а служба просто заново читает мир, которого минуту назад не видела. Журнал службы в обоих случаях покажет чистый запуск, поэтому один только просмотр событий редко это объясняет.

Зафиксируйте оба состояния, прежде чем что-то менять: что RRAS сообщает при загрузке и что существует в момент успешного ручного перезапуска. Если эти два наблюдения идентичны, порядок запуска не является вашим объяснением и зависимость не поможет. Сравнение стоит десять минут и экономит неделю догадок.

Зависимость, добавленная на основании «работает после перезапуска», лишь откладывает ту же ошибку на время, которое нужно предварительной службе, чтобы сообщить RUNNING. Она также усложняет понимание загрузки, потому что ограничение порядка теперь выглядит как объяснение. Спросите, какой объект гарантирует зависимость и является ли этот объект тем, которого RRAS не видел.

Назовите ресурс, а не только службу

Запишите конкретную недостающую вещь. Это может быть адаптер туннеля с адресом, маршрут к подсети партнёра, ответ DNS или сертификат, который ещё выдаётся. «Служба VPN работает» не является описанием ресурса, как и зелёный значок в клиенте. Пока вы не можете назвать объект и команду, которая его показывает, вы не определили условие, которого пытаетесь ждать.

Установите также, как запускается этот экземпляр OpenVPN. Туннель под управлением GUI и туннель под управлением службы имеют разные жизненные циклы загрузки, и имя службы должно браться с машины перед вами, а не из примера, написанного для другого установщика. Перечислите кандидатов, вместо того чтобы доверять запомненному имени.

Get-Service | Where-Object Name -match 'vpn|openvpn' | Select-Object Name, Status, StartType

Прочитайте цепочку зависимостей, прежде чем что-то добавлять

Диспетчер управления службами сообщает состояния, такие как START_PENDING и RUNNING, а SERVICE_STATUS reference точно определяет, что означает каждое поле. Ни одно из этих состояний не обещает, что партнёр, DNS-имя или нижестоящее приложение доступны. Именно этот разрыв — вся причина, по которой ошибка переживает правильно настроенную зависимость.

Get-Service -Name RemoteAccess | Select-Object Status, StartType
sc.exe qc RemoteAccess
Get-Service -Name RemoteAccess | Select-Object -ExpandProperty DependentServices

Строка DEPENDENCIES из sc.exe qc — это список, который нужно сохранить, потому что sc.exe config RemoteAccess depend= заменяет весь список, а не добавляет к нему. Если убрать не связанное предварительное условие при добавлении службы VPN, возникнет вторая неисправность, которая проявится при другой загрузке, и её гораздо труднее диагностировать, чем исходную. Скопируйте существующий список в журнал изменений, прежде чем его трогать.

Зависимости меняют и поведение при выключении, потому что остановка предварительного условия останавливает зависящие от него службы. Проверьте, что происходит при обслуживании, прежде чем подключать RRAS к чему-то, что часто перезапускается.

Привяжите перезапуск к условию, а не к таймеру

Фиксированное ожидание предполагает, что туннель всегда будет готов в этом окне, и именно это допущение не срабатывает при загрузке, когда сертификат медленный или канал недоступен. Проверьте сам ресурс, с крайним сроком, и позвольте проверке решить, нужен ли перезапуск вообще.

Get-NetAdapter | Where-Object Status -eq 'Up'
Get-NetRoute -DestinationPrefix 0.0.0.0/0
Get-WinEvent -LogName System -MaxEvents 40 |
  Where-Object ProviderName -eq 'Service Control Manager'

Запланированная задача при загрузке, которая выполняет эти проверки и перезапускает RRAS только когда адаптер или маршрут всё ещё отсутствуют, ограничена, проверяема и легко удаляется. Альтернатива — перезапускать RRAS при каждом переподключении — прерывает здоровые сеансы и превращает нестабильный канал в цикл перезапусков. Этот цикл хуже исходной неисправности, потому что теперь затрагивает пользователей, у которых всё было хорошо.

Дайте проверке максимальное ожидание, соответствующее времени, которое туннель разумно занимает на вашем оборудовании, и пусть задача завершается с ненулевым статусом, когда сдаётся. Тихая задача, которая просто перестаёт пытаться, неотличима от успешной.

Записывайте переход, чтобы следующая загрузка объясняла себя сама

Запишите три отметки времени в одной строке: когда служба зависимости достигла RUNNING, когда появился нужный ресурс и когда RRAS наконец его принял. Эта единственная строка отвечает на вопрос, который задаст следующий инженер, и её создание почти ничего не стоит. Без неё следующее расследование начинается с тех же догадок, что и это.

Остановите автоматизацию после заданного числа попыток и сообщите об ошибке, вместо того чтобы повторять вечно. Загрузка, которая заканчивается ясным сообщением «ресурс так и не появился», стоит больше, чем та, что продолжает перезапускать службу в темноте. Когда это сообщение появится, имя ресурса, которое вы записали во втором разделе, — это то, что будет искать следующий человек.

Похожие статьи