Ресолвер

Материал из ALT Linux Wiki

Ресолвер — механизм преобразования имен хостов в адреса IP.

Включает в себя glibc, libresolv, использует /etc/resolv.conf, /etc/hosts, /etc/nsswitch.conf

В ALT дополнительно используются /etc/net/ifaces/*/resolv.conf, systemd-resolved, openresolv

Введение

Лучшее понимание механизмов преобразования имен хостов в адреса IP позволит быстрее диагностировать ошибки.

Преобразованием имен хостов в адреса занимается glibc на основе различных источников данных (/etc/hosts, mDNS, winbind, dns, ldap и т. п.). Это модульная система, можно добавить много различных модулей.

Источники для преобразования имён в адреса указаны в grep hosts /etc/nsswitch.conf:

hosts:      files dns myhostname

Например, добавив в строку hosts: параметр mymachines (пакет libnss-mymachines), мы сможем обращаться к нашим контейнерам systemd-nspawn по именам.

Мы сейчас говорим о модуле dns (/lib{,64}/libnss_dns.so), который слинкован с libresolv. Именно в libresolv определено использование /etc/resolv.conf.

С вводной частью закончили, давайте перейдём к практике и рассмотрим, кто и как наполняет этот /etc/resolv.conf.

etcnet

В etcnet есть 2 варианта создания /etc/resolv.conf, один для статической настройки, другой для DHCP.

  • для статики все просто, файл копируется из /etc/net/ifaces/foo/resolv.conf в /etc/resolv.conf
  • для DHCP посложнее. dhcpcd получает данные от сервера DHCP, а дальше с помощью хуков (/lib/dhcpcd/dhcpcd-hooks/20-resolv.conf) обновляет /etc/resolv.conf

openresolv

openresolv был придуман для того, что бы во время работы при смене DNS удобно управлять /etc/resolv.conf. Оправдан, кода вы одни серверы DNS получили от сервера DHCP, а другие — от соединения VPN.

Когда у нас происходит настройка на серверы DNS только один раз при загрузке, то использовать openresolv нет необходимости. Возможно даже вредно, т. к. это вносит еще один элемент (прокладку) во всю эту хрупкую конструкцию.

При наличии openresolv в системе, etcnet начинает автоматически использовать её, поэтому копирование /etc/net/ifaces/foo/resolv.conf в /etc/resolv.conf или наполнение /etc/resolv.conf данными от сервера DHCP происходит не напрямую, а через вызов /sbin/resolvconf.

Надо еще упомянуть, что openresolv умеет готовить конфиги для dnsmasq, unbound, pdns, bind, если они используются как локальные серверы DNS.

systemd-resolved

systemd-resolved — это по сути маленький локальный кэширующий dns-сервер, принимающий запросы на 127.0.0.53:53. Его можно с натяжкой сравнить с dnsmasq, unbound, knot-resolver (конечно, они гораздо мощнее и гибче), но он умеет, например, DNSSEC и DNS-Over-TLS.

Кроме этого, он предоставляет API для взаимодействия напрямую через вызовы библиотеки, а не через запросы по UDP.

Добавив в nsswitch.conf

hosts: resolve

(пакет libnss-resolve), мы сможем резолвить имена без (/lib{,64}/libnss_dns.so) и без обращения к /etc/resolv.conf. /etc/resolv.conf он тоже умеет читать, но никак его не модифицирует.

Скажем так, у systemd-resolved свой resolv.conf, который находится в /run/systemd/resolve. И не один.

Чтобы glibc продолжал работать с nss-модулем dns, systemd-resolved может предоставить для него resolv.conf

а) статический /lib/systemd/resolv.conf в котором указан nameserver 127.0.0.53.

сделав симлинк /etc/resolv.conf → /lib/systemd/resolv.conf, мы укажем нашей системе использовать systemd-resloved как локальный сервер DNS.

б) сгенерированный /run/systemd/resolve/stub-resolv.conf

Вот на него более правильно делать симлинк /etc/resolv.conf. В нём также указан nameserver 127.0.0.53, но еще могут быть указаны домены поиска:

search example.com
в) сгенерированный /run/systemd/resolve/resolv.conf

В нём указаны реальные серверы DNS. Т. е., скопировав в /etc/resolv.conf (или симлинк), приложения (glibc nss-dns) перестанут использовать локальный кэширующий dns-сервер systemd-resolved и начнут напрямую использовать указанные серверы.

Информация в этот сгенерированный файл попадает из файлов /etc/systemd/network/*.network и /etc/systemd/resolved.conf (DNS=…, Domains=…)

Эти же данные используются и для работы самого systemd-resolved.

NetworkManager

NetworkManager по умолчанию использует встроенный клиент DHCP, но может и внешний.

Можно определить в /etc/NetworkManager/conf.d/dhcp-client.conf:

[main]
dhcp=dhcpcd или dhclient (по умолчанию internal)

Так же он может использовать dnsmasq, unbound или systemd-resolved в качестве локального сервера DNS (dns=dnsmasq). При этом не надо отдельно стартовать dnsmasq или unbound, он их сам запустит и настроит (подсунет конфиг).

Если /etc/resolv.conf является симлинком на один из systemd-resolved конфигов, NM это понимает и использует systemd-resolved (не трогает /etc/resolv.conf).

А вот если /etc/resolv.conf не симлинк, а файл, то NM начинает его изменять (указывает nameserver для статического или DHCP адреса), используя openresolv (собран с параметром --with-config-dns-rc-manager-default=resolvconf).

По аналогии с systemd-resolved NM генерирует resolv.conf в /run/NetworkManager/resolv.conf и /run/NetworkManager/no-stub-resolv.conf

update_chrooted

Наши замечательные ALT особенности

Множество сервисов и отдельных программ(например ping) запускаются в chroot. В этот chroot должны быть скопированы и библиотеки, и настройки для этих библиотек, в частности resolv.conf. Т. е. ping не использует /etc/resolv.conf, а использует /var/resolv/etc/resolv.conf.

Нам очень важно держать в chroot'ах resolv.conf синхронным c основной системой.
Вроде все утилиты, обновляющие /etc/resolv.conf, обучены вызывать update_chrooted conf.

Первая глобальная проблема

update_chroot не предполагал симлинка /etc/resolv.conf до версии chrooted-0.3.11-alt1: altbug #33591
Проблема возникала в системах с systemd, на текущий момент нужная версия chrooted присутствует в ветках, начиная с p8.

Вторая проблема

Как изменение resolv.conf обрабатывать в systemd.
Если используются etcnet или NetworkManager то они за собой дёргают update_chrooted. А вот systemd-networkd и systemd-resolved не имеют возможности запустить какой либо хук.

Дополнительные сервисы в systemd

(Для решения второй проблемы с update_chrooted) systemd умеет отслеживать изменение файлов и запускать по событию сервис. Были написаны сервисы altlinux-libresolv.path (отслеживает изменения) и altlinux-libresolv.service (запускает /etc/chroot.d/resolv.conf).

Для обновления /etc/resolv.conf без использования openresolv были написаны сервисы altlinux-simpleresolv.path и altlinux-simpleresolv.service

Для обновления /etc/resolv.conf с ипользование openresolv были написаны сервисы altlinux-openresolv.path и altlinux-openresolv.service

dnsmasq

Если используется dnsmasq, то он сам перезаписывает /etc/resolv.conf в соответствии со своей конфигурацией.

Подведение итогов и рекомендации

  • systemd-resolved работает в связке с systemd-networkd. Можно конечно и без, но это создание дополнительных трудностей. Проще рекомендовать использовать systemd-resolved только с systemd-networkd.
  • При использовании etcnet не пытайтесь использовать systemd-resolved. Можно конечно, но это создание дополнительных трудностей. Просто удалите пакет systemd-networkd.
  • NetworkManager вроде должен уметь работать в любых условиях с кем угодно.

Примечания

Источник — письмо Alexey Shabalin <a.shabalin@gmail.com> в sisyphus (31 марта 2020 г.) «Приключения resolv.conf в ALT»

См. также