# systemd-resolved - локальный DNS-stub _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** systemd-resolved - DNS stub-resolver, слушает на `127.0.0.53:53` и проксирует запросы на upstream-DNS, агрегируя данные от NetworkManager/DHCP/VPN. Управляется `resolvectl`. ## Что это и зачем Раньше `/etc/resolv.conf` - обычный текстовый файл, в нём руками или через DHCP-клиент прописывались `nameserver`-строки. Проблемы старого подхода: - Только 3 nameserver-а максимум (по RFC). - Все интерфейсы делят один список - нет per-link DNS (важно для VPN). - Нет кеширования - каждый запрос в сеть. - Нет DNSSEC, DoT (DNS-over-TLS) из коробки. `systemd-resolved` - демон-стаб который решает это. Он слушает на адресе `127.0.0.53:53` (последний октет = 53, порт DNS) и: - Принимает запросы локальных приложений через `/etc/resolv.conf`. - Хранит **отдельные** конфиги DNS-серверов на каждый сетевой интерфейс (`enp0s3` идёт через ISP, `wg0` через VPN - резолв туда куда надо). - Кеширует ответы. - Поддерживает DNSSEC, DoT, LLMNR, mDNS. - Получает upstream-DNS от NetworkManager / systemd-networkd / DHCP. Базовый поток: ``` curl example.com ↓ (libc gethostbyname) /etc/resolv.conf → nameserver 127.0.0.53 ↓ (UDP к 127.0.0.53:53) systemd-resolved ↓ (выбирает интерфейс по routing'у, шлёт upstream) Внешний DNS (ISP / 8.8.8.8 / 1.1.1.1) ``` ## /etc/resolv.conf - это symlink На современных Ubuntu 22+/Fedora/RHEL 9+ файл - symlink: ```bash ls -l /etc/resolv.conf # → ../run/systemd/resolve/stub-resolv.conf ``` Содержит только `nameserver 127.0.0.53` плюс search-домены. Реальные upstream-DNS видны через `resolvectl`, не в этом файле. Есть два варианта target'а symlink'а: | Цель symlink'а | Поведение | |---------------------------------------------|---------------------------------| | `/run/systemd/resolve/stub-resolv.conf` | через `127.0.0.53` (default) | | `/run/systemd/resolve/resolv.conf` | прямо в upstream, без stub'а | | свой статичный `/etc/resolv.conf` | bypass systemd-resolved совсем | Если нужно вырубить resolved и вернуть "по-старому": ```bash sudo systemctl disable --now systemd-resolved sudo rm /etc/resolv.conf echo 'nameserver 1.1.1.1' | sudo tee /etc/resolv.conf # Но NetworkManager может перезаписать - отключить ему управление ``` ## resolvectl - главный инструмент ```bash resolvectl status # все link'и + upstream-DNS на каждом resolvectl query example.com # резолв через resolved (как dig, но через stub) resolvectl statistics # cache hits/misses resolvectl flush-caches # сбросить кеш resolvectl dns enp0s3 1.1.1.1 9.9.9.9 # задать DNS на конкретный интерфейс resolvectl domain wg0 '~corp.local' # split-DNS: только запросы corp.local через wg0 ``` Префикс `~` в домене = **routing-only** (использовать этот link только для таких доменов). Без `~` - обычный search-домен. ## Конфигурация - /etc/systemd/resolved.conf Глобальные настройки. Не редактировать сам файл - использовать drop-in: ```ini # /etc/systemd/resolved.conf.d/dns.conf [Resolve] DNS=1.1.1.1#cloudflare-dns.com 9.9.9.9 FallbackDNS=8.8.8.8 Domains=~. # все запросы через DNS= (а не per-link) DNSSEC=allow-downgrade DNSOverTLS=opportunistic Cache=yes ``` После правки: ```bash sudo systemctl restart systemd-resolved resolvectl status # проверить что подхватилось ``` Drop-in (см. [systemd-drop-ins](/kb/systemd-drop-ins.md)) важен потому что пакетные обновления могут перезаписать `/etc/systemd/resolved.conf`. ## /etc/nsswitch.conf - порядок резолверов Резолв имени проходит через цепочку из `nsswitch.conf`: ``` hosts: files myhostname mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns ``` Слева направо: 1. `files` → `/etc/hosts` (статические записи) 2. `myhostname` → имя самого хоста + localhost 3. `mdns4_minimal` → Avahi/mDNS для локальной сети 4. `resolve` → systemd-resolved через D-Bus (быстро, поддерживает DNSSEC) 5. `dns` → fallback на классический glibc-resolver через `/etc/resolv.conf` Если cross-проверка не нужна и хочется только resolved - оставить `files resolve [!UNAVAIL=return] dns`. Менять nsswitch обычно не надо, но это первое что смотришь при «host пингается, а dig не находит» (или наоборот). ## DNSSEC, DoT, LLMNR - что включать - **DNSSEC** - валидация подписей DNS-зон. `DNSSEC=allow-downgrade` - разумный дефолт: пытается, но не ломает резолв если upstream не умеет. - **DNSOverTLS** - шифрование DNS-трафика до upstream-сервера. `opportunistic` - попробовать TLS, fallback на plain. Для гарантий нужен upstream который реально умеет (1.1.1.1, 9.9.9.9). - **LLMNR** - link-local multicast, замена WINS. Для домашних сетей. Шумный, можно выключить (`LLMNR=no`). - **MulticastDNS** - `.local` имена в локалке. Если стоит Avahi - отключить в resolved (`MulticastDNS=no`) чтобы не дублировать. ## Дебаг - почему не резолвится ```bash resolvectl status # какие upstream'ы на каком link'е resolvectl query --cache=no example.com # обход кеша journalctl -u systemd-resolved -f # стрим логов резолвера sudo resolvectl log-level debug # подробный лог ss -ulnp 'sport = :53' # кто реально слушает 53 dig @127.0.0.53 example.com # обращение прямо в stub ``` Типичные проблемы: - **Пустой DNS Servers в `resolvectl status`** - NetworkManager не отдал; проверить `nmcli dev show | grep DNS`. - **Резолвится через `dig` но не через приложение** - приложение не использует libc, читает `/etc/resolv.conf` сам и видит `127.0.0.53`, но glibc-кеш пуст. Перезапустить приложение. - **VPN сломал DNS** - VPN-клиент перезаписал `/etc/resolv.conf` поверх symlink'а. Использовать `resolvectl domain wg0 '~.'` вместо подмены файла. ## Команды ```bash resolvectl status ``` Главный обзор: какие DNS-сервера, на каких link'ах, какие протоколы активны ```bash resolvectl query example.com ``` Резолв через resolved (показывает кеш-хит, link, время) - точнее чем dig ```bash sudo resolvectl flush-caches ``` Сбросить кеш - после смены upstream'а или для теста ```bash resolvectl domain wg0 '~corp.local' ``` Split-DNS: только запросы corp.local идут через VPN-интерфейс ```bash journalctl -u systemd-resolved -f ``` Live-логи резолвера - увидеть DNSSEC-фейлы, timeouts, отвалившиеся upstream'ы ## См. также - [systemd - init и менеджер сервисов](/kb/systemd.md) - [DNS resolution](/kb/dns-resolution.md) - [BIND - авторитативный/кеширующий DNS-сервер](/kb/bind-dns-server.md) - [journalctl - журнал systemd](/kb/cmd-journalctl.md) - [chrony и NTP - синхронизация времени](/kb/chrony-and-ntp.md)