Настройка DNS в Ubuntu: systemd-resolved, resolv.conf и netplan
В Ubuntu за разрешение имён отвечает systemd-resolved, а привычный /etc/resolv.conf — всего лишь симлинк, который переписывается сам. Разбираем, где на самом деле задавать DNS-серверы, как посмотреть текущие через resolvectl, чем отличается глобальный DNS от привязанного к интерфейсу и как включить шифрование запросов.
Самая частая ошибка при настройке DNS в Ubuntu — вписать серверы в /etc/resolv.conf и обнаружить, что после перезагрузки правки исчезли. Файл давно перестал быть местом настройки: он генерируется автоматически. Разбираемся, где DNS задаётся на самом деле и как проверить, что запросы уходят туда, куда вы ожидаете.
Кто на самом деле отвечает за DNS
В Ubuntu 24.04 цепочка выглядит так:
- Приложение спрашивает имя через системную библиотеку.
- Запрос уходит на локальный резолвер
systemd-resolved, слушающий127.0.0.53:53. resolvedсмотрит кэш и, если ответа нет, обращается к вышестоящим DNS-серверам.- Список этих серверов он берёт из настроек интерфейса (netplan/DHCP) или из своего глобального конфига.
Отсюда главное следствие: /etc/resolv.conf — не настройка, а результат работы resolved. Он представляет собой симлинк:
ls -l /etc/resolv.conf
# /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
Внутри почти всегда одна и та же строка:
nameserver 127.0.0.53
Это адрес локальной заглушки resolved, а не ваш DNS-сервер. Реальные вышестоящие серверы смотрят другой командой.
Смотрим текущие настройки
resolvectl status
Вывод разбит по интерфейсам. Ключевые строки:
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Link 2 (ens3)
Current Scopes: DNS
Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS
Current DNS Server: 192.168.1.1
DNS Servers: 192.168.1.1 8.8.8.8
DNS Domain: local.lan
Current DNS Server — куда уходят запросы прямо сейчас. DNS Servers — весь список для этого интерфейса. Если строки пустые, а в Global тоже ничего нет, имена разрешаться не будут.
Короткий вариант — только серверы:
resolvectl dns
resolvectl domain # поисковые домены
resolvectl statistics # попадания в кэш
Задаём DNS через netplan
Для сервера это основной способ. Правим файл в /etc/netplan/ (имя зависит от системы — 50-cloud-init.yaml, 01-netcfg.yaml):
network:
version: 2
ethernets:
ens3:
addresses: [192.168.1.50/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
search: [local.lan]
Применяем с автоматическим откатом:
sudo netplan try
Команда применит конфигурацию и через две минуты вернёт прежнюю, если её не подтвердить. На удалённом сервере это защита от потери связи. Когда уверены — sudo netplan apply. Подробно про синтаксис и отладку — в статье про netplan.
Проверяем, что серверы подхватились:
resolvectl status ens3
Если адрес получается по DHCP
DHCP-сервер обычно навязывает и свои DNS. Чтобы взять адрес по DHCP, но использовать свои DNS-серверы:
network:
version: 2
ethernets:
ens3:
dhcp4: true
dhcp4-overrides:
use-dns: false
nameservers:
addresses: [1.1.1.1, 9.9.9.9]
use-dns: false заставляет игнорировать DNS из DHCP-аренды, остальное (адрес, шлюз) продолжает приходить автоматически.
Глобальные настройки resolved
Когда DNS нужен один на всю систему, независимо от интерфейсов, его задают в /etc/systemd/resolved.conf:
[Resolve]
DNS=1.1.1.1 8.8.8.8
FallbackDNS=9.9.9.9
Domains=~.
Cache=yes
sudo systemctl restart systemd-resolved
resolvectl status
Что означают параметры:
DNS— основные серверы;FallbackDNS— запасные, используются если основные молчат;Domains=~.— маршрутизировать все домены на эти серверы, а не только те, что не обслуживаются интерфейсами. Без этой строки серверы из DHCP могут иметь приоритет;Cache=yes— кэшировать ответы (по умолчанию включено).
Разница между глобальным и интерфейсным DNS важна на машинах с VPN или несколькими сетями: resolved умеет отправлять запросы для разных доменных зон на разные серверы. Для одиночного сервера проще задать всё в netplan.
Локальный домен и поиск имён
Параметр search (в netplan) или Domains (в resolved.conf) задаёт домены, которые дописываются к коротким именам:
nameservers:
addresses: [192.168.1.1]
search: [local.lan, office.example.com]
После этого ping db-server попробует db-server.local.lan, затем db-server.office.example.com. Удобно во внутренней сети, где машины называют короткими именами.
Проверить, как разрешается конкретное имя и через какой сервер:
resolvectl query db-server
Для статических записей, которые не должны зависеть от DNS вообще, остаётся /etc/hosts:
192.168.1.20 db-server db-server.local.lan
Этот файл проверяется раньше DNS — удобно для фиксации адресов на время миграции или для отключения обращений к внешним хостам.
Шифрование запросов: DNS-over-TLS
resolved умеет отправлять запросы по TLS, скрывая их содержимое от промежуточных узлов. Включается в /etc/systemd/resolved.conf:
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 9.9.9.9#dns.quad9.net
DNSOverTLS=yes
Синтаксис адрес#имя обязателен: имя после решётки нужно для проверки сертификата сервера. Без него соединение установится, но подлинность сервера не проверяется.
sudo systemctl restart systemd-resolved
resolvectl status | grep -i "DNSOverTLS"
Значение yes в строгом режиме означает, что при недоступности TLS запросы не пойдут в открытом виде — имена просто перестанут разрешаться. Компромиссный вариант DNSOverTLS=opportunistic разрешает откат на обычный DNS, но тогда шифрование не гарантировано.
Учтите, что DNS-over-TLS немного увеличивает задержку первого запроса к каждому серверу и требует, чтобы порт 853 был открыт наружу.
Диагностика
Проверить разрешение имени:
resolvectl query serveraid.ru # через systemd-resolved, с указанием источника
dig serveraid.ru # напрямую, минуя resolved
dig @1.1.1.1 serveraid.ru # к конкретному серверу
dig +short serveraid.ru # только адрес
Утилита dig ставится пакетом dnsutils:
sudo apt install -y dnsutils
Сравнение resolvectl query и dig @сервер сразу показывает, где проблема: если прямой запрос к DNS-серверу работает, а через resolved — нет, дело в локальной конфигурации, а не в сети.
Полезные проверки:
systemctl status systemd-resolved # работает ли служба
sudo resolvectl flush-caches # сбросить кэш
sudo resolvectl log-level debug # подробный лог
journalctl -u systemd-resolved -f # смотреть, что происходит
Просмотр логов разобран в шпаргалке по journalctl.
Проверить, что порт 53 слушается локально:
sudo ss -tulpn | grep :53
Строка 127.0.0.53:53 — это resolved. Если там же висит что-то ещё (например, установленный dnsmasq или BIND), они конфликтуют за порт — работать будет только один.
Типовые проблемы
Правки в /etc/resolv.conf пропадают после перезагрузки. Так и должно быть: файл генерируется. Задавайте DNS в netplan или resolved.conf.
Имена не разрешаются, хотя IP пингуется. Значит сеть работает, а DNS — нет. Смотрите resolvectl status: скорее всего, список серверов пуст. Проверьте, что в netplan-конфиге секция nameservers не потерялась при правке YAML — отступы там критичны.
DNS из DHCP перебивает ваши серверы. Добавьте dhcp4-overrides: {use-dns: false} в netplan или Domains=~. в resolved.conf.
Внутренние имена не резолвятся, внешние работают. Не задан поисковый домен: добавьте search в netplan. Проверить: resolvectl domain.
Нужно полностью отключить systemd-resolved. Изредка требуется, когда на машине работает собственный DNS-сервер (BIND, dnsmasq, Pi-hole):
sudo systemctl disable --now systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
После этого /etc/resolv.conf становится обычным файлом и больше не переписывается. Способ рабочий, но нештатный: часть инструментов Ubuntu рассчитывает на присутствие resolved, а созданный вручную файл может перезаписать resolvconf или NetworkManager, если они установлены.
Частые вопросы
Почему изменения в /etc/resolv.conf не сохраняются?
Потому что это симлинк на файл, который генерирует systemd-resolved. Все правки затираются при следующем обновлении сетевой конфигурации или перезагрузке.
Настраивать DNS нужно в netplan (секция nameservers) для конкретного интерфейса либо в /etc/systemd/resolved.conf — для всей системы.
Как посмотреть, какие DNS-серверы используются сейчас?
Командой resolvectl status — она покажет серверы по каждому интерфейсу и глобальные, а также какой сервер используется прямо сейчас (Current DNS Server).
Смотреть /etc/resolv.conf бесполезно: там почти всегда 127.0.0.53 — адрес локальной заглушки, а не реального сервера.
Как задать DNS на Ubuntu Server?
Через netplan: в конфиге /etc/netplan/*.yaml в секции интерфейса добавьте nameservers: {addresses: [1.1.1.1, 8.8.8.8]} и примените через sudo netplan try.
Если адрес приходит по DHCP, но DNS нужны свои, добавьте dhcp4-overrides: {use-dns: false} — иначе серверы из DHCP-аренды перебьют ваши.
Как очистить кэш DNS в Ubuntu?
sudo resolvectl flush-caches. Проверить, что кэш действительно сброшен, можно через resolvectl statistics — счётчик текущих записей обнулится.
Перезапуск службы (sudo systemctl restart systemd-resolved) тоже очищает кэш, но это более грубый способ.
Чем resolvectl отличается от dig?
resolvectl query спрашивает через systemd-resolved — то есть тем же путём, каким ходят обычные приложения, и показывает, из кэша ли получен ответ и через какой интерфейс. dig обращается к DNS-серверу напрямую, минуя локальный резолвер.
Разница помогает в диагностике: если dig @1.1.1.1 отвечает, а resolvectl query — нет, проблема в конфигурации resolved, а не в сети или самом DNS-сервере.
Что запомнить
/etc/resolv.conf— сгенерированный симлинк, править его бесполезно;127.0.0.53в нём — это локальныйsystemd-resolved.- Реальные серверы смотрят командой
resolvectl status, задают — в netplan или/etc/systemd/resolved.conf. - При DHCP свои DNS-серверы требуют
dhcp4-overrides: {use-dns: false}, иначе их перебьёт аренда. - Применяйте netplan через
netplan try: он откатит конфигурацию сам, если вы потеряете связь с сервером. - В диагностике сравнивайте
resolvectl queryиdig @сервер— это сразу отделяет проблему конфигурации от проблемы сети.