Зачем вообще разбираться в DNS-цепочке Linux
Симптомы «медленного DNS» почти всегда одинаковые: SSH «думает» перед логином, apt/dnf подвисает на подключениях, приложения долго стартуют при обращении к доменным именам, а в логах мелькают Temporary failure in name resolution или необъяснимые задержки на 2–5–10 секунд. В поиске это часто выглядит как linux dns slow, dns timeout или «почему curl зависает до первого байта».
Проблема в том, что DNS в Linux — это не один файл /etc/resolv.conf, а цепочка компонентов:
- приложение вызывает резолвинг (обычно через
getaddrinfo()); - дальше работает
glibc+ NSS (логика из/etc/nsswitch.conf); - в зависимости от конфигурации запрос уходит либо напрямую на DNS-серверы, либо в локальный stub (часто
systemd-resolvedна127.0.0.53); - дальше уже идёт реальная сеть: локальный резолвер, провайдер, корпоративный DNS, VPN и т.д.
Если чинить не тот уровень, легко получить эффект «починил — через неделю снова сломалось»: например, вручную отредактировали /etc/resolv.conf, а NetworkManager или systemd-resolved перезаписали файл при переподключении сети.
Кто есть кто: glibc, NSS, nsswitch.conf и resolv.conf
glibc и NSS: почему nsswitch.conf важнее, чем кажется
Большинство программ в Linux не делают DNS-запросы самостоятельно. Они вызывают функции glibc (например, getaddrinfo()), а дальше вступает в дело NSS (Name Service Switch). NSS решает, где искать имя: в файлах, DNS, mDNS, LDAP, systemd и т.д. Порядок и правила задаются в /etc/nsswitch.conf.
Ключевая строка обычно выглядит так:
hosts: files dns
Но на системах с systemd-resolved часто встречается более «богатый» вариант:
hosts: files mymachines myhostname resolve [!UNAVAIL=return] dns
Здесь resolve означает «спросить у systemd-resolved через NSS-модуль», а dns — классический DNS-резолвинг (через /etc/resolv.conf).
Типичная причина задержек: когда в hosts: присутствуют лишние источники (например, mdns4_minimal, wins, LDAP), которые по сети «висят» и добавляют таймауты. Иногда задержку даёт и неправильный порядок: приложение сначала идёт в источник, который отвечает медленно или никогда, и только потом — в DNS.
/etc/resolv.conf — это часто «витрина», а не источник истины
Файл /etc/resolv.conf исторически содержит nameserver, search и options. Но на современных дистрибутивах он нередко является:
- симлинком на файл, который генерирует
systemd-resolved; - симлинком на файл, который генерирует NetworkManager;
- ручным файлом (обычно на минимальных серверах без «сетевых комбайнов»).
Важно: выражение «glibc resolv.conf» в контексте диагностики означает, что классический резолвер glibc читает настройки из /etc/resolv.conf. Но если nsswitch.conf направляет резолвинг в systemd-resolved, тогда /etc/resolv.conf может содержать stub 127.0.0.53, а реальная конфигурация будет храниться внутри resolved.

