Ваш VPN работает только после входа из-за связки ключей
Работающий профиль в вашей сессии — не служба при загрузке. Посмотрите, какой владелец запускает туннель, где живёт секрет и как проверить настоящее событие.
Команда работает, пока вы вошли в систему, поэтому вы кладёте её в скрипт автозапуска и идёте домой. На следующее утро машина в сети, а туннель — нет. Миф в том, что работающий вызов — это работающая служба. На практике разница обычно в одном из двух: профиль принадлежит вашей пользовательской сессии, а не системе, либо секрет разблокируется чем-то, что существует только после вашего входа. И то и другое прекрасно работает при ручной проверке и отказывает ровно в тот момент, когда никто не смотрит.
Почему вход заставляет это работать
Графический вход запускает шину сессии и агент службы секретов, и именно там многие клиенты, ориентированные на рабочий стол, хранят пароль профиля или парольную фразу закрытого ключа. Активация, работающая как ваш пользователь после входа, может запросить секрет у этого агента и добиться успеха. У той же активации, выполняемой юнитом при загрузке, нет сессии, шины и агента, поэтому поиск отказывает или блокируется на запросе, которого никто не видит.
Запустите тот же профиль до и после входа — и получите два разных результата из одной конфигурации. Это признак зависимости от учётных данных, а не сломанного туннеля, и он объясняет, почему ручная проверка в терминале доказывает меньше, чем кажется. Туннель в порядке; отсутствует то, что разблокирует его секрет.
Решите, какой владелец запускает туннель
Есть два поддерживаемых шаблона, и их смешивание — другой способ, которым это ломается. NetworkManager может активировать подключение системного уровня, что уместно, когда машина уже централизует сеть там. Либо отдельный юнит systemd запускает VPN напрямую и сам владеет интерфейсом.
systemctl list-unit-files 'openvpn*'
systemctl list-unit-files 'wg-quick*'
nmcli connection show --active
systemctl enable --now wg-quick@wg0
Не запускайте обоих владельцев на одной конфигурации. Если NetworkManager управляет интерфейсом, а юнит тоже поднимает его, они будут бороться за маршруты и DNS, и итоговое состояние зависит от того, кто завершил последним.
Положите секрет туда, где служба сможет его прочитать
Фоновая служба не может ответить на запрос. Парольные фразы сертификатов, пароли учётных записей и указанные файлы аутентификации — всем им нужен такой порядок хранения, до которого юнит доберётся без человека, который принадлежит учётной записи, запускающей службу, и нечитаем для всех остальных.
Соблазнительный короткий путь — сделать файл читаемым для всех, пока не исчезнет ошибка прав. Это меняет отказ при загрузке на долговременную утечку учётных данных, и это тот вид изменения, к которому никто не возвращается. Используйте механизм, которому развёртывание уже доверяет: ограниченный файл учётных данных, незашифрованный ключ, защищённый правами файла, или подключение системного уровня с собственным хранилищем секретов.
Проверьте событие, которое действительно происходит
Запуск службы вручную после входа почти ничего не проверяет. Перезагрузитесь или отключите графический вход на один цикл и посмотрите, как юнит поднимается сам. Это единственная проверка, которая одновременно упражняет доступность учётных данных, готовность сети и порядок юнитов. Это также проверка, которая воспроизводит сбой, о котором сообщил пользователь, чего ручной запуск никогда не делает.
systemctl is-enabled wg-quick@wg0
journalctl -u wg-quick@wg0 -b --no-pager
systemctl status systemd-networkd-wait-online --no-pager
Порядок важен не меньше учётных данных. Юнит, который стартует раньше, чем настроено основное восходящее подключение, сдастся, а некоторые дистрибутивы различаются тем, ждут ли они связности. Если юнит сообщает об отказе при загрузке, но успешно запускается вручную через тридцать секунд, вы нашли проблему порядка, а не проблему секрета.
Проверяйте маршруты и DNS, а не только интерфейс
Существующий интерфейс — не работающий туннель. После неохраняемого запуска проверьте маршруты, состояние резолвера и один адрес назначения, прежде чем проверять имя. Затем проверьте приложение, для которого существует туннель.
ip -4 route show
resolvectl status
ping -c 3 10.61.0.1
curl -sS --max-time 5 https://internal.example/ -o /dev/null -w '%{http_code}\n'
Если адрес работает, а имя нет, оставшаяся проблема — политика DNS, а не туннель. Запишите, какой владелец запускает службу и где живёт секрет, потому что следующему человеку, который перезагрузит эту машину, понадобятся оба факта.