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

Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND

Если локальный DNS в Debian или Ubuntu не стартует с ошибкой address already in use, причина часто в systemd-resolved и DNSStubListener на 127.0.0.53. Разберём, как найти конфликт, проверить resolv.conf и собрать устойчивую схему.
Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND

На Debian и Ubuntu одна из самых частых причин проблем с локальным DNS — не сам dnsmasq, unbound или bind9, а служба systemd-resolved. Она может поднимать локальный stub-resolver на адресе 127.0.0.53:53, из-за чего другой DNS-демон уже не может занять порт 53 на loopback или на нужном интерфейсе.

В результате вы видите знакомые сообщения вроде address already in use, а затем начинаются хаотичные попытки переписать /etc/resolv.conf, перенести сервис на другой адрес или отключить всё подряд. Обычно это только усложняет картину.

Проблема неприятна тем, что система может выглядеть почти рабочей: apt то резолвит имена, то нет, локальный кэширующий резолвер стартует через раз, а контейнеры и сам хост используют разные DNS-цепочки. Если не понять архитектуру, получается классический зоопарк из нескольких DNS-компонентов.

Разберём, что именно делает systemd-resolved, зачем ему нужен DNSStubListener, почему используется адрес 127.0.0.53, как диагностировать конфликт и как выбрать нормальную схему работы с dnsmasq, unbound или bind9 на сервере Debian/Ubuntu.

Что такое systemd-resolved и почему он слушает 127.0.0.53

systemd-resolved — это системный сервис резолвинга имён. Он умеет принимать локальные DNS-запросы, кэшировать ответы, использовать разные upstream DNS-серверы и интегрироваться с сетевыми компонентами системы. В Ubuntu он часто включён по умолчанию, а в Debian его поведение зависит от версии и профиля установки.

Когда включён параметр DNSStubListener, служба слушает локальный адрес 127.0.0.53 на порту 53. Обычно в /etc/resolv.conf при этом прописывается nameserver 127.0.0.53, и приложения отправляют запросы туда, а уже systemd-resolved пересылает их на реальные DNS-серверы.

Сам адрес 127.0.0.53 не является ошибкой. Конфликт начинается только тогда, когда другой DNS-сервис тоже пытается слушать порт 53 на том же хосте.

Типичный сценарий: вы ставите dnsmasq как локальный кэш, unbound как validating resolver или bind9 для форвардинга и локальных зон. Сервис не стартует, потому что часть DNS-сокетов уже занята systemd-resolved.

Как проявляется конфликт DNSStubListener

Симптомы обычно однотипны: служба не запускается после установки или после изменения конфигурации, в логе есть ошибка привязки адреса, а команда диагностики показывает активный listener на 127.0.0.53:53.

  • не стартует dnsmasq, unbound или bind9;
  • в журнале есть address already in use;
  • ss или lsof показывают слушатель на порту 53;
  • /etc/resolv.conf указывает на 127.0.0.53, хотя вы рассчитывали использовать 127.0.0.1;
  • после отключения одного сервиса резолвинг ломается полностью.

Сначала проверьте, кто именно занял порт 53:

ss -ltnup '( sport = :53 )'
ss -lnup | grep ':53'
lsof -i :53 -nP

Затем проверьте статус резолвера и текущую схему:

systemctl status systemd-resolved
resolvectl status
readlink -f /etc/resolv.conf
cat /etc/resolv.conf

Если видите systemd-resolved на 127.0.0.53:53, а /etc/resolv.conf ведёт на stub-файл, значит у вас активна стандартная схема со stub listener.

Проверка слушателей DNS на порту 53 в Linux через системные утилиты

Главная ошибка: держать два локальных резолвера на одном порту

Суть конфликта проста: на одном IP и одном порту не могут одновременно слушать два процесса. Поэтому схема «оставлю включённым systemd-resolved и рядом подниму unbound или dnsmasq на localhost:53» почти всегда заканчивается проблемой.

Нужно не лечить симптом, а выбрать одну рабочую архитектуру:

  • оставить systemd-resolved как локальный stub, а второй DNS-сервис слушать на другом адресе или порту;
  • отключить только DNSStubListener, но оставить сам systemd-resolved в системе;
  • полностью отключить systemd-resolved и отдать роль локального DNS другому демону;
  • запустить альтернативный резолвер только на конкретном интерфейсе без пересечения по адресам.

Правильное решение зависит от роли сервера. Для простого кэша достаточно одного DNS-компонента, а для валидации DNSSEC, форвардинга или локальных зон уже нужен осознанный выбор между unbound, dnsmasq и bind9.

