Резолвер
Резолвер — механизм преобразования имен хостов в адреса 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 — фреймворк для управления файлом /etc/resolv.conf. openresolv применим для организации совместного доступа нескольких приложений к файлу /etc/resolv.conf. При наличии openresolv в системе, etcnet начинает автоматически использовать его, поэтому копирование /etc/net/ifaces/foo/resolv.conf в /etc/resolv.conf или наполнение /etc/resolv.conf данными от сервера DHCP происходит не напрямую, а через вызов /sbin/resolvconf. openresolv также настраивает зоны для локальных резолверов, отличных от glibc, и отмечает конфигурации как частные (то есть не в /etc/resolv.conf). Например, следующие файлы resolv.conf, созданные DHCP-клиентом и отправленные в resolvconf:
# resolv.conf from bge0
search foo.com
nameserver 1.2.3.4
# resolv.conf from tap0
domain bar.org
nameserver 5.6.7.8
Запросы к foo.com будут направляться на 1.2.3.4, а запросы к bar.org — на 5.6.7.8. Если какой-либо из них отмечен как приватный, то для них будут пересылаться только запросы по их поисковым или доменным именам. Однако для этого требуется, чтобы резолверы были настроены на использование конфигурации, сгенерированной resolvconf.
openresolv может подготовить конфигурации для dnsmasq, unbound, pdns, bind, если они используются как локальные DNS-серверы.
Конфигурация
/etc/resolvconf.conf — конфигурационный файл openresolv. По умолчанию он взаимодействует только с glibc. Если установлен другой резолвер, помимо glibc, потребуется настроить три переменные. Пример конфигурации для dnsmasq, pdns_recursor и именованных резолверов:
# Use the local name server
name_servers="127.0.0.1"
# If don't want to forward the root zone and let the local resolver
# recursively query the root servers directly,
# simply mark all interfaces private.
# You may need to do this if you enable DNSSEC in the local resolver but the
# upstream DNS servers say from your router or ISP don't support DNSSEC.
#private_interfaces="*"
# Write out dnsmasq extended configuration and resolv files
dnsmasq_conf=/etc/dnsmasq-conf.conf
dnsmasq_resolv=/etc/dnsmasq-resolv.conf
# Modify the pdnsd configuration file
pdnsd_conf=/etc/pdnsd.conf
# Write out PowerDNS Recursor forward zones file
pdns_zones=/etc/recursor-zones.conf
# Write out named extended configuration and zone files
named_options=/etc/namedb/resolvconf-options.conf
named_zones=/etc/namedb/resolvconf-zones.conf
# Write out unbound configuration file
unbound_conf=/etc/unbound-resolvconf.conf
Затем необходимо настроить резолвер для использования этих файлов.
Резолверы
openresolv поддерживает множество сторонних резолверов, когда glibc оказывается недостаточно.
bind
Пример простого локального резолвер файла для bind:
options {
# This directory is distribution dependent - it's commonly /etc/bind as well
directory "/etc/namedb";
listen-on {
127.0.0.1;
};
allow-recursion { localhost; localnets; };
include "resolvconf-options.conf";
};
include "resolvconf-zones.conf";
# The below options are only here for completeness.
# They are taken from the stock NetBSD install and may not
# apply to your distribution configuration.
zone "." {
type hint;
file "root.cache";
};
zone "localhost" {
type master;
file "localhost";
};
zone "127.IN-ADDR.ARPA" {
type master;
file "127";
};
zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" {
type master;
file "loopback.v6";
};
dnsmasq
Пример простого локального резолвер файла для dnsmasq:
domain-needed
interface=lo
# If dnsmasq is compiled for DBus then we can take
# advantage of not having to restart dnsmasq.
enable-dbus
conf-file=/etc/dnsmasq-conf.conf
resolv-file=/etc/dnsmasq-resolv.conf
pdnsd
Пример простого локального резолвер файла для pdnsd:
global {
server_ip = 127.0.0.1;
status_ctl = on;
}
server {
# A server definition is required, even if emtpy.
label="empty";
proxy_only=on;
# If this configuation is read-only then you can include a resolv.conf
# style file using the below directive if you enable pdnsd_resolv in resolvconf.conf
# file="/etc/pdnsd-resolv.conf";
}
PowerDNS Recursor
Пример простого локального резолвер файла для PowerDNS Recursor:
allow-from=127.0.0.0/8, ::1/128
forward-zones-file=/etc/recursor-zones.conf
unbound
Пример простого локального резолвер файла для unbound:
include: "/etc/unbound-resolvconf.conf"
server:
pidfile: "/var/run/unbound.pid"
# Allow reverse IPv4 local network queries
local-zone: "10.in-addr.arpa." nodefault
local-zone: "168.192.in-addr.arpa." nodefault
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»