Выберите продукт

systemd-resolved: NXDOMAIN, negative caching, TTL и DNSSEC (SERVFAIL) — диагностика и лечение

Частая проблема на Linux/VDS: внезапные NXDOMAIN в systemd-resolved, «залипание» из-за negative caching и stale cache, влияние SOA/TTL и типичные DNSSEC SERVFAIL. Пошаговая диагностика через resolvectl, логи и сброс кэша.
systemd-resolved: NXDOMAIN, negative caching, TTL и DNSSEC (SERVFAIL) — диагностика и лечение

Если на сервере с systemd внезапно «пропадает» домен и приложения получают NXDOMAIN, многие начинают подозревать провайдера DNS или сетевую проблему. На практике часто виноват локальный резолвер systemd-resolved: он кэширует не только успешные ответы, но и отрицательные (negative caching), а при DNSSEC может возвращать SERVFAIL. Ниже — практичная схема, как быстро отличить «реально нет записи» от «залип кэш» и понять, где ломается DNSSEC.

Что означает NXDOMAIN и почему он «залипает»

NXDOMAIN — это DNS-ответ «такого имени не существует». Важно: это не «не удалось спросить», а именно «в данной зоне имени/типа записи нет» (или резолвер получил отрицательный ответ и принял его как валидный).

Ключевой момент: отрицательные ответы тоже кэшируются. Механизм называется negative caching. Его цель — не создавать лишнюю нагрузку на авторитетные DNS запросами к заведомо несуществующим именам. Для администратора это выглядит так: «я только что создал запись, а сервер продолжает видеть NXDOMAIN».

Время «залипания» задаётся не TTL A/AAAA, а параметрами зоны: в отрицательном ответе используется SOA, и отрицательный кэш живёт согласно negative TTL (исторически это поле MINIMUM в SOA, в современных интерпретациях — TTL самого SOA). Поэтому «TTL» в истории с NXDOMAIN — это ещё и TTL для факта отсутствия записи.

Практическая ловушка: вы добавили A/AAAA, но до этого имя реально не существовало. Клиенты уже успели получить NXDOMAIN и закэшировали его на negative TTL. Пока таймер не истечёт (или вы не почистите кэш), изменения как будто не работают.

systemd-resolved как кэширующий резолвер: что именно он делает

systemd-resolved может работать как локальный stub на 127.0.0.53, как кэширующий резолвер с upstream DNS и как часть split-DNS (разные DNS для разных интерфейсов/доменов через networkd/NetworkManager). На практике это означает, что он:

  • кэширует ответы, включая negative caching;
  • может валидировать DNSSEC и отдавать SERVFAIL, если цепочка доверия не сходится;
  • иногда возвращает данные из устаревшего кэша (stale cache), когда upstream временно недоступен.

Из-за этого для приложений симптомы выглядят по-разному:

  • NXDOMAIN — «имени нет» (часто negative caching или реальная ошибка в зоне/делегировании);
  • SERVFAIL — «не смог получить валидный ответ» (часто DNSSEC или проблемы транспорта/EDNS0);
  • «то работает, то нет» — нередко признак нескольких upstream DNS с разным состоянием или split-DNS.

Вывод resolvectl status с DNS-серверами, DNSSEC и доменами поиска

Быстрый чек-лист: убедиться, что проблема именно в resolved

Сначала важно понять, кто именно резолвит на хосте и куда реально уходят запросы. Это экономит время: иногда приложения ходят не через stub, а напрямую на внешние DNS (например, в контейнерах), и тогда любые действия с resolved не помогут.

1) Проверяем, что приложения используют stub 127.0.0.53

ls -l /etc/resolv.conf
cat /etc/resolv.conf

Если /etc/resolv.conf указывает на 127.0.0.53 и содержит комментарий про stub resolver — запросы идут в systemd-resolved.

2) Смотрим статус и активные DNS-серверы

resolvectl status

В выводе обращайте внимание на:

  • DNS глобально и DNS по интерфейсам;
  • режим DNSSEC (disabled/allow-downgrade/yes);
  • DNS-over-TLS (если включён);
  • search domains и routing domains (критично для split-DNS).

3) Проверяем проблемное имя через resolvectl (а не «как-нибудь»)

resolvectl query example.com
resolvectl query -t A example.com
resolvectl query -t AAAA example.com

Так вы гарантированно проходите тем же путём, что и приложения, использующие resolved. Для сравнения: dig по умолчанию может идти мимо, если вы явно не указали сервер.

