Как настроить DNS на Ubuntu с VPN¶
Дано¶
- Имеется личный ноутбук с ОС Ubuntu 22.04.
 - Для разрешения DNS-имен используется локальный сервис 
systemd-resolved(1). - На работе выдали настройки VPN-подключения к корпоративной сети.
 - Сразу после подключения отвалился резолвинг внешних (2) доменных имен. Резолвинг внутренних (3) доменов тоже не работает.
 - А ещё, VPN-сервер анонсировал дефолтный маршрут к себе и руинит всю маршрутизацию. В общем, не работает ни-че-го :-).
 
systemd-resolved— это компонент системы инициализацииsystemd, который отвечает за разрешение DNS-запросов. Он предоставляет кэширование DNS-запросов, поддержку DNS через TLS (DoT) и DNS через HTTPS (DoH), а также может работать с различными источниками DNS, включая традиционные DNS-серверы, MDNS и LLMNR.systemd-resolvedможет управлять DNS-запросами для различных сетевых интерфейсов и поддерживает конфигурацию через D-Bus и конфигурационные файлы.- Внешние домены: Используются для доступа к ресурсам из интернета, доступные для всех пользователей.
 - Внутренние домены: Используются в локальных сетях и не доступны из интернета (например, домены, используемые в корпоративных сетях).
 
Задача¶
- Обеспечить корректное резрешение внешних доменов при отключенном VPN с использованием публичных NS-серверов.
 - Обеспечить корректное резрешение внешних и внутренних DNS-имен при подключенном VPN с использованием публичных и корпоративных NS-серверов. Внешние имена идем разрешать в Интернет. Внутренние — в контур компании.
 - Обеспечить корректную маршрутизацию трафика при подключенном VPN, чтобы работал доступ как к публичным, так и корпоративным ресурсам. А то DNS-имена могут успешно разрешаться, но Интернет-сайты при этом не загружаться.
 
Решение¶
Шаг 1. Настройка резолвинга DNS-имен.¶
- Сначала нужно установить 
dnsmasq. На следующем шаге мы отключаемsystemd-resolvedи резолвинг DNS-имен не будет работать, т.е. установить пакет не получится. - Затем нужно остановить и отключить 
systemd-resolved, т.к. он не поддерживает условный резолвинг по имени доменов. Это когда внешние домены мы идем разрешать на публичные NS-сервера, а предзаданный список внутренних доменов на корпоративные. По крайней мере у меня так и не удалось заставить его корректно работать, сколько я ни указывал опциюDomains=. - Далее удаляем символическую ссылку 
/etc/resolv.conf: - Создаем новый файл 
/etc/resolv.conf: - Добавляем в него следующую строку:
 - Открываем файл конфигурации 
dnsmasq: - Вносим следующие изменения:
   /etc/dnsmasq.conf
# Never forward plain names (without a dot or domain part) domain-needed # Add other name servers here, with domain specs if they are for # non-public domains. # Corporate NS1 server=/your-corporate-domain.dev/YOUR_CORPORATE_NS1_IP server=/your-corporate-domain.tech/YOUR_CORPORATE_NS1_IP ... # Corporate NS2 server=/your-corporate-domain.dev/YOUR_CORPORATE_NS2_IP server=/your-corporate-domain.tech/YOUR_CORPORATE_NS2_IP ... # You can control how dnsmasq talks to a server: this forces # queries to 10.1.2.3 to be routed via eth1 # server=10.1.2.3@eth1 # Настройки для корпоративных доменов. # Корпоративные DNS-серверы через VPN-туннель. server=YOUR_CORPORATE_NS1_IP@tun0 server=YOUR_CORPORATE_NS2_IP@tun0 ... # Настройки для всех остальных доменов. # Публичные DNS-серверы через интерфейс WiFi. server=1.1.1.1@wlp0s20f3 (1) server=8.8.8.8@wlp0s20f3 ... # If you want dnsmasq to listen for DHCP and DNS requests only on # specified interfaces (and the loopback) give the name of the # interface (eg eth0) here. # Repeat the line for more than one interface. #interface= # Or you can specify which interface _not_ to listen on #except-interface= # Or which to listen on by address (remember to include 127.0.0.1 if # you use this.) listen-address=127.0.0.53 (2) listen-address=172.17.0.1 (3) # Set the cachesize here. cache-size=150 # If you want to disable negative caching, uncomment this. no-negcache - Перезапускаем 
dnsmasq: 
- Идентификатор интерфейса см. с помощью команды 
nmcliилиnmcli device show | grep GENERAL.DEVICE. - Слушать на 
localhostдля обслуживания запросов от сервисов и приложений хоста. - Слушать на дефолтном IP шлюза сети Docker для обслуживания запросов из контейнеров. В команды запуска контейнеров
   нужно добавлять аргумент 
--dns 172.17.0.1. 
Теперь для резолвинга DNS-имен будет использоваться dnsmasq. Запросы для корпоративных доменов будут направляться
через VPN-туннель к корпоративным DNS-серверам, а все остальные запросы будут обрабатываться публичными DNS-серверами.
Далее необходимо настроить VPN-соединение.
Шаг 2. Настройка VPN-соединения.¶
- Заходим в настройки VPN-соединения в GUI (
NetworkManager) Ubuntu. - Вкладка IPv4:
- IPv4 Method: Automatic (DHCP);
 - DNS: Automatic;
 - Routes: Automatic;
 - Use this connection only for resources on its network — включить. Это деактивирует получение default маршрута из VPN-туннеля.
 
 
Осталось проверить сетап.
Шаг 3. Диагностические команды (опционально)¶
sudo systemctl status dnsmasq
journalctl -u dnsmasq
sudo lsof -i :53
sudo netstat -tuln | grep :53
sudo ss -tuln | grep :53
Шаг 4. Проверка разрешения DNS-имен.¶
- При отключенном VPN-туннеле:
- Проверка разрешения DNS-имен:
 - Проверка доступности Интернет-сайтов:
- Открыть в браузере Интернет-сайт. Должен загрузиться, иначе тест провален.
 
 
 - При включенном VPN-туннеле:
- Проверка разрешения DNS-имен:
 - Проверка доступности внешних и внутренних сайтов:
- Открыть в браузере Интернет-сайт. Должен загрузиться, иначе тест провален.
 - Открыть в браузере корпоративный сайт. Должен загрузиться, иначе тест провален.
 
 
 
Если все проверки прошли успешно, поздравляю! 🎉
Сетап работает корректно, можно эффективно работать с внешними и корпоративными ресурсами при поднятом VPN-туннеле.