Когда VPN-соединение поднимается на Linux-десктопе, за кулисами работает NetworkManager: он добавляет маршруты через туннельный интерфейс, перенастраивает DNS-резолвер и следит за тем, чтобы трафик шёл именно туда, куда ожидает пользователь. Понимание этой механики помогает диагностировать утечки DNS, настраивать split tunneling и разбираться, почему после подключения VPN перестали открываться локальные ресурсы.
NetworkManager не реализует VPN-протоколы самостоятельно. Для каждого типа туннеля существует плагин:
Плагин получает параметры из профиля соединения, запускает соответствующий VPN-демон или настраивает интерфейс, а затем передаёт NetworkManager набор маршрутов и DNS-серверов, которые тот применяет к системе.
Профили хранятся в
При активации VPN-соединения NetworkManager выполняет два действия:
Если в профиле не указано
В случае WireGuard это напрямую связано с параметром
Если
Пример: корпоративный VPN даёт доступ к
Или через nmcli:
Когда в системе несколько интерфейсов с маршрутами по умолчанию (например, Wi-Fi и VPN), NetworkManager использует метрику (
Проверить текущие метрики:
Если маршруты конфликтуют, метрику можно задать явно:
DNS — наиболее частый источник проблем при работе VPN на Linux. NetworkManager поддерживает несколько бэкендов для применения DNS-настроек:
Определить активный бэкенд:
Когда одновременно активны несколько соединений (Wi-Fi + VPN), каждое может предлагать свои DNS-серверы. NetworkManager разрешает конфликт через
Типичная настройка для VPN, чтобы гарантировать использование только VPN-DNS:
VPN-сервер может передавать домены поиска (search domains). Например, корпоративный VPN добавляет
Утечка DNS при работе VPN происходит, когда запросы уходят не через туннель, а через DNS-сервер провайдера. Причины:
Для комплексной проверки утечек существуют внешние сервисы (dnsleaktest.com, ipleak.net), которые показывают, какие DNS-серверы фактически обрабатывают запросы. Подробнее — в материале DNS leak: как VPN может скрыть IP, но выдать DNS-запросы, и как это проверить.
Полезные команды для проверки состояния после подключения VPN:
Причина: метрика маршрута по умолчанию через VPN выше, чем у основного интерфейса. Проверьте
Решение:
NetworkManager не восстановил оригинальный default route. Это происходит, если VPN-плагин некорректно удалил маршруты или если NetworkManager был перезапущен во время активной сессии.
Решение:
Проверьте, что VPN-профиль действительно передаёт DNS-серверы. Для OpenVPN это директива
Если серверы не появляются в
Если в системе одновременно запущены
Проверка:
Если порт занят несколькими процессами, отключите один из бэкендов или настройте dnsmasq на другой порт.
NetworkManager не управляет правилами iptables/nftables напрямую. Если нужно гарантировать, что трафик не пойдёт мимо туннеля (kill switch), это реализуется отдельно через правила файрвола.
Принцип kill switch: разрешить исходящий трафик только через туннельный интерфейс, а всё остальное — заблокировать, оставив исключение для самого VPN-сервера (чтобы туннель мог установиться).
Пример для nftables (WireGuard, сервер
Правила применяются последовательно: первое совпадение определяет действие. Без kill switch при обрыве туннеля трафик мгновенно пойдёт через основной интерфейс, что может привести к утечке реального IP. Подробнее о том, что видит провайдер при использовании VPN и без него — в материале Что видит интернет-провайдер при использовании VPN: метаданные, DNS и границы приватности.
Архитектура: что делает NetworkManager при подключении VPN
NetworkManager не реализует VPN-протоколы самостоятельно. Для каждого типа туннеля существует плагин:
NetworkManager-openvpn— для OpenVPN
NetworkManager-wireguard(илиnm-wireguard) — для WireGuard
NetworkManager-strongswan— для IKEv2/IPsec
NetworkManager-libreswan— для Libreswan/IPsec
Плагин получает параметры из профиля соединения, запускает соответствующий VPN-демон или настраивает интерфейс, а затем передаёт NetworkManager набор маршрутов и DNS-серверов, которые тот применяет к системе.
Профили хранятся в
/etc/NetworkManager/system-connections/ в формате keyfile (INI-подобный формат). Каждый профиль содержит секции [connection], [ipv4], [ipv6] и специфичную для VPN секцию (например, [vpn]).Управление маршрутами
При активации VPN-соединения NetworkManager выполняет два действия:
- Создаёт или настраивает туннельный интерфейс. Для WireGuard это
wg0,wg1и т. д. Для OpenVPN —tun0илиtap0. Интерфейс получает IP-адрес из пула VPN-сервера.
- Добавляет маршруты через этот интерфейс. Конкретный набор зависит от конфигурации.
Full tunnel (весь трафик через VPN)
Если в профиле не указано
ipv4.never-default = true, NetworkManager добавляет маршрут по умолчанию (0.0.0.0/0) через туннельный интерфейс. Оригинальный default route заменяется или получает бо́льшую метрику, чтобы туннельный маршрут имел приоритет.В случае WireGuard это напрямую связано с параметром
AllowedIPs: значение 0.0.0.0/0 означает, что все исходящие пакеты шифруются и отправляются через туннель. При использовании плагина NetworkManager для WireGuard этот параметр из конфигурационного файла транслируется в маршрут по умолчанию через интерфейс wg0.Split tunnel (часть трафика через VPN)
Если
ipv4.never-default = true, NetworkManager не добавляет default route через туннель. Вместо этого добавляются только маршруты к конкретным подсетям, указанным в конфигурации VPN-сервера или вручную в профиле.Пример: корпоративный VPN даёт доступ к
10.0.0.0/8, но весь остальной трафик идёт напрямую. В профиле это выглядит так:
INI:
[ipv4]
method=auto
never-default=true
route1=10.0.0.0/8
Или через nmcli:
Bash:
nmcli connection modify "Corp VPN" ipv4.never-default yes
nmcli connection modify "Corp VPN" +ipv4.routes "10.0.0.0/8"
Метрики маршрутов
Когда в системе несколько интерфейсов с маршрутами по умолчанию (например, Wi-Fi и VPN), NetworkManager использует метрику (
ipv4.route-metric) для определения приоритета. Меньшая метрика = выше приоритет. Значения по умолчанию зависят от типа соединения и версии NetworkManager; как правило, VPN-соединения получают меньшую метрику, чем проводные или беспроводные интерфейсы, что обеспечивает приоритет туннеля.Проверить текущие метрики:
Bash:
nmcli -f NAME,DEVICE,TYPE connection show --active
ip route show table main
Если маршруты конфликтуют, метрику можно задать явно:
Bash:
nmcli connection modify "My VPN" ipv4.route-metric 50
Управление DNS
DNS — наиболее частый источник проблем при работе VPN на Linux. NetworkManager поддерживает несколько бэкендов для применения DNS-настроек:
| Бэкенд | Как работает | Где встречается |
|---|---|---|
systemd-resolved | Передаёт DNS-серверы через D-Bus в systemd-resolved, который ведёт per-link конфигурацию | Fedora, Ubuntu (начиная с 22.04), Arch |
dnsmasq | Запускает локальный dnsmasq как кэширующий резолвер, пересылает запросы к нужным серверам | Старые версии Ubuntu, опционально |
resolvconf | Записывает в /etc/resolv.conf через утилиту resolvconf | Debian, Gentoo |
none / direct | NetworkManager сам пишет /etc/resolv.conf | Минимальные установки |
Определить активный бэкенд:
Bash:
grep -i dns /etc/NetworkManager/NetworkManager.conf
resolvectl status # если используется systemd-resolved
Приоритеты DNS-серверов
Когда одновременно активны несколько соединений (Wi-Fi + VPN), каждое может предлагать свои DNS-серверы. NetworkManager разрешает конфликт через
ipv4.dns-priority:- Значение по умолчанию: 0.
- Отрицательное значение (например, -100) означает, что DNS этого соединения имеет наивысший приоритет и используется эксклюзивно.
- Положительное значение — сервер добавляется в список, но не вытесняет другие.
Типичная настройка для VPN, чтобы гарантировать использование только VPN-DNS:
Bash:
nmcli connection modify "My VPN" ipv4.dns-priority -100
DNS-домены поиска
VPN-сервер может передавать домены поиска (search domains). Например, корпоративный VPN добавляет
corp.internal, и запрос gitlab резолвится как gitlab.corp.internal. Это настраивается через ipv4.dns-search:
Bash:
nmcli connection modify "Corp VPN" ipv4.dns-search "corp.internal"
Предотвращение утечек DNS
Утечка DNS при работе VPN происходит, когда запросы уходят не через туннель, а через DNS-сервер провайдера. Причины:
- NetworkManager не переназначил DNS. Бэкенд
resolvconfили прямая запись в/etc/resolv.confможет не обновиться, если VPN-плагин не передал серверы корректно.
- systemd-resolved кэширует старый сервер. Per-link DNS не обновился, и запросы уходят через link с более высоким приоритетом.
- IPv6 DNS не перекрыт. VPN туннелирует только IPv4, а DNS-запрос уходит по IPv6 к серверу провайдера.
Проверка текущего состояния
Bash:
## Текущий резолвер
cat /etc/resolv.conf
## Если systemd-resolved:
resolvectl status
resolvectl dns
## Тестовый запрос с указанием интерфейса
resolvectl query example.com --interface=tun0
Для комплексной проверки утечек существуют внешние сервисы (dnsleaktest.com, ipleak.net), которые показывают, какие DNS-серверы фактически обрабатывают запросы. Подробнее — в материале DNS leak: как VPN может скрыть IP, но выдать DNS-запросы, и как это проверить.
Рекомендуемая конфигурация против утечек
Bash:
## Принудительно использовать только DNS VPN-сервера
nmcli connection modify "My VPN" ipv4.dns-priority -100
## Отключить IPv6 на туннеле, если VPN не поддерживает IPv6
nmcli connection modify "My VPN" ipv6.method disabled
## Перезапустить соединение
nmcli connection down "My VPN" && nmcli connection up "My VPN"
Диагностика через nmcli и ip
Полезные команды для проверки состояния после подключения VPN:
Bash:
## Активные соединения и их устройства
nmcli connection show --active
## Детали конкретного соединения (маршруты, DNS)
nmcli connection show "My VPN"
## Таблица маршрутов
ip route show
## Адреса на туннельном интерфейсе
ip addr show tun0 # для OpenVPN
ip addr show wg0 # для WireGuard
## Статус systemd-resolved по интерфейсам
resolvectl status tun0
resolvectl status wg0
Типичные проблемы и решения
VPN подключается, но трафик не идёт через туннель
Причина: метрика маршрута по умолчанию через VPN выше, чем у основного интерфейса. Проверьте
ip route show — default route должен указывать на туннельный интерфейс с наименьшей метрикой.Решение:
Bash:
nmcli connection modify "My VPN" ipv4.route-metric 50
После отключения VPN нет доступа в интернет
NetworkManager не восстановил оригинальный default route. Это происходит, если VPN-плагин некорректно удалил маршруты или если NetworkManager был перезапущен во время активной сессии.
Решение:
Bash:
nmcli networking off && nmcli networking on
## или
systemctl restart NetworkManager
DNS не переключается на сервер VPN
Проверьте, что VPN-профиль действительно передаёт DNS-серверы. Для OpenVPN это директива
dhcp-option DNS в конфигурации сервера. Для WireGuard DNS-сервер обычно указывается в секции [Interface] клиентского конфига как DNS = ..., и плагин NetworkManager должен его подхватить.Если серверы не появляются в
resolvectl status, проверьте логи:
Bash:
journalctl -u NetworkManager --since "5 min ago" | grep -i dns
Конфликт с systemd-resolved и dnsmasq
Если в системе одновременно запущены
systemd-resolved и dnsmasq (например, dnsmasq как часть libvirt), они могут конфликтовать за порт 53. NetworkManager в этом случае не может корректно применить DNS.Проверка:
Bash:
ss -tlnp | grep :53
Если порт занят несколькими процессами, отключите один из бэкендов или настройте dnsmasq на другой порт.
Взаимодействие с firewall и kill switch
NetworkManager не управляет правилами iptables/nftables напрямую. Если нужно гарантировать, что трафик не пойдёт мимо туннеля (kill switch), это реализуется отдельно через правила файрвола.
Принцип kill switch: разрешить исходящий трафик только через туннельный интерфейс, а всё остальное — заблокировать, оставив исключение для самого VPN-сервера (чтобы туннель мог установиться).
Пример для nftables (WireGuard, сервер
203.0.113.1, порт 51820):
Bash:
## Разрешить трафик к VPN-серверу (для установки туннеля)
nft add rule inet filter output ip daddr 203.0.113.1 udp dport 51820 accept
## Разрешить весь трафик через туннельный интерфейс
nft add rule inet filter output oifname "wg0" accept
## Заблокировать остальной исходящий трафик
nft add rule inet filter output drop
Правила применяются последовательно: первое совпадение определяет действие. Без kill switch при обрыве туннеля трафик мгновенно пойдёт через основной интерфейс, что может привести к утечке реального IP. Подробнее о том, что видит провайдер при использовании VPN и без него — в материале Что видит интернет-провайдер при использовании VPN: метаданные, DNS и границы приватности.
Итоговый чек-лист настройки
- Убедитесь, что
ipv4.never-defaultсоответствует желаемому режиму (full/split tunnel).
- Установите
ipv4.dns-priority -100для VPN-соединения, если хотите эксклюзивное использование VPN-DNS.
- Отключите IPv6 на туннеле, если VPN-провайдер его не поддерживает.
- Проверьте
resolvectl statusпосле подключения: DNS-серверы должны принадлежать VPN.
- Настройте kill switch через nftables, если критична защита от утечек при обрыве.
- Протестируйте на dnsleaktest.com или аналогичном сервисе.
