Разбираемся с локальными DNS

20 марта 2019

  • Стало достаточно традиционным для Linux/Unix запускать на рабочих станциях небольшой локальный DNS-сервер (resolver), который ускоряет работу, запоминая (кэшируя) ответы на повторяющиеся DNS-запросы и отвечая на них гораздо быстрее, чем внешние DNS-серверы.
  • Для его использования в общесистемный /etc/resolv.conf помещается директива “nameserver 127.0.0.1” , а IP-адреса внешних DNS-серверов переносятся в настройки локального.
  • Однако при этом возникает проблема — если локальный ресолвер почему-либо не запущен, система остаётся без распознавания доменных имён, т.е. в такие моменты лучше использовать медленные внешние DNS, чем никакие.
  • Для её решения была написана утилита resolvconf, предоставляющая остальным программам централизованный интерфейс для добавления и удаления записей в /etc/resolv.conf при изменении сетевой конфигурации, запуске и остановке процессов и т.д.

Всё работало хорошо, пока не появились NetworkManager и systemd:

  • systemd содержит свой собственный ресолвер systemd-resolved, запущенный по умолчанию и требующий отдельной настройки.
  • NetworkManager пытается дружить со всеми — с resolvconf, с systemd, с наиболее распространёнными DNS-ресолверами.

Всё это привело к тому, что теперь в одной системе порт 53 может слушать несколько разных ресолверов, причём для избежания конфликтов NetworkManager и systemd-resolved используют вместо 127.0.0.1 другие IP-адреса в loopback-сети:

  • 127.0.0.1 — стандартный dnsmasq, Unbound или knot-resolver с настройками по умолчанию;
  • 127.0.1.1 — dnsmasq или Unbound, запущенный NetworkManager'ом и управляемый через D-Bus;
  • 127.0.0.53 — systemd-resolved.

Проблема заключается в том, что с systemd NetworkManager пытается дружить сильнее разумного:

  • если NM видит, что в системе установлен systemd-resolved, то автоматически использует его, не проверяя, включен тот или выключен;
  • из-за этого вместо адресов настоящих DNS в resolv.conf попадает 127.0.0.53.

Решение:

  • Устанавливаем старый добрый dnsmasq:
  • apt install dnsmasq resolvconf
  • Отключаем DNS-ресолвер systemd:
  • systemctl disable systemd-resolved
  • Редактируем /etc/NetworkManager/NetworkManager.conf => добавляем в секцию "[main]" следующие строки:
  • dns=default
    rc-manager=resolvconf
    
  • Обратите внимание, что вариант “dns=default” надо указывать явно, потому что он вовсе не является вариантом по умолчанию!

Что должно получиться после перезагрузки?

  • /etc/resolv.conf должен содержать “nameserver 127.0.0.1”, указывающий на локальный dnsmasq, а /run/dnsmasq/resolv.conf (часть настроек запущенного dnsmasq) — IP-адреса внешних ресолверов, которые NetworkManager получил по DHCP или из настроек сетевого соединения.
  • Если остановить dnsmasq вручную (systemctl stop dnsmasq), IP-адреса внешних ресолверов должны переместиться в /etc/resolv.conf.


← Назад в Блог

Подпишитесь на новые статьи: