Один только хук сна не вернёт VPN
Хук, который завершается с нулём, доказывает лишь то, что скрипт запустился. Поставьте его после сети, используйте правильную идентичность и проверьте, подходит ли профиль вообще.
Поместите команду переподключения в хук сна — и проблема кажется решённой. Она решена только если хук запускается после появления сети, от имени идентичности, которую клиент распознаёт, по пути, который клиент действительно реализует. Большинство сбоев после пробуждения — один из этих трёх, и ни один не проявляется как ошибка в самом хуке. Хук в любом случае возвращает успех.
Скрипт, который завершается с нулём, ничего не сказал о том, вернулся ли туннель.
Хук запускается, и что дальше?
#!/bin/sh
case "$1" in
pre)
vpn-client disconnect
;;
post)
vpn-client connect
;;
esac
Каждое событие вызывает хук дважды, до и после перехода, передавая ему фазу и имя события. Он работает как root в минимальном окружении, поэтому нужны абсолютные пути и не стоит ожидать никакой переменной сеанса рабочего стола. То, что оба вызова быстро возвращаются, говорит лишь о том, что скрипт запустился. Поднялся ли профиль после этого — отдельное наблюдение, и ему нужны собственные доказательства в журнале.
Рассматривайте аргумент фазы как часть замысла. Попытка переподключения в фазе pre происходит, когда машина вот-вот потеряет всё, и она не может удаться.
Root, минимальное окружение, не тот пользователь
Если клиент хранит токен входа для каждого пользователя, запуск хука от root оставляет ему нечего предъявить. Проверяйте состояние под той идентичностью, которую хук действительно использует, а не под той, которую вы тестировали из терминала рабочего стола. Некоторые сборки после отключения оставляют демон, удерживающий интерфейс, поэтому переподключение попадает в устаревшее состояние, а очистка процесса сначала восстанавливает его ценой нечистого завершения. Ни одно из двух поведений не видно, если проверять только счастливый путь.
Пишите хук с абсолютными путями, держите его во владении root и исполняемым, и записывайте, что он сделал. Без этого журнала следующее расследование начнётся с нуля.
Автоподключение — не путь VPN
NetworkManager предлагает два механизма активации: флаг автоподключения в профиле и вторичные подключения, которые запускаются при активации основного профиля. Родные типы устройств реализуют первый; плагины VPN исторически реализовывали только второй, поэтому отметка автоподключения в профиле OpenVPN может вообще не дать эффекта. Проверьте оба свойства, а затем подключите VPN как вторичное к профилю Wi-Fi или Ethernet.
[Unit] PartOf=NetworkManager.service Requires=NetworkManager-wait-online.service After=NetworkManager-wait-online.service
Интерфейсу WireGuard, управляемому юнитом systemd, нужен именно этот дополнительный файл, а не хук, упорядоченный после того, как сеть окажется онлайн.
Дождитесь сети, но с потолком
timer=1 while ! ping -c1 -n -w1 203.0.113.1 >/dev/null; do sleep 1; timer=$((timer+1)) [ $timer -ge 300 ] && exit 0 done nmcli connection up "work-vpn"
При пробуждении туннель могут запросить, пока Wi-Fi ещё переподключается, что превращает любой фиксированный сон в догадку. Дождитесь доступного адреса, затем поднимите профиль, и ограничьте ожидание, чтобы хук не мог держать путь пробуждения открытым бесконечно. Предпочитайте имя профиля числовому индексу, и если правильный профиль зависит от сети, пусть здоровый туннель заранее запишет свой выбор в файл.
Берегитесь и штормов перезапуска: считайте попытки и останавливайтесь. Сторож, реагирующий на каждую неудачную проверку, превращает один сбой в цикл.
Приостановите систему один раз, затем прочитайте в журнале собственный вывод хука. Это единственный тест, доказывающий порядок.