Если на сервере с 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.

Быстрый чек-лист: убедиться, что проблема именно в 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.
Negative caching и DNS TTL: как оценить «время залипания» NXDOMAIN
Когда авторитетный DNS возвращает NXDOMAIN, резолвер получает отрицательный ответ и кэширует его на время, определённое SOA зоны. Это и есть практический смысл TTL в контексте NXDOMAIN: вы можете уже создать запись, но клиенты законно продолжают «помнить», что её не было.
Что делать администратору по шагам:
- Убедиться, что запись действительно появилась на авторитетных серверах (а не только «в панели», которая ещё не применила изменения).
- Оценить negative TTL зоны (по SOA) и, если вы управляете зоной, заранее уменьшать его перед массовыми изменениями/деплоями.
- На проблемной машине очистить кэш 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/ключей и сроков подписей, чем копать сеть.
Stale cache: когда resolved отдаёт «устаревшее»
Stale cache — ситуация, когда резолвер временно возвращает данные из кэша даже после истечения TTL, потому что обновить запись у upstream не получается (таймауты, недоступность DNS, проблемы маршрутизации). Для доступности сервисов это иногда полезно, но при расследовании инцидента может сбивать с толку: вы «уже всё исправили», а сервер живёт прошлым.
Признаки, что дело похоже на stale cache или на нестабильный апстрим:
- периодические таймауты до DNS-серверов;
- в логах resolved появляются ошибки транзакций;
- после
resolvectl flush-cachesвместо «старого ответа» вы получаете ошибку получения (потому что кэш выкинули, а upstream всё ещё недоступен).

Логи 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»
- Убедитесь, что запись реально появилась на авторитетных DNS.
- Оцените negative TTL зоны (SOA): сколько по правилам может жить отрицательный кэш.
- На сервере выполните:
resolvectl flush-caches
resolvectl query example.com
resolvectl statistics
Если после очистки запись появилась — это был negative caching. Если нет — проблема выше по цепочке (ошибка записи, делегирование, разные ответы авторитетных серверов).
Сценарий B: «иногда NXDOMAIN, иногда работает»
Частая причина — несколько upstream DNS с разным состоянием или split-DNS:
- один DNS уже видит новую зону/запись, другой — ещё нет;
- один отдаёт split-horizon (внутренний вид), другой — публичный;
- один нестабилен или плохо проходит крупные ответы (особенно с DNSSEC).
Действия:
- Проверьте, какие DNS заданы глобально и по интерфейсам:
resolvectl status. - Временно зафиксируйте один заведомо корректный DNS (на уровне сети/интерфейса) и проверьте, исчезает ли «флаппинг».
- Перепроверьте search/routing domains: иногда запрос уходит «не в тот домен» из-за суффикса поиска.
Сценарий C: «DNSSEC SERVFAIL только на этом сервере»
- Проверьте режим DNSSEC в
resolvectl status. - Посмотрите логи
systemd-resolvedна ошибки валидации и таймауты. - Если домен ваш — проверьте DS/ключи/сроки подписей (часто ломается после ротации).
- Если домен чужой — подтвердите гипотезу, переключив 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.