Если вы разворачиваете инфраструктуру на VDS, такую схему лучше определить сразу после базовой установки системы. Тогда и отладка, и автоматизация будут заметно проще.

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

Вариант 1: отключить только DNSStubListener

Это самый аккуратный путь, если вам нужен dnsmasq, unbound или bind9 на localhost:53, но вы не хотите полностью удалять или отключать systemd-resolved.

Откройте конфигурацию:

sudo editor /etc/systemd/resolved.conf

Добавьте или измените параметр:

[Resolve]
DNSStubListener=no

После этого перезапустите службу:

sudo systemctl restart systemd-resolved
ss -lnup | grep ':53'

Но здесь есть важный нюанс: после отключения stub listener нужно проверить, куда теперь указывает /etc/resolv.conf. Если он всё ещё ссылается на файл с nameserver 127.0.0.53, резолвинг сломается.

Один из безопасных вариантов — направить /etc/resolv.conf на runtime-файл systemd-resolved с реальными upstream DNS:

sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
readlink -f /etc/resolv.conf
cat /etc/resolv.conf

Если же вы хотите, чтобы система ходила в ваш локальный резолвер, тогда в /etc/resolv.conf должен быть указан уже адрес этого сервиса, например 127.0.0.1.

Вариант 2: полностью отключить systemd-resolved

Такой путь часто выбирают на серверах, где DNS должен быть полностью предсказуемым и управляться только через dnsmasq, unbound или bind9. На минимальных установках это часто проще сопровождать.

Базовая последовательность выглядит так:

sudo systemctl disable --now systemd-resolved
sudo rm -f /etc/resolv.conf
sudo editor /etc/resolv.conf

Затем создайте обычный файл, например:

nameserver 127.0.0.1
options edns0 trust-ad

После этого запускайте ваш DNS-демон и проверяйте, что он реально отвечает на запросы.

У этого варианта есть нюанс: некоторые компоненты сети могут ожидать наличие systemd-resolved или пытаться перегенерировать DNS-настройки. Поэтому после отключения проверьте, кто у вас управляет сетью: systemd-networkd, Netplan, NetworkManager, cloud-init или свои скрипты.

Как настроить dnsmasq без конфликта

dnsmasq часто используют как лёгкий кэширующий DNS с локальными записями. Если он должен стать основным резолвером на сервере, лучше заранее отключить stub listener или сам systemd-resolved.

Минимальная конфигурация может выглядеть так:

listen-address=127.0.0.1
bind-interfaces
no-resolv
server=1.1.1.1
server=8.8.8.8
cache-size=1000

После настройки проверьте запуск:

sudo systemctl restart dnsmasq
sudo systemctl status dnsmasq
dig @127.0.0.1 example.org
getent hosts example.org

Если хотите использовать локальные записи и кэш, но без лишнего усложнения, dnsmasq обычно достаточно. Главное — не смешивать его с другим локальным резолвером без чёткой необходимости.

Настройка локального DNS-резолвера на сервере Debian или Ubuntu

Как настроить Unbound без конфликта

Unbound удобен, когда нужен validating resolver с DNSSEC, понятной моделью кэширования и предсказуемой серверной логикой. На Debian и Ubuntu это один из самых популярных вариантов для локального DNS на хосте.

Базовые параметры выглядят примерно так:

server:
    interface: 127.0.0.1
    port: 53
    do-ip4: yes
    do-udp: yes
    do-tcp: yes
    access-control: 127.0.0.0/8 allow

Проверка после настройки:

unbound-checkconf
sudo systemctl restart unbound
sudo systemctl status unbound
dig @127.0.0.1 example.org
getent hosts example.org

Если systemd-resolved ещё остаётся в системе, полезно дополнительно проверить, не указывает ли /etc/resolv.conf на старый stub listener. Именно здесь чаще всего и прячется причина странного поведения.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Как настроить bind9 без конфликта

bind9 нужен там, где кроме обычного резолвинга требуются локальные зоны, ACL, forwarding, recursion и более классическая DNS-архитектура. Но и у него тот же принцип: если named должен занять 53-й порт, никто другой не должен держать этот сокет.

Пример базовой конфигурации прослушивания:

options {
    directory "/var/cache/bind";
    listen-on { 127.0.0.1; };
    listen-on-v6 { ::1; };
    recursion yes;
    allow-query { localhost; };
};

Проверка:

sudo named-checkconf
sudo systemctl restart bind9
sudo systemctl status bind9
ss -lnup | grep ':53'
dig @127.0.0.1 example.org

Если BIND должен обслуживать не только локальный хост, а ещё и сеть, указывайте нужные адреса явно и не оставляйте прослушивание на всех интерфейсах без необходимости.