4) Снимаем статистику: кэш, промахи и намёки на нестабильный upstream

resolvectl statistics

Снимите статистику дважды: до и после серии запросов к проблемному имени. Если растут cache hits — ответ берётся из кэша. Если растут промахи/ошибки транзакций — upstream нестабилен или есть проблемы с маршрутизацией DNS.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Negative caching и DNS TTL: как оценить «время залипания» NXDOMAIN

Когда авторитетный DNS возвращает NXDOMAIN, резолвер получает отрицательный ответ и кэширует его на время, определённое SOA зоны. Это и есть практический смысл TTL в контексте NXDOMAIN: вы можете уже создать запись, но клиенты законно продолжают «помнить», что её не было.

Что делать администратору по шагам:

  1. Убедиться, что запись действительно появилась на авторитетных серверах (а не только «в панели», которая ещё не применила изменения).
  2. Оценить negative TTL зоны (по SOA) и, если вы управляете зоной, заранее уменьшать его перед массовыми изменениями/деплоями.
  3. На проблемной машине очистить кэш resolved и повторить запрос.

Если вы часто создаёте новые поддомены (staging/preview-окружения), слишком большой negative TTL делает опечатки и «не тот нейм» долгоиграющей проблемой.

Как сбросить кэш systemd-resolved

resolvectl flush-caches

После этого повторите запрос:

resolvectl query example.com

Если сразу «починилось» — почти наверняка вы упёрлись в negative caching (или в stale cache, если upstream был недоступен).

DNSSEC и SERVFAIL: почему «домен есть, но не открывается»

Вторая классическая история — не NXDOMAIN, а SERVFAIL при включённой DNSSEC-валидации. Для наблюдателя это выглядит так: имя существует, «у других» резолвится, но ваш сервер стабильно получает SERVFAIL.

Типовые причины:

  • у домена сломан DNSSEC (неверный DS в родительской зоне, неправильные подписи, рассинхрон ключей, просроченные подписи);
  • разные upstream DNS ведут себя по-разному (одни валидируют, другие нет), а resolved периодически выбирает «плохую» ветку;
  • проблемы транспорта: MTU/фрагментация/EDNS0. DNSSEC-ответы часто больше, UDP-пакеты чаще режутся, что превращается в таймауты и ошибки.

SERVFAIL при DNSSEC — это не «домена нет», а «ответ нельзя считать доверенным или не получилось корректно получить». Здесь обычно лечат либо цепочку доверия DNSSEC, либо транспорт/апстримы.

Где проверить режим DNSSEC в resolved

Сначала посмотрите режим в resolvectl status. Затем проверьте конфигурацию resolved:

grep -R "^DNSSEC" /etc/systemd/resolved.conf /etc/systemd/resolved.conf.d 2>/dev/null

Если сервер обслуживает прод, безопаснее не «отключать DNSSEC наугад», а стабилизировать upstream DNS и исправить DNSSEC на стороне домена. Если домен ваш, иногда проще и быстрее начать с проверки DS/ключей и сроков подписей, чем копать сеть.

FastFox VDS
Регистрация доменов от 99 руб.
Каждый проект заслуживает идеального доменного имени, выберите один из сотни, чтобы начать работу!

Stale cache: когда resolved отдаёт «устаревшее»

Stale cache — ситуация, когда резолвер временно возвращает данные из кэша даже после истечения TTL, потому что обновить запись у upstream не получается (таймауты, недоступность DNS, проблемы маршрутизации). Для доступности сервисов это иногда полезно, но при расследовании инцидента может сбивать с толку: вы «уже всё исправили», а сервер живёт прошлым.

Признаки, что дело похоже на stale cache или на нестабильный апстрим:

  • периодические таймауты до DNS-серверов;
  • в логах resolved появляются ошибки транзакций;
  • после resolvectl flush-caches вместо «старого ответа» вы получаете ошибку получения (потому что кэш выкинули, а upstream всё ещё недоступен).

Логи systemd-resolved с таймаутами и сообщениями DNSSEC validation failed

Логи systemd-resolved: быстро вытащить нужное из journald

journalctl -u systemd-resolved --since "1 hour ago" --no-pager

Ищите слова вроде timeout, DNSSEC, validation failed, degraded feature set, а также упоминания конкретных DNS-серверов и интерфейсов. Это часто сразу показывает, «кто» ломается: сеть, конкретный апстрим, DNSSEC или split-DNS.

