DNS в Ubuntu 20.04. Возвращаем контроль над /etc/resolv.conf

Уже достаточно давно в Ubuntu встроен локальный кеширующий DNS-сервер, который «ускоряет» работу, кешируя ответы на повторяющиеся DNS-запросы. Файлом resolv.conf управляют приложения и если внести туда изменения — жить они будут ровно до следующего ребута. Или что бывает еще чаще — resolv.conf это симлинк на /run/systemd/resolve/resolv.conf или /run/resolvconf/resolv.conf. Все эти надстройки над простой возможностью вбить echo «nameserver 8.8.8.8» >> /etc/resolv.conf не «напрягают», но когда вместе с обновлениями колличество DNS-серверов в системе увеличивается, хочется в этом навести порядок.

Все описанное в статье касается десктоп версии Ubuntu 20.04, для Ubuntu server алгоритм немного другой и тут я его касаться не буду. У меня стоит Mint уже достаточно давно и пережил серию апгрейдов с 18й до 20й Ubuntu. За это время на смену dnsmasq и resolvconf пакетам пришел systemd-resolved. При апгрейдах Ubuntu заботливо удалил resolvconf, но почему-то (потому что стоит libvirt KVM) оставил dnsmasq.

Если заглянуть в lsof -i :53 видно что у нас есть два сервера совместно слушающих 53 порт — dnsmasq и systemd-resolved. Но зачем нам столько? Меня в целом устраивает и команда из первого абзаца — решающая ровно ту же задачу. Правда остается вопрос с получением DNS через DHCP, поэтому я решил оставить управление файлом resolv.conf NetworkManager’у.

С вступлением закончили, перейдем к практической части.

Шаг первый, интуитивный. Первым делом пытаясь вернуть контроль, наивный я удалил dnsmasq, systemd-resolved, убрал симлинк на /run/systemd/resolve/resolv.conf и добавил для теста в resolv.conf DNS-сервер

apt remove dnsmasq
apt remove systemd-resolved
rm /etc/resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf

Проверил резолв сайтов — работает. Для теста перезагрузил систему и… получил систему без прописаного DNS-сервера. Управление resolv.conf осталось под NetworkManager, содержимое файла было следующим:

cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 127.0.1.1

Стало понятно что с наскока это сделать не получится и стоит почитать мануалы. Пришло время шага второго — исследовательского.

Оказалось что все достаточно просто. NetworkManager давно смирился с тем что локальных DNS-служб может быть несколько и в зависимости от той какая используется в resolv.conf может быть следующее:

  • 127.0.0.1 — dnsmasq или unbound с настройками по умолчанию
  • 127.0.1.1 — dnsmasq или unbound и запущенный NetworkManager
  • 127.0.0.53 — systemd-resolved, запущенный по умолчанию

Читаем man networkmanager.conf раздел про ДНС и выясняем:

Set the DNS processing mode.
If the key is unspecified, default is used, unless /etc/resolv.conf is a symlink to /run/systemd/resolve/stub-resolv.conf, /run/systemd/resolve/resolv.conf, /lib/systemd/resolv.conf or /usr/lib/systemd/resolv.conf. In that case, systemd-resolved is chosen automatically.

default: NetworkManager will update /etc/resolv.conf to reflect the nameservers provided by currently active connections. The rc-manager setting (below) controls how this is done.

dnsmasq: NetworkManager will run dnsmasq as a local caching nameserver, using "Conditional Forwarding" if you are connected to a VPN, and then update resolv.conf to point to the local nameserver. It is possible to pass custom options to the dnsmasq instance by adding them to files in the "/etc/NetworkManager/dnsmasq.d/" directory. Note that when multiple upstream servers are available, dnsmasq will initially contact them in parallel and then use the fastest to respond, probing again other servers after some time. This behavior can be modified passing the 'all-servers' or 'strict-order' options to dnsmasq (see the manual page for more details).

systemd-resolved: NetworkManager will push the DNS configuration to systemd-resolved

unbound: NetworkManager will talk to unbound and dnssec-triggerd, using "Conditional Forwarding" with DNSSEC support. /etc/resolv.conf will be managed by dnssec-trigger daemon. This option is deprecated. Note that dnssec-trigger ships a NetworkManager dispatcher script so this DNS plugin is not necessary.

none: NetworkManager will not modify resolv.conf. This implies rc-manager unmanaged

Все прояснилось, если резолв.конф это симлинк — NetworkManager считает что используется systemd-resolved. Остальные режимы определяют как менеджер будет работать с файлом. Я симлинк удалил и в моем случае он решил что я использую dnsmasq. Потому требуется немного обновить конфиг NetworkManager. Для этого создаю конфиг файл со следующим содержимым:

cat /etc/NetworkManager/conf.d/dns.conf 
[main]
# Указываю что работаем в режиме по умолчанию
# Этот режим предполагает наличие дополнительной настройки rc-manager
# которая определяет как это делается. Параметры этой настройки также присутствуют в man после DNS
# Если необходимо обновлять resolv.conf в ручную, установите параметр в none
#dns=none
dns=default
# rc-manager параметр ставлю в file
# Параметр говорит что менеджер будет писать параметры DNS сразу в resolv.conf
# Удобно в случае если настройки получаем по DHCP
rc-manager=file

С настройками покончено, перезагружаю NetworkManager и проверяю resolv.conf

service NetworkManager restart
cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 8.8.8.8
nameserver 2001:4860:4860::8844
nameserver 2001:4860:4860::8888

Работает. Перезагружаю систему для уверенности и все продолжает работать как хотелось.

Шаг третий. Для тех кто выбрал dns=none шагом выше.

Приведу краткий мануал по resolv.conf (man resolv.conf)

Максимальное количество нэймсерверов в файле — 3, укажете больше — остальные кроме первых трех работать не будут.

Также resolv.conf предполагает опции:

options attempts=2, timeout=2, rotate, где

  • attempts — число попыток посылки запроса к серверу. (По логике резолвер сначала перебирает все сервера из списка и если ни один сервер не ответил, повторяет опрос по списку серверов с числом попыток указанным в attempts)       
  • timeout — — таймаут за который сервер должен успеть ответить (по умолчанию 5 сек.)       
  • rotate   случайный выбор nameserver из списка, а не опрос по порядку.

Для отладки удобно использовать «options debug»

[Голосов: 0 Средний бал: 0]