Импорт в NetworkManager не удаётся для файлов OpenVPN и WireGuard
Обычно ломается парсер, а не профиль. Проверьте плагин, прочитайте импортированное подключение, исправьте secret-флаги и маршруты, затем проверьте перезагрузку.
Я выбрал Импорт из файла… в настройках GNOME, выбрал профиль, который работает с клиентом провайдера, и диалог закрылся, ничего не добавив в список. На втором ноутбуке импорт завершился, подключение появилось под именем профиля, а затем оно не прошло при первом запросе аутентификации. NetworkManager никогда не запускает ваш файл .ovpn или wg-quick как есть. Он передаёт файл парсеру, парсер превращает его в собственный формат подключения NetworkManager, и с этого момента туннель строится из этого разобранного объекта — секреты, маршруты, DNS и всё остальное. Поэтому полезный вопрос не в том, почему файл сломан, а в том, произошёл ли разбор и что он сохранил.
Что импорт на самом деле делает с файлом
Для OpenVPN парсер живёт в пакете плагина, а создаваемое им подключение указывает на службу D-Bus вроде org.freedesktop.NetworkManager.openvpn. Нет плагина — нет парсера: тип неизвестен nmcli, а графический список добавления VPN может вообще не показывать пункт импорта. WireGuard отличается в одном важном отношении — у NetworkManager есть собственные настройки WireGuard начиная с серии 1.30, поэтому отдельного пакета-плагина нет, но читатель wg-quick существует только в сборках, которые его поставляют.
В любом случае файл читается один раз. Результат записывается как keyfile в /etc/NetworkManager/system-connections/, называется по имени подключения, принадлежит root и недоступен другим пользователям, потому что содержит ключевой материал. Этот keyfile теперь и есть подключение; правка исходного .ovpn после этого ничего не меняет.
Три симптома относятся к трём разным этапам. Отсутствие пункта импорта или неизвестный тип означает, что не хватает плагина или версии. Ошибка импорта с упоминанием директивы означает, что парсер прочитал файл и отверг его часть. Подключение, которое существует, но никогда не активируется, означает, что разобранный объект неполон или сервер его отвергает. Определите, какой из трёх случаев у вас, прежде чем что-либо править.
Убедитесь в наличии плагина, прежде чем отлаживать профиль
Отсутствующий плагин выглядит ровно как повреждённый профиль, поэтому сначала проверьте пакет. В Debian и Ubuntu поддержка OpenVPN поставляется как network-manager-openvpn плюс помощник для рабочего стола; в Fedora это пакеты NetworkManager-openvpn и NetworkManager-openvpn-gnome; в Arch — networkmanager-openvpn.
dpkg -l network-manager-openvpn-gnome | tail -n 2 rpm -q NetworkManager-openvpn pacman -Q networkmanager-openvpn
Затем импортируйте по абсолютному пути: nmcli connection import type openvpn file /home/you/profile.ovpn. Относительные пути обычно работают, но оболочка, сменившая каталог, превращает быстрый импорт в объезд. Для WireGuard проверьте nmcli --version и убедитесь, что сторона ядра есть с modprobe wireguard; импорт, который удаётся на машине без модуля, оставляет вас с подключением, чьё устройство так и не появится. справочник nmcli документирует подкоманду import и допустимые имена типов. Если type wireguard отвергается сразу, сборка старше этой возможности, и правильный шаг — пакет из дистрибутива или бэкпорт, а не копирование конфигурации в произвольный каталог в надежде, что что-нибудь её прочитает.
Читайте подключение OpenVPN, а не .ovpn
Когда подключение создано, читайте разобранные настройки, а не перечитывайте файл: nmcli connection show "Work VPN" | grep -E '^vpn\.'. Вам нужны remote и порт, транспорт, идентификационный материал — ca, cert, key, tls-auth или tls-crypt — и метод аутентификации. Для профиля с паролем приватного ключа добавьте sudo nmcli --show-secrets connection show "Work VPN" и посмотрите на secret-флаги: 0 — none, значит секрет лежит в keyfile; 1 — agent-owned; 2 — not-saved, то есть он никогда не записывается в keyfile; 4 — not-required, то есть секрет вообще не нужен. Это биты, а не шкала, поэтому 3 — это просто agent-owned плюс not-saved. Секрет, который спрашивают раз за сеанс, — это agent-owned (1), причём его запрашивает агент; отдельного номера флага для этого нет. Несовпадение флагов — обычная причина, по которой профиль подключается из апплета рабочего стола и не работает из скрипта или при загрузке.
Быстрее всего увидеть, что парсер выбросил, попросив плагин записать файл обратно, а затем сравнив его: nmcli connection export "Work VPN" /tmp/roundtrip.ovpn. Директивы, исчезнувшие в этом diff, не будут существовать при подключении. Хуки — обычные подозреваемые: script-security, up, down и route-up рассчитывают на скрипт, запускаемый с повышенными правами, и намеренно не переносятся. Не снижайте проверку и не давайте лишних привилегий, чтобы импорт удался; неподдерживаемая опция обычно отражает набор возможностей плагина, а не недоступный сервер. Перенесите это поведение в dispatcher-скрипт NetworkManager или в политику на стороне сервера.
Также убедитесь, что поля идентичности выжили: ссылка на CA, remote-cert-tls и любая проверка имени, на которую полагался профиль. Подключение, которое поднимается без них, может разговаривать с чем угодно, что отвечает по этому адресу.
Читайте подключение WireGuard, а не файл wg-quick
Файл wg-quick — это формат с shell-семантикой; импортированное подключение — это набор настроек. PrivateKey становится приватным ключом интерфейса, Address — одним или несколькими адресами IPv4 и IPv6, DNS сопоставляется со свойствами resolver в NetworkManager, MTU сопоставляется с wireguard.mtu (собственное значение wg-quick по умолчанию — 1420), а каждый блок peer становится записью peer с публичным ключом, endpoint, разрешёнными IP и persistent keepalive. Выведите то, что сохранено, с nmcli --show-secrets connection show wg0; если список peer не появляется в этом выводе, прочитайте keyfile:
sudo sed -n '/^\[wireguard\]/,/^\[/p' /etc/NetworkManager/system-connections/wg0.nmconnection
Не выживает shell-половина wg-quick. PreUp, PostUp, PreDown, PostDown и Table — это поведение того инструмента, а не атрибуты интерфейса WireGuard, поэтому после импорта их никто не выполняет. Если оригинал использовал Table = off, чтобы не трогать маршрут по умолчанию, свежие выпуски NetworkManager предоставляют для той же цели ip4-auto-default-route и ip6-auto-default-route; задайте их явно, вместо того чтобы предполагать, что подключение ведёт себя как скрипт. Хуку, который добавлял собственный маршрут, нужен этот маршрут в настройках маршрутизации подключения, иначе он просто будет отсутствовать.
Дайте подключению ровно одного владельца
Классический последующий сбой — подключение, которое работает до следующей загрузки, а потом зацикливается. Обычно [email protected] всё ещё был включён с прошлого эксперимента, или клиент провайдера запускал собственный демон, и два владельца писали маршруты и DNS для одного и того же назначения. NetworkManager задаёт resolver своим путём, wg-quick пишет через resolvconf, и побеждает последний писатель — так что разрешение имён работает, потом перестаёт, потом снова работает. Проверьте systemctl status wg-quick@wg0, nmcli connection show --active и ip link show type wireguard, а затем отключите второго владельца, вместо того чтобы подкручивать его метрику.
Если вам действительно нужны оба, дайте им отдельные интерфейсы и непересекающиеся разрешённые IP, и пусть ровно один из них устанавливает маршрут по умолчанию. Два маршрута по умолчанию с разными метриками — это не split tunnel; это гонка, которую решает служба, стартующая второй. И после переподключения снова проверьте применённое состояние — разовая ручная правка resolver, которая всё чинит, не доказывает, что импорт полон.
Проверьте трафиком и переживите перезагрузку
Поднимите подключение с nmcli connection up "Work VPN", а затем читайте состояние, адрес и маршруты, вместо того чтобы доверять значку: nmcli device show wg0 | grep -E 'GENERAL.STATE|IP4.ADDRESS|IP4.ROUTE', ip route show default и настоящий запрос имени, которое разрешается только внутри туннеля. Handshake или успешный ping доказывает лишь то, что криптография работает; он ничего не говорит о пересылке, префиксах split tunnel или приватном DNS — а это обычно и ломается.
Затем перезагрузитесь и повторите. Поведение autoconnect, переименованный интерфейс и плагин, который загружается после устройства, — всё это сбои, которые видно только при чистой загрузке. journalctl -u NetworkManager -b --no-pager | tail -n 40 показывает, что демон сделал с этим подключением в этой загрузке. Для второго компьютера скопируйте keyfile и держите его принадлежащим root с режимом 600, либо используйте nmcli connection export для OpenVPN и импортируйте полученный .ovpn заново — у пути экспорта нет эквивалента для WireGuard, так что это направление — копия файла или новый импорт из защищённого оригинала.
Коротко, по порядку: подтвердите плагин или версию NetworkManager, импортируйте по абсолютному пути, прочитайте разобранные настройки вместе с secret-флагами, сравните экспорт OpenVPN с оригиналом, проверьте хуки и маршруты со стороны WireGuard, отключите любого второго владельца, а затем после перезагрузки проверьте разрешение имени и таблицу маршрутов. Когда подключение проходит всё это, файл профиля, с которого оно началось, можно вернуть в защищённое хранилище.