[sisyphus] приключения resolv.conf в ALT

Alexey Shabalin a.shabalin на gmail.com
Вт Мар 31 22:05:17 MSK 2020


> PS: следующим письмом попробую подробно описать наши кувыркания с resolv.conf.
> дождитесь его, прежде чем отвечать :)

Может это куда-то на wiki перенести. Лучшее понимание механизмов
позволит быстрее диагностировать ошибки.

Преобразование имен хостов в адреса занимается 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

1) 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

2) 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-сервера.

3) 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.

4) 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)
А вот если не симлинк, то начинает его именять (указывает nameserver
для статического или DHCP адреса) используя openresolv(собран с
параметром --with-config-dns-rc-manager-default=resolvconf) .
По аналогии с systemd-resolved генерирует resolv.conf в
/run/NetworkManager/resolv.conf и /run/NetworkManager/no-stub-resolv.conf

5) 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 на .
https://bugzilla.altlinux.org/show_bug.cgi?id=33591
- Вторая проблема, как изменение resolv.conf обрабатывать в systemd.
Если используются etcnet или NetworkManager то они за собой дёргают
update_chrooted.
А вот systemd-networkd и systemd-resolved не имеют возможности
запустить какой либо хук.

6) дополнительные сервисы в systemd
- Для решения второй проблемы в пункте 5
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


Подробная информация о списке рассылки Sisyphus