БлогРазбор

«Отключить» отказал шесть раз за ночь

Кнопка выхода сама стала ловушкой. Разбор одной ночи с UPN: что сломалось, что поменял, какую цену за это плачу и что ещё не проверено.

Большая чёрная кнопка на стальном корпусе, туго обмотанная цепью с замком. На тёмном фоне по кнопке скользит оранжевый свет.
Содержание
  1. Как шла ночь
  2. Причина: две записи и сброс между ними
  3. Что поменял
  4. Цена решения
  5. Как проверял и что ещё не проверено
  6. Что вынес

С 01:56 до 02:08 я шесть раз нажал «Отключить» в собственной программе. Все шесть раз она отказала, а компьютер остался без сети. Перезагрузка не помогла. Сеть вернулась только в десять утра, после спасательного скрипта.

UPN это мой личный VPN для Windows. Когда связь рвётся, он держит запрет на уровне системы: программы сидят без сети, зато ничего не выходит мимо туннеля. Для этого он и нужен. Плохо то, что в ту ночь этот запрет оказалось нечем снять.

Как шла ночь

Время Что произошло
01:52–⁠01:54 Две аварийные перезагрузки подряд. Сессия в этот момент переподключалась под запретом
01:54–⁠01:56 Все попытки восстановления падают с одной ошибкой
01:56–⁠02:08 Шесть нажатий «Отключить», шесть отказов, сети нет
06:12–⁠10:01 Ещё пять аварийных перезагрузок. Приложение поднимает ту же сессию каждые 3,5 минуты: 21 попытка, все с той же ошибкой
10:00–⁠10:05 Спасательный fix-network.bat: служба отключена, сброс брандмауэра, winsock и TCP/IP, перезагрузка
15:51 Установлено исправление

Всего за день случилось 12 аварийных перезагрузок: шла отладка железа. UPN их не вызывал, но именно они вскрыли дефекты.

Причина: две записи и сброс между ними

Запрет лежит в Windows Filtering Platform, а что именно поставлено, программа записывает в файл состояния. Это два разных хранилища, и атомарно их не связать:

Текст
1. коммит транзакции WFP     фильтры уже стоят в Windows
2. запись state.json         файл узнаёт о них только здесь

Жёсткий сброс пришёлся между этими шагами. В Windows остались фильтры, которых не называла ни одна запись в файле. А кнопка «Отключить» снимала запрет, только если он в точности совпадал с записанной политикой, поэтому отвечала так:

Текст
failedProtectionRetained / differentGlobalPolicyActive

Правило «чужое не трогаю» звучало разумно, пока чужим не оказалось своё. Отказывали все команды: отключение, подключение, перезапуск и замена. Выхода не было.

Рядом нашлись ещё четыре дефекта, и каждый добавил к ночи по-своему:

  • Запрет переживал перезагрузку. Фильтры были постоянными, Windows загружалась уже без сети, и интернет зависел от удачного восстановления. Для него нужны Wi‑Fi, DHCP под запретом и точная запись политики. Сломалось любое из трёх, и компьютер оставался без сети.
  • Восстановление повторялось без конца. Сессию, найденную при старте, приложение считало защищённой и перезапускало каждые 3,5 минуты.
  • Отказа приложение не понимало. Такой статус в ответе не распознавался, и каждое нажатие висело 3 минуты до тайм-аута.
  • Отключённая служба ломала и подключение. Старые фильтры при этом лежат в Windows спящими: включи службу без чистки, и запрет вернётся.

Что поменял

«Отключить» больше не отказывает. Новая команда purge удаляет все фильтры своего подуровня, какой бы политикой они ни были поставлены, и отключённые тоже. Ей не нужны ни политика, ни адаптер, ни служба. Процесс сессии, который за 35 секунд не остановился сам, завершается. Если какой-то шаг уборки не удался, снятие всё равно идёт до конца, а приложение называет этот шаг текстом.

Запрет живёт до перезагрузки, не дольше. Фильтры теперь статические. Падение движка или координатора их не снимает, перезагрузка снимает, в том числе аварийная.

При входе в Windows прошлая сессия закрывается. Раньше она восстанавливалась и держала компьютер в заложниках. Потом идёт обычное подключение. Не вышло, значит сеть остаётся обычной, а приложение показывает ошибку.

Отказ виден сразу. Если закрыть сессию не удалось, приложение не подключается и называет выход: файл Stop-UPN-System.cmd или перезагрузка.

Цена решения

Во время работы всё осталось как было: обрыв и смена маршрута идут под запретом, и он держится до «Отключить» или до перезагрузки.

Как проверял и что ещё не проверено

  • 13тестов системного модуля
  • 172теста координатора и движка
  • 30групп проверок приложения без окна

Самое полезное здесь не количество. Новые тесты сценария той ночи падают на прежнем координаторе и проходят на новом, то есть проверяют именно этот дефект.

Установка в 15:51 прошла: чистка сработала, ночная сессия закрылась, сеть работает. А вот первая живая попытка подключиться в 16:06 отказала через 5 секунд, на проверке службы, ещё до постановки запрета. Сеть при этом не менялась. Вероятная причина в том, что второй компонент защиты получил от Windows флаг DISABLED, пока служба была отключена, и следующая перезагрузка должна его снять. Это вывод из кода, наблюдать его я не наблюдал.

Вживую пока не проверены:

  • подключение и «Отключить» новым координатором;
  • «Отключить» из по-настоящему зависшей сессии;
  • загрузка Windows при подключённом UPN;
  • сколько спящих фильтров удалила чистка: установщик хранит только статус.

Что вынес

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

Умар Турсунов

Нейрокреатор

Собираю с нейросетями приложения, сайты, программы, ботов и драйверы. От идеи до работающего продукта.

Обсудить задачуОбо мне

UPN

Программа для Windows, личный инструмент

При обрыве связь встаёт на паузу

Личный VPN на своих серверах: весь компьютер идёт через туннель, а при обрыве связь встаёт на паузу.

  • Windows
  • Свои серверы
  • Весь компьютер
  • 17–18 сна переподключение
  • ~20 савтопереход при сбое
  • 172теста координатора

Похожие по темам