systemd-resolved: что делает и почему из-за него бывает «dns timeout»
systemd-resolved — локальный сервис резолвинга. Он умеет кешировать ответы, поддерживать split DNS (разные DNS для разных интерфейсов/VPN), работать с DNSSEC (валидация/попытки) и выступать локальным «stub resolver».
С ним связано два типичных класса проблем:
- неожиданный маршрут запроса: приложение думает, что использует один DNS, а реально запрос уходит в другой (например, через VPN-интерфейс);
- задержки на попытках: несколько серверов, fallback-логика, IPv6/IPv4, DNSSEC, недоступные адреса — всё это может суммироваться и выглядеть как dns timeout.
Как понять, используете ли вы systemd-resolved
Проверяем статус, привязку /etc/resolv.conf и текущую картину DNS:
systemctl status systemd-resolved
resolvectl status
ls -l /etc/resolv.conf
cat /etc/resolv.conf
Если видите nameserver 127.0.0.53 — это stub. В таком режиме не пытайтесь «угадывать правду» по самому /etc/resolv.conf: смотрите resolvectl status, там видно, какие DNS-серверы назначены, на каких интерфейсах, какие домены поиска активны, включён ли DNSSEC и т.д.
resolvectl: быстрые команды для диагностики
Полезный минимум:
resolvectl status
resolvectl query example.com
resolvectl query example.com --legend=yes
resolvectl statistics
Если запрос «висит», выполните его несколько раз подряд: если второй и третий раз заметно быстрее — кеш работает, а задержка была на сетевой части или на правилах поиска (search/ndots).
Самая частая причина «linux dns slow»: search + ndots + лишние попытки
Многие «магические» задержки DNS объясняются не сетью, а логикой резолвера: когда вы запрашиваете имя без точки (например, api или redis), система пытается дополнить его доменами из search и делает несколько запросов подряд. Ещё сильнее это проявляется из-за опции ndots.
Пример: есть search corp.local, а ndots выставлен в 5. Тогда имя example.com (две точки) может считаться «недостаточно полным» и сначала резолвиться как example.com.corp.local, а только потом как example.com. На каждом шаге возможны таймауты, особенно если внутренний DNS не отвечает или блокирует такие запросы.
Где смотреть ndots и search
В классическом варианте — в /etc/resolv.conf:
cat /etc/resolv.conf
В resolved-варианте — через resolvectl status по каждому интерфейсу: там будет видно домены (DNS Domain), которые фактически участвуют в поиске/маршрутизации запросов.
Как безопасно уменьшить задержки из-за ndots
Для серверов часто разумно держать ndots:1 (или ndots:2 в некоторых корпоративных схемах). Это снижает количество «лишних» запросов при обращении к публичным доменам.
Если система управляется resolved/NetworkManager, править /etc/resolv.conf вручную — обычно временная мера. Сначала зафиксируйте текущее поведение: какие домены поиска реально нужны, и какие запросы ломаются без них. После этого уже имеет смысл закреплять настройки в «источнике правды» (профиль подключения, настройка resolved, DHCP-опции).
Fallback DNS: когда помогает и когда только маскирует проблему
fallback dns — запасные DNS-серверы, к которым система обращается, если «основные» недоступны. В systemd-resolved они могут быть заданы глобально (как fallback) и/или на интерфейсе (как основные).
Это полезно для серверов: если вы держите проект на VDS и хотите переживать кратковременные сбои локального резолвера в датацентре. Но есть нюанс: fallback добавляет задержку, если основные серверы «полу-живые» (потери пакетов, редкие ответы). Тогда каждый запрос сначала ждёт таймаута на основном, а уже потом уходит на fallback.
Что делать практически:
- если основной DNS ненадёжен — лучше заменить его, а не надеяться на fallback;
- если DNS-серверов несколько — проверьте, что все адреса действительно доступны по сети (включая IPv6);
- не держите «мертвые» DNS в списке: они превращают любой резолвинг в лотерею с ожиданием таймаута.

