Как настроить 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-туннеле.