Привязка зависимой службы к tun0.device выглядит как подписка на туннель, но это не так. Юнит устройства отражает существование интерфейса, и это может оставаться верным при неудачном соединении и последующем переподключении. Тогда служба действует не в тот момент или не действует вовсе, в зависимости от того, исчезал ли интерфейс между ними. Хук, описывающий событие, которое вам действительно важно, — это тот, который вызывает OpenVPN, а не тот, который выводит systemd.

Решите, какое условие нужно службе, прежде чем выбирать триггер, потому что три кандидата не взаимозаменяемы.

Что на самом деле отслеживает юнит устройства

systemd создаёт юнит устройства на основе представления ядра о сетевом интерфейсе, поэтому tun0.device становится активным, когда интерфейс появляется, и неактивным, когда его удаляют. С persist-tun мягкий перезапуск сохраняет интерфейс на месте, так что юнит никогда не мерцает и ничего привязанного к нему не запускается. Даже без сохранения состояния юнит ничего не говорит о маршрутах, DNS или о том, отвечает ли удалённая сторона.

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

up, route-up и up-restart означают разные вещи

up выполняется после открытия устройства TUN/TAP и настройки интерфейса — это правильный момент для слушателя, привязывающего назначенный адрес. route-up выполняется после установки маршрутов, с учётом любой настроенной задержки маршрута, и подходит для работы, требующей завершённого этапа маршрутов. Ни то, ни другое не доказывает, что удалённое приложение отвечает. Выбор между ними — вопрос о том, что нужно службе, а не о том, какой хук звучит более законченным.

С persist-tun перезапуски повторно используют устройство, поэтому up не выполняется снова, если не задан up-restart. Эта опция включает up-скрипт для документированного жизненного цикла перезапуска, а его окружение урезано по сравнению с первым запуском. Скрипт, рассчитывающий на полное окружение, работает при первом подключении и падает при следующем.

Отправьте действие, не дожидаясь его

Хук, синхронно вызывающий systemctl restart, может войти в клинч с юнитом, порядок которого ждёт туннель. systemctl --no-block try-restart vpn-dependent.service ставит задачу в очередь и возвращается, что не даёт хуку заблокировать соединение, на которое он реагировал. try-restart действует только на работающий юнит, тогда как restart запускает и неактивный; выбирайте осознанно, а не по привычке.

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

Политика перезапуска живёт в юните, а не в хуке

Юнит oneshot с RemainAfterExit=yes остаётся активным после завершения команды, а второй запрос запуска ничего не делает, потому что systemd считает его уже запущенным. Это свойство, вокруг которого проектируют, а не дефект, который обходят повторными вызовами запуска. Если действие должно выполняться на каждое соединение, юниту нужна форма, которая это позволяет.

After= упорядочивает юниты, а BindsTo= связывает время жизни, но ни то, ни другое не означает «перезапускай это при каждом переподключении VPN». Юнит, привязанный к туннелю, останавливается, когда останавливается туннель; он не перезапускает себя, когда туннель возвращается, если только что-то не запустит его снова.

Проверьте три переподключения, а не одно

Холодная загрузка, полный перезапуск клиента и мягкое переподключение отрабатывают каждый свой путь. Мягкое переподключение — это то, которое выявляет отсутствующий up-restart, урезанное окружение или юнит устройства, который так и не стал неактивным. Запустите все три и подтвердите оба направления: служба действует, когда туннель поднимается, и не перезапускается при несвязанных изменениях канала, таких как роуминг Wi-Fi.

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

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