Где в реальности рождается таймаут: чек-лист по слоям
1) Слой NSS: порядок источников и зависания
Посмотрите /etc/nsswitch.conf и строку hosts:. Если там есть источники, которые вам не нужны, это кандидат на задержки.
Минимально-предсказуемый вариант для многих серверов:
hosts: files dns
Но не применяйте его «вслепую»: на некоторых системах нужны resolve (чтобы работал resolved), myhostname (локальные имена) или специфичные источники корпоративной сети.
2) Слой systemd-resolved: split DNS и «не тот интерфейс»
Проверьте resolvectl status и убедитесь, что:
- DNS-серверы назначены ожидаемому интерфейсу;
- у VPN-интерфейса не стоит домен
~.(маршрутизация всего DNS через VPN), если вы этого не планировали; - домен поиска не раздувает количество попыток резолвинга.
Если есть подозрение на split DNS, сделайте тесты, чтобы понять «куда реально уходит» запрос:
resolvectl query example.com
resolvectl dns
resolvectl domain
3) Слой сети: доступность DNS и потери пакетов
DNS — это в основном UDP/53, иногда TCP/53 (например, при больших ответах/фрагментации или при форсировании). Проверьте базовую доступность сети и сам резолвинг через NSS:
ping -c 3 1.1.1.1
ping -c 3 8.8.8.8
getent hosts example.com
getent hosts — хороший «реальный» тест, потому что он проходит через NSS/глобальную конфигурацию, а не через утилиту, которая может использовать собственные библиотеки и обходные пути.
Практика: типовые сценарии и решения
Сценарий A: SSH/sudo «подвисают», а сайты/HTTP норм
Часто это обратные DNS-запросы (PTR) или попытки резолвинга имени хоста в процессе логина. Но в рамках этой статьи важен общий подход: проверьте, не добавляет ли NSS лишние источники, и не пытается ли система резолвить несуществующие имена через search.
Проверьте скорость резолвинга локального имени и внешнего домена:
getent hosts localhost
getent hosts $(hostname)
getent hosts example.com
Сценарий B: периодические «dns timeout» при деплое/в контейнерах
Если на хосте всё нормально, а в контейнерах случаются таймауты, убедитесь, что контейнеры получают рабочий resolv.conf и не наследуют «сломанный» stub без маршрута. Отдельно проверьте, не упираетесь ли в ограничение на DNS-пакеты и фрагментацию (особенно при EDNS0): тогда иногда случается переход на TCP и заметные задержки.
Для первичной проверки внутри контейнера достаточно:
cat /etc/resolv.conf
getent hosts example.com
Сценарий C: после подключения VPN всё стало медленно
Классика: VPN подменил DNS и добавил домены поиска. В результате публичные имена начинают сначала «примеряться» к внутренним суффиксам, а запросы уходят через медленный корпоративный резолвер.
Лечится не «ускорением DNS», а приведением split DNS к ожидаемой схеме: внутренние домены — через VPN, всё остальное — через обычный DNS. В терминах resolved это обычно означает аккуратную настройку доменов маршрутизации (например, только ~corp.local, а не ~.).
На что не тратить время: анти-паттерны при починке DNS
- Править
/etc/resolv.confвручную, не разобравшись, кто им управляет. Это часто даёт эффект «до перезагрузки» или «до переподключения сети». - Добавлять всё подряд в список DNS-серверов. Лишний DNS, который иногда не отвечает, делает резолвинг хуже, а не лучше.
- Игнорировать
nsswitch.conf. Можно иметь идеальный DNS-сервер, но получать задержки из-за порядка NSS-источников.
Короткий план диагностики «по-быстрому»
Понять путь: resolved или классический
glibcчерез/etc/resolv.conf.ls -l /etc/resolv.conf cat /etc/resolv.conf resolvectl statusПроверить NSS и порядок резолвинга.
grep -n '^hosts:' /etc/nsswitch.conf getent hosts example.comПроверить search/
ndotsи оценить количество лишних попыток.cat /etc/resolv.conf resolvectl statusСравнить скорость «с кешем» (повторный запрос) и «без» (первый запрос).
resolvectl query example.com resolvectl query example.com
Главная мысль: DNS-«тормоза» чаще всего появляются не из-за «плохого интернета», а из-за лишних попыток резолвинга (search/
ndots), недоступных DNS в списке или неправильного пути через NSS/systemd-resolved.
Итоги
Чтобы уверенно чинить DNS в Linux, держите в голове цепочку «приложение → glibc → NSS (nsswitch.conf) → systemd-resolved или прямой DNS по /etc/resolv.conf». Почти любой linux dns slow раскладывается на конкретные причины: лишние источники в hosts:, неудачный search, завышенный ndots, мёртвые DNS-серверы, агрессивный fallback или неожиданная split DNS-логика после VPN.
Если вы сначала определите, кто именно отвечает за резолвинг (resolved или нет), и проверите путь через resolvectl и getent, то «плавающие» dns timeout обычно становятся понятными и воспроизводимыми — а значит, исправляемыми.
Если параллельно решаете вопрос защищённого доступа к панелям/внутренним сервисам, не забудьте про SSL-сертификаты: это не ускорит DNS, но уберёт отдельный класс проблем вокруг доверия и безопасных подключений.