Что делать с resolv.conf, чтобы не сломать DNS после фикса

Самая частая вторая ошибка после освобождения порта 53 — забыть про /etc/resolv.conf. Сервис уже стартует, а система продолжает спрашивать DNS у старого адреса.

Здесь полезно мыслить очень просто: /etc/resolv.conf должен указывать туда, где реально доступен рабочий DNS-сервис для приложений.

  • nameserver 127.0.0.53 — когда используется активный stub listener от systemd-resolved;
  • nameserver 127.0.0.1 — когда основной локальный резолвер это dnsmasq, unbound или bind9;
  • внешние DNS-серверы — когда локального резолвера на машине нет.

Если после изменения схемы всё как будто работает по-старому, это ещё не победа. Часто оказывается, что приложения по-прежнему используют старый resolv.conf, а новый локальный DNS вообще не участвует в цепочке.

Если на сервере используются свои зоны, внешние записи и сертификаты, DNS лучше держать в полностью предсказуемом состоянии. В смежной теме может пригодиться материал про автоматизацию wildcard SSL через DNS-01, где корректный локальный и внешний DNS особенно важен.

Быстрый алгоритм диагностики

Если локальный DNS-демон падает с address already in use, пройдите короткий чек-лист:

  1. Проверьте, кто слушает порт 53 через ss или lsof.
  2. Посмотрите статус systemd-resolved.
  3. Проверьте, куда указывает /etc/resolv.conf.
  4. Определите, кто должен быть главным DNS-компонентом на сервере.
  5. Либо отключите DNSStubListener, либо полностью выключите systemd-resolved.
  6. Приведите resolv.conf в соответствие новой схеме.
  7. Проверьте запросы через dig и getent.

Этот порядок почти всегда быстрее бессистемного редактирования конфигов и помогает не получить ситуацию, когда демон стартует, но система его не использует.

Какую схему выбрать на практике

Нужен просто стабильный локальный кэш

Обычно достаточно либо systemd-resolved, либо dnsmasq. Два локальных резолвера одновременно чаще мешают, чем помогают.

Нужен validating resolver и предсказуемое поведение

Чаще всего лучше выбрать unbound и отключить stub listener либо сам systemd-resolved.

Нужны локальные зоны и классический DNS-серверный стек

Тогда логичен bind9, особенно если нужно явно разделять рекурсию, форвардинг и авторитативные зоны.

Это минимальный сервер без desktop-компонентов

Чем меньше скрытой автоматизации, тем проще сопровождение. Поэтому на сервере удобнее одна ясная DNS-схема без наложения ролей.

На практике это особенно заметно на проектах, размещённых на виртуальном хостинге или на отдельном сервере, где любой сетевой сбой сразу отражается на приложении. Понятный DNS-стек экономит время и при отладке, и при миграциях.

Итог

Конфликт systemd-resolved с dnsmasq, unbound или bind9 — типовая история для Debian и Ubuntu. Корень проблемы почти всегда один: активный DNSStubListener занимает 127.0.0.53:53, а второй DNS-сервис пытается слушать тот же порт или пересекающийся адрес.

Правильный путь — выбрать одну понятную архитектуру. Либо оставляете systemd-resolved и не поднимаете рядом второй локальный резолвер на том же порту, либо отключаете DNSStubListener, либо полностью переходите на dnsmasq, unbound или bind9. И обязательно синхронизируете это с /etc/resolv.conf.

Если запомнить только одну мысль, то она такая: ошибка address already in use у DNS-демона почти всегда начинается с двух вопросов — кто сейчас слушает порт 53 и куда указывает /etc/resolv.conf. Ответ на них обычно и даёт половину решения.

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

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

Debian/Ubuntu: как исправить NFS mount.nfs: access denied by server while mounting OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить NFS mount.nfs: access denied by server while mounting

Ошибка mount.nfs: access denied by server while mounting в Debian и Ubuntu обычно указывает на проблему на стороне NFS-сервера: не ...
Debian/Ubuntu: как устранить конфликт systemd-resolved DNSStubListener с BIND9, dnsmasq и AdGuard Home OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как устранить конфликт systemd-resolved DNSStubListener с BIND9, dnsmasq и AdGuard Home

Если в Debian или Ubuntu DNS-сервер не стартует из-за ошибки port 53 busy, часто причина в systemd-resolved с локальным слушателем ...
Debian/Ubuntu: как исправить Device is busy у Docker network, volume и namespace OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Device is busy у Docker network, volume и namespace

Если Docker на Debian или Ubuntu отвечает Device is busy при удалении сети, тома или namespace, причина обычно в живом процессе, о ...