Ресолвер
Ресолвер — механизм преобразования имен хостов в адреса 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 варианта, для статической настройки и для DHCP.
- для статики все просто, файл копируется из /etc/net/ifaces/foo/resolv.conf в /etc/resolv.conf
- для DHCP посложнее. dhcpcd получает данные от dhcp-сервера, а дальше с помощью хуков (/lib/dhcpcd/dhcpcd-hooks/20-resolv.conf) обновляет /etc/resolv.conf
openresolv
Был придуман для того, что бы во время работы при смене DNS удобно управлять /etc/resolv.conf. Оправдан, кода вы одни dns получили от dhcp сервера, а другие dns от 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-reolver(конечно они гораздо мощнее и гибче), но он умеет, например, DNSSEC и DNSOverTLS.
Кроме этого он предоставляет 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).
А вот если это не симлинк, а файл, то 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.
Первая глобальная проблема
update_chroot не предполагает симлинка /etc/resolv.conf.
Приплыли. Большая часть проблем отпала (точнее наоборот появилась).
Подождем еще 3 месяца и баге будет 3 года. Спасибо ldv@.
altbug #33591
Вторая проблема
Как изменение 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
Подведение итогов и рекомендации
- 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»