Небольшой программе, которая подключает существующий VPN, нужен контроллер, а не новая реализация VPN. Поддерживаемый движок должен заниматься согласованием и трафиком туннеля; ваша программа должна выражать запрос пользователя и честно объяснять результат. В Linux интерфейс NetworkManager D-Bus даёт такому контроллеру конкретную модель, которой можно следовать.

Четыре проверки не дают контроллеру перепутать сохранённый профиль, запрос на активацию и работающий сеанс.

Проверка первая: какая сущность выбирается

Держите UUID профиля как постоянную сущность и разрешайте его через менеджер, когда нужен путь к объекту. Отображаемое имя могут разделять два профиля, а путь шины во время выполнения — не разумная пользовательская настройка для хранения. Запишите выбор в свою конфигурацию, а не в комментарий о том, какая запись была второй в списке.

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

Проверка вторая: что возвращает вызов активации

Документированный вызов активации принимает путь к объекту существующего соединения, путь к устройству и конкретный объект. Он возвращает путь активного соединения, и этот ответ — дескриптор, а не результат готовности. Не выставляйте флаг готовности приложения из возвращённого значения; подпишитесь вместо этого на состояние и причину активного соединения.

Для VPN конкретный объект выбирает активное базовое соединение. Передача корневого пути оставляет выбор устройства NetworkManager, который берёт то, что сейчас по умолчанию. Это решение о контексте маршрутизации, а не поле пароля, и оно меняет, на каком устройстве лежит туннель.

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

Проверка третья: как представляется состояние

Активное соединение проходит через активацию, активно, деактивацию и деактивировано, а поле причины говорит почему. Сжатие всего этого в логическое значение с именем loggedIn теряет сведения, нужные пользователю и те, которые запросит поддержка. Показывайте хотя бы, ожидает ли соединение, установлено или исчезло, и сохраняйте строку причины для случая сбоя.

Связывайте асинхронные ответы с запросом, который их породил. Позднее завершение старой попытки не должно перезаписывать более новое действие пользователя, а повторное нажатие Connect следует либо игнорировать, либо трактовать как отмену и повтор с видимой политикой.

Проверка четвёртая: что происходит после перезапуска

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

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

Держите полномочия и секреты у их владельцев

Разрешения возвращаются как да, auth или нет, и интерфейс должен отражать разницу между разрешено, разрешено после аутентификации и отказано. Запуск контроллера от root не реализует политику разрешений; он убирает вопрос.

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

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

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