Типовые сценарии и что делать (по шагам)

Сценарий A: «создал запись, но systemd-resolved всё ещё NXDOMAIN»

  1. Убедитесь, что запись реально появилась на авторитетных DNS.
  2. Оцените negative TTL зоны (SOA): сколько по правилам может жить отрицательный кэш.
  3. На сервере выполните:
resolvectl flush-caches
resolvectl query example.com
resolvectl statistics

Если после очистки запись появилась — это был negative caching. Если нет — проблема выше по цепочке (ошибка записи, делегирование, разные ответы авторитетных серверов).

Сценарий B: «иногда NXDOMAIN, иногда работает»

Частая причина — несколько upstream DNS с разным состоянием или split-DNS:

  • один DNS уже видит новую зону/запись, другой — ещё нет;
  • один отдаёт split-horizon (внутренний вид), другой — публичный;
  • один нестабилен или плохо проходит крупные ответы (особенно с DNSSEC).

Действия:

  1. Проверьте, какие DNS заданы глобально и по интерфейсам: resolvectl status.
  2. Временно зафиксируйте один заведомо корректный DNS (на уровне сети/интерфейса) и проверьте, исчезает ли «флаппинг».
  3. Перепроверьте search/routing domains: иногда запрос уходит «не в тот домен» из-за суффикса поиска.

Сценарий C: «DNSSEC SERVFAIL только на этом сервере»

  1. Проверьте режим DNSSEC в resolvectl status.
  2. Посмотрите логи systemd-resolved на ошибки валидации и таймауты.
  3. Если домен ваш — проверьте DS/ключи/сроки подписей (часто ломается после ротации).
  4. Если домен чужой — подтвердите гипотезу, переключив upstream DNS на стабильный валидирующий резолвер в вашей инфраструктуре.

Полезные команды для runbook (одним блоком)

resolvectl status
resolvectl query example.com
resolvectl query -t A example.com
resolvectl query -t AAAA example.com
resolvectl statistics
resolvectl flush-caches
journalctl -u systemd-resolved --since "2 hours ago" --no-pager

На что обратить внимание в проде: чтобы NXDOMAIN не ломал деплои

Если вы часто создаёте/переносите домены и поддомены (CI, staging, миграции), заложите это в процесс:

  • Планируйте TTL заранее: снижайте TTL и учитывайте negative TTL (SOA), иначе NXDOMAIN может «пережить» релиз.
  • Добавьте в runbook диагностику именно через resolvectl и явный шаг resolvectl flush-caches — это реально экономит часы.

Если тема кэширования в целом болит (не только в DNS), полезно держать под рукой разбор общих принципов TTL и валидации токенов в Nginx: secure_link, TTL и влияние кэша на доступ.

Итоги

Если вы видите systemd-resolved NXDOMAIN, это часто не «DNS сломан», а ожидаемое поведение кэша: negative caching плюс SOA TTL. Самый быстрый тест — resolvectl flush-caches и повторный запрос через resolvectl query. Если же вы ловите DNSSEC SERVFAIL, ищите проблему в DNSSEC-валидации или в транспорте (таймауты, EDNS0/MTU) и подтверждайте гипотезы логами systemd-resolved и статистикой resolvectl statistics.

Поделиться статьей

Вам будет интересно

FRR Linux: BGP multihoming, communities и защита от route leak — практический шаблон OpenAI Статья написана AI (GPT 5)

FRR Linux: BGP multihoming, communities и защита от route leak — практический шаблон

Собираем практичную конфигурацию FRR для eBGP multihoming с двумя аплинками: строгий экспорт только своих префиксов, импорт defaul ...
LVM cache (dm-cache) в Linux: ускоряем HDD с помощью SSD/NVMe без миграции данных OpenAI Статья написана AI (GPT 5)

LVM cache (dm-cache) в Linux: ускоряем HDD с помощью SSD/NVMe без миграции данных

LVM cache (dm-cache) позволяет подключить SSD/NVMe как кэш к медленному HDD-томy и ускорить I/O без переноса данных. Разберём cach ...
MongoDB на VDS: WiredTiger cache, journaling и quorum в replica set OpenAI Статья написана AI (GPT 5)

MongoDB на VDS: WiredTiger cache, journaling и quorum в replica set

Практика MongoDB в production на VDS: как выбрать WiredTiger cacheSizeGB с запасом для ОС, что даёт journaling и где он упирается ...