АйТи Фреш
Главная / Статьи / Сети
Сети

Почему dig находит хост в зоне .local, а Linux-приложения его не открывают

Автор: Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш» · · ~26 мин чтения
Почему dig находит хост в зоне .local, а Linux-приложения его не открывают
Иллюстрация к статье «Почему dig находит хост в зоне .local, а Linux-приложения его не открывают».

С этим ко мне приходят раз в пару месяцев. Внутренний портал живёт по адресу app01.corp.local. С Windows-станций открывается. С Linux-станции `dig app01.corp.local @10.20.0.10` отдаёт правильный A-адрес за пару миллисекунд, а `ping` того же имени говорит «Name or service not known», браузер — «сервер не найден». Админ идёт править зону на контроллере домена, перезапускает службу DNS и злится. Зона не при чём. Ниже разбираю, почему dig и обычное приложение идут к имени разными дорогами, что systemd-resolved и Avahi делают с суффиксом .local, как это диагностировать за пять минут и как чинить — от разового костыля до стратегического ухода с .local.

dig ничего не доказывает: он вообще не тот путь проверяет

Первое, что нужно принять: dig, nslookup и host — это самостоятельные DNS-клиенты. Они формируют DNS-пакет сами и отправляют его на UDP/53 напрямую. Файл /etc/resolv.conf они читают только чтобы узнать адрес сервера, а если вы написали @10.20.0.10, то не читают и его. Ни одна из этих утилит не обращается к системному механизму разрешения имён. Поэтому успешный ответ dig доказывает ровно одно: на DNS-сервере запись есть и сервер по сети доступен. Про то, как имя будет разрешать браузер, ничего не доказывает.

Обычное приложение — Chrome, curl, psql, java, ваш самописный сервис — зовёт getaddrinfo(3) из glibc. А тот идёт по цепочке модулей, описанной в /etc/nsswitch.conf, строка hosts. Это и есть тот путь, который надо проверять. Правильный «тест приложения» — не dig, а getent:

grep '^hosts' /etc/nsswitch.conf
getent hosts app01.corp.local     # так видит имя приложение
dig +short app01.corp.local @10.20.0.10   # так видит имя админ

Если dig отвечает, а getent молчит — вопрос закрыт: DNS-сервер и зона исправны, ломается разрешение имени на клиенте. Дальше остаётся выяснить, какой механизм перехватил запрос. Здесь дистрибутивы расходятся. Мануал nss-resolve(8) рекомендует строку hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns, и Fedora ставит модуль resolve в hosts-строку штатно: запрос уходит в systemd-resolved, а приписка [!UNAVAIL=return] означает, что при работающей службе её отрицательный ответ окончательный и до dns дело не доходит. Ubuntu на десктопной установке идёт другим путём: в hosts-строке обычно files mdns4_minimal [NOTFOUND=return] dns, а /etc/resolv.conf — симлинк на stub-resolv.conf с единственным сервером 127.0.0.53. То есть классический nss-dns отправляет пакет в тот же systemd-resolved, только через stub-listener. Правила маршрутизации к таким запросам применяются те же самые, поэтому итог для .local одинаковый. Точную строку на своей машине всегда смотрите сами — после обновлений и установки пакетов она меняется.

Если в hosts-строке стоит `resolve [!UNAVAIL=return]` или /etc/resolv.conf указывает на stub 127.0.0.53, то адреса DNS-серверов в resolv.conf ничего не решают: запрос в любом случае проходит через systemd-resolved и его правила маршрутизации. Вписать туда адрес контроллера руками — не лечение, а способ получить конфиг, который перезапишут при следующем переподключении. Я на этом когда-то потерял несколько часов и не хочу, чтобы вы повторяли.

Почему .local — заминированный суффикс

Суффикс .local зарезервирован RFC 6762 за Multicast DNS. Это не рекомендация «по этикету», а нормативное резервирование, и systemd-resolved соблюдает его буквально. Мануал systemd-resolved.service(8) формулирует прямо: многокомпонентные имена с суффиксом .local разрешаются через MulticastDNS на всех локальных интерфейсах, где MulticastDNS включён. И тут же вторая половина, ради которой всё и написано: по умолчанию запросы к доменам с суффиксом .local не направляются на DNS-серверы, если домен не задан явно как routing- или search-домен.

Прочитайте это ещё раз. Не «сначала попробуем DNS, потом mDNS». Не «попробуем оба». А «на обычный DNS вообще не пойдём». Ваш контроллер домена с идеальной зоной corp.local просто не спрашивают. Более того, мануал отдельно замечает, что сегодня заводить .local на DNS-сервере в целом не рекомендуется, потому что RFC 6762 резервирует этот домен исключительно под Multicast DNS. Microsoft говорит то же самое со своей стороны: в руководстве по выбору корневого домена леса на learn.microsoft.com прямо написано, что использовать незарегистрированные суффиксы вроде .local не рекомендуется, а в статье об именовании доменов (бывшая KB 909264) — что стоит избегать имён, занятых интернет-стандартными механизмами, и .local приведён как пример.

Откуда тогда взялись тысячи доменов corp.local и office.local? Из мастеров установки Small Business Server и Active Directory середины двухтысячных, где .local предлагался как безопасный вариант «не публичного» имени. Пока парк чисто виндовый, всё тихо: DNS-клиент Windows про RFC 6762 в этой части не переживает и спокойно спрашивает корпоративный DNS. Проблема вылезает ровно в тот день, когда в сети появляется первая Linux-станция, Mac или контейнер.

И это не единственная беда .local. mDNS работает через мультикаст на 224.0.0.251:5353 (и ff02::fb для IPv6) и через маршрутизатор не проходит. Значит, даже если mDNS «поймает» имя, поймает он его только в своём широковещательном домене. Хост в соседнем VLAN не найдётся никогда — а именно так обычно и живут серверы: в отдельном сегменте. Плюс к тому публичный сертификат на имя в .local не выпустит ни один удостоверяющий центр, цепочку доверия DNSSEC до такой зоны не построить, а SRV-записи вроде _ldap._tcp корпоративная инфраструктура через mDNS не публикует.

Ключевой факт из мануала: «lookups for domains with the .local suffix are not routed to DNS servers, unless the domain is specified explicitly as routing or search domain». Пока вы не объявили зону явно — корпоративный DNS про неё даже не спросят.
Почему dig находит хост в зоне .local, а Linux-приложения его не открывают — схема
Схема к статье. Открыть схему в полном размере

Разбор из практики: инкубатор «Бизнес-трамплин», 21 рабочее место

Инкубатор стартапов: общий офис с коворкингом, 21 рабочее место — администрация, менеджеры программ и столы резидентов. Домен AD corp.local подняли много лет назад «по мастеру», сейчас два контроллера на Windows Server 2019 (10.20.0.10 и 10.20.0.12). На внутреннем сервере 10.20.0.11 крутится портал бронирования переговорок и учёта резидентов по адресу app01.corp.local, рядом веб-интерфейс мониторинга на mon.corp.local. Сотрудники администрации работают на Windows, а у резидентов-разработчиков стоят четыре станции Ubuntu 24.04 и две Fedora. Серверный сегмент 10.20.0.0/24, пользовательский 10.20.10.0/24, между ними маршрутизатор.

Заявка пришла обычная: «после переустановки системы не открывается портал бронирования, а у соседа на Windows открывается». Подключились удалённо, посмотрели. С Ubuntu 24.04: dig +short app01.corp.local @10.20.0.10 → 10.20.0.11, время ответа 1 мс. ping app01.corp.local → Name or service not known. getent hosts app01.corp.local → пусто. То есть классика из первого раздела, и падало это почти мгновенно, из-за чего все и решили, что «записи нет».

Смотрим resolvectl status. На линке enp1s0 стоят DNS-серверы 10.20.0.10 и 10.20.0.12 (пришли по DHCP), строки DNS Domain: нет вовсе — DHCP-сервер суффикс не раздавал. В строке Protocols: на Ubuntu-станциях было -mDNS, на одной из Fedora — +mDNS, но разницы в симптоме это не давало. Дальше resolvectl query app01.corp.local: на Ubuntu сразу «No appropriate name servers or networks for name found», на Fedora — то же отрицательное решение после короткой паузы на мультикаст-опрос. Всё сходится: имя многокомпонентное, суффикс .local, routing- или search-домена для corp.local нет — на 10.20.0.10 запрос просто не пошёл, а в эфире такого имени никто не объявляет.

Второй слой сюрприза нашёлся на Ubuntu-станциях. Там стоял libnss-mdns — приехал зависимостью вместе с avahi-daemon и подсистемой печати, в /etc/nsswitch.conf строка hosts: files mdns4_minimal [NOTFOUND=return] dns. На app01.corp.local он не влиял: имя из трёх меток, а nss-mdns по своей эвристике отказывается обслуживать .local-имена длиннее двух меток и пропускает их дальше по цепочке. Зато ломал обращения к самому corp.local — к DFS-пространству \\corp.local\files и при проверке домена через getent hosts corp.local. Это имя из двух меток, модуль его берёт, SOA для верхнеуровневого local через DNS не получает (resolved такой запрос тоже не маршрутизирует), уходит в мультикаст, ничего не находит и отдаёт NOTFOUND, а [NOTFOUND=return] останавливает цепочку. Два независимых механизма, и починка одного второй не лечит.

Чинили так: на всех шести Linux-станциях объявили corp.local search-доменом в профиле NetworkManager и выключили mDNS на уровне соединения, а на Ubuntu убрали mdns4_minimal из hosts-строки (avahi-daemon оставили — через него находится принтер в коворкинге, но NSS-модуль для этого не нужен). Проверка getent hosts app01.corp.local, getent hosts corp.local и resolvectl query mon.corp.local — все отдают адрес, в хвосте вывода query появилась строка о том, что информация получена по протоколу DNS. Работы на весь парк — около 25 минут вместе с проверками. Отдельной задачей в план ушёл вопрос ухода с .local для новых сервисов — про это в последнем разделе.

Обратите внимание на скорость отказа. Когда имя не находится за доли секунды, все автоматически думают «записи нет». Настоящий таймаут недоступного DNS-сервера выглядит как несколько секунд ожидания. Мгновенное «No appropriate name servers or networks» от resolved на .local-имя — признак того, что запрос никуда не отправлялся: маршрута нет, а сервер тут ни при чём.
Цифры и версии: Разбор из практики: инкубатор «Бизнес-трамплин», 21 рабочее место — схема
Цифры и версии: Разбор из практики: инкубатор «Бизнес-трамплин», 21 рабочее место. Открыть схему в полном размере

Диагностика за пять минут: шесть команд

Порядок, которым я пользуюсь на выезде. Он же годится, чтобы отдать его младшему инженеру и не объяснять теорию.

# 1. Что реально в цепочке NSS и куда смотрит resolv.conf
grep '^hosts' /etc/nsswitch.conf
ls -l /etc/resolv.conf

# 2. Путь приложения против пути админа
getent hosts app01.corp.local
dig +short app01.corp.local @10.20.0.10

# 3. Что думает systemd-resolved: DNS на линке, домены, строка Protocols
resolvectl status

# 4. Запрос глазами resolved; легенда (по умолчанию включена) покажет протокол
resolvectl query --legend=yes app01.corp.local

# 5. Стоит ли на машине NSS-модуль Avahi
dpkg -S libnss_mdns4_minimal.so.2 2>/dev/null || rpm -qf /usr/lib64/libnss_mdns4_minimal.so.2

# 6. Что творится в самой службе
sudo resolvectl flush-caches
journalctl -u systemd-resolved -n 50 --no-pager

Самая ценная команда здесь — resolvectl query. В отличие от dig она показывает решение самой службы: в хвосте успешного ответа есть строка вида «Information acquired via protocol DNS», а при отсутствии маршрута вы сразу получаете «No appropriate name servers or networks for name found». Ключ --legend= управляет этими служебными строками: по умолчанию они выводятся, а --legend=no пригодится в скриптах, когда нужен только адрес. Не рассчитывайте обойти запрет ключом -p dns: он ограничивает набор протоколов, но правило «.local не отправлять в unicast DNS без явного домена» от этого не отменяется. Лучшее доказательство диагноза другое — временно объявить домен через resolvectl domain (следующий раздел) и повторить query: если имя тут же находится по протоколу DNS, дело было в маршрутизации, а не в записи.

Отдельно проверьте, а systemd-resolved вообще в игре. Если /etc/resolv.conf — симлинк на /run/systemd/resolve/stub-resolv.conf (сервер 127.0.0.53) или в hosts-строке есть resolve, то да, и правила маршрутизации .local действуют. Если это обычный файл с адресами корпоративных серверов, а в hosts-строке нет resolve — вы имеете дело с классическим nss-dns, и там .local ведёт себя как любая другая зона. В этом случае ищите Avahi и nss-mdns, третьего почти не бывает.

Не начинайте диагностику с tcpdump. В девяти случаях из десяти `resolvectl status` и `resolvectl query` дают ответ за минуту. tcpdump на 224.0.0.251:5353 пригодится только чтобы убедить скептика, что запросы действительно уходят в мультикаст.

Как чинить: три уровня, от проверки гипотезы до постоянного конфига

Уровень первый — разово, чтобы подтвердить диагноз. Все изменения живут в оперативной памяти службы и слетают при переподключении интерфейса, зато делаются мгновенно и ничего не ломают.

# выключить mDNS на конкретном линке
sudo resolvectl mdns enp1s0 no

# объявить корпоративную зону search-доменом этого линка
sudo resolvectl domain enp1s0 corp.local

# если .local-зон несколько — routing-домен на весь суффикс
# sudo resolvectl domain enp1s0 '~local'

sudo resolvectl flush-caches
resolvectl query app01.corp.local

Разница между search- и routing-доменом важна и её постоянно путают. Search-домен (без тильды) делает две вещи: маршрутизирует запросы этого домена на DNS-серверы данного линка и дополнительно подставляет суффикс к однокомпонентным именам, то есть app01 превратится в app01.corp.local. Routing-домен (с тильдой, ~corp.local) только маршрутизирует, суффикс не подставляет. Для корпоративной зоны обычно нужен именно search-домен. А ~. — это «всё остальное сюда», типовой приём для основного линка при живом VPN.

Уровень второй — постоянный конфиг через NetworkManager, это то, что я оставляю у клиента. Свойство connection.mdns принимает значения 0 (no), 1 (resolve), 2 (yes) и -1 (default), а ipv4.dns-search поддерживает тильду для routing-доменов ровно с той же семантикой, что и resolvectl:

nmcli con show   # узнать имя профиля
nmcli con mod "Wired connection 1" ipv4.dns-search "corp.local"
nmcli con mod "Wired connection 1" connection.mdns 0
nmcli con mod "Wired connection 1" connection.llmnr 0
nmcli con up "Wired connection 1"

Уровень третий — глобально, drop-in для systemd-resolved. Удобен там, где интерфейс один и NetworkManager не используется (серверы, systemd-networkd). Кладём файл /etc/systemd/resolved.conf.d/50-corp.conf:

[Resolve]
DNS=10.20.0.10 10.20.0.12
Domains=~corp.local
MulticastDNS=no
LLMNR=no

И перезапускаем: sudo systemctl restart systemd-resolved. Держите в голове, что глобальные настройки из resolved.conf действуют вместе с per-link, а не вместо них. Для маршрутизации resolved выбирает «лучше всего совпадающий» routing-домен — тот, у которого больше меток, — и шлёт запрос серверам, к которым этот домен привязан, будь то линк или глобальная секция. Поэтому Domains=~corp.local в глобальном конфиге отправит corp.local на глобальные DNS= даже при серверах, пришедших по DHCP. А MulticastDNS=no глобально выключает mDNS везде: по resolved.conf(5) он работает на линке, только если включён и глобально, и на линке. На станциях с DHCP и NetworkManager я всё же предпочитаю профиль соединения — там настройки живут рядом с остальной сетью, а drop-in оставляю для серверов и статики.

Есть и четвёртый, аварийный вариант — вынести systemd-resolved из цепочки NSS: убрать resolve [!UNAVAIL=return] из hosts-строки, оставить files dns и положить статический /etc/resolv.conf. Работает, .local начинает резолвиться как обычная зона. Но вы теряете split-DNS: на машине с корпоративным VPN или несколькими туннелями это выйдет боком очень быстро, потому что резолвиться всё начнёт через один набор серверов. Я так делаю только на изолированных стендах и в качестве временной меры, когда нужно поднять человека здесь и сейчас.

Если вы «уже это чинили, а через неделю опять сломалось» — вы чинили через resolvectl и не зафиксировали конфиг. Любое переподключение линка, ребут или `nmcli con up` возвращает всё как было. Проверить просто: после перезагрузки посмотрите `resolvectl status`.
Памятка: Как чинить: три уровня, от проверки гипотезы до постоянного конфига — схема
Памятка: Как чинить: три уровня, от проверки гипотезы до постоянного конфига. Открыть схему в полном размере

Второй фронт: Avahi, nss-mdns и приложения со своим резолвером

На Debian и Ubuntu в цепочку часто вклинивается libnss-mdns — NSS-модуль Avahi. Minimal-вариант обслуживает исключительно имена в .local (и обратные запросы для 169.254.x.x) и в типовой конфигурации стоит в hosts-строке до dns: hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4. Логика такая: на имя, которое модуль брать не хочет, он возвращает UNAVAIL и пропускает запрос дальше по цепочке, а вот на .local-имя, которое он взял и не нашёл в мультикаст-эфире, возвращает NOTFOUND — и [NOTFOUND=return] обрывает цепочку. До dns дело не доходит.

Какие имена модуль берёт — вопрос, в котором путаются чаще всего. По документации nss-mdns работают две эвристики. Первая: запросы к .local-именам длиннее двух меток отклоняются — foo.bar.local модуль пропускает дальше. Значит, app01.corp.local он не трогает, а вот сам corp.local, короткие имена вида printer.local и имена DFS-пространства в корне домена — перехватывает. Вторая: перед обслуживанием .local модуль проверяет SOA, и если unicast DNS отдаёт SOA для верхнеуровневого имени local, запрос отклоняется. Ваша зона называется corp.local, SOA на голом local сервер не отдаст — защита не срабатывает. Настроить поведение можно файлом /etc/mdns.allow, но только для полного варианта mdns4: minimal-вариант, по документации, этот файл не читает никогда. Поэтому на машинах, где Avahi нужен только для печати, я просто вычищаю mdns из hosts-строки:

# было:  hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
# стало: hosts: files dns
sudo sed -i 's/ mdns4_minimal \[NOTFOUND=return\]//; s/ mdns4$//' /etc/nsswitch.conf
getent hosts app01.corp.local

Третья категория сюрпризов — программы, которые идут к имени не через glibc. Go по документации пакета net предпочитает собственный резолвер, который сам читает /etc/resolv.conf и /etc/hosts, но переключается на cgo и getaddrinfo, если в nsswitch.conf указаны источники, которых он не умеет, — а resolve и mdns4_minimal как раз такие; статически собранный бинарник без cgo этого сделать не сможет. Образы на musl/Alpine NSS-модулей не поддерживают вообще и читают resolv.conf напрямую. SSSD для поиска контроллеров использует собственный асинхронный резолвер поверх resolv.conf. Отсюда вечное «а у нас curl работает, а наш сервис нет» — и наоборот. Важная деталь: если resolv.conf указывает на 127.0.0.53, такие программы всё равно попадают в systemd-resolved, и запрет на .local их тоже касается; обходят его только те, у кого в resolv.conf адреса корпоративных серверов.

И отдельно про контейнеры. Docker при stub-резолвере на хосте не копирует 127.0.0.53 в контейнер: в сетях по умолчанию он подставляет реальные upstream-серверы, а в пользовательских сетях контейнер ходит во встроенный DNS 127.0.0.11, который пересылает запросы наружу. mDNS внутри контейнера, как правило, нет. Получается обратная картина: контейнер спрашивает контроллер домена напрямую и corp.local видит, а хост — нет. Это сбивает с толку при диагностике («в контейнере же работает»), поэтому проверяйте хост и контейнер раздельно и не делайте выводов об одном по другому.

Проверяйте оба механизма сразу и несколькими именами. Я не раз видел, как чинят systemd-resolved, радуются `getent hosts app01.corp.local` — а через день жалоба «не открывается \\corp.local\files», потому что двухметочное имя по-прежнему перехватывает mdns4_minimal. Финальная проверка — getent и на имя хоста, и на имя самого домена.

Что делать в первую очередь, а на что забить

Приоритет номер один — зафиксировать конфиг на станциях через NetworkManager или drop-in resolved.conf.d и убрать mdns из nsswitch там, где он приехал зависимостью. Это 3-5 минут на машину, делается скриптом, живёт годами и решает 100 % симптома. Никаких правок на контроллерах домена для этого не требуется, и это важный аргумент, когда AD трогать страшно или некому.

Приоритет номер два — решить, живёте ли вы дальше на .local. Штатное переименование домена AD (rendom/gpfixup) технически существует, но это операция на выходные с реальными рисками, а при установленном Exchange за неё браться я не советую вовсе. Практичный путь, который я применяю у клиентов: не переименовывать, а завести внутреннюю зону на реальном домене — corp.example.com, делегированную и видимую только внутри. Новые сервисы публикуются там, старые имена остаются алиасами, и через год-полтора .local встречается только в SPN и Kerberos, куда пользовательские приложения не лезут. Заодно вы получаете возможность выпустить нормальные сертификаты Let's Encrypt на внутренние имена, чего с .local не сделать в принципе.

На что можно спокойно забить. На переименование NetBIOS-имени домена — оно к нашей проблеме отношения не имеет. На попытки «починить DNS-сервер» или «пересоздать зону» — зона исправна, вы это уже доказали командой dig. На идею отключить systemd-resolved целиком: соблазнительно, но вы теряете split-DNS, кеш и per-link конфигурацию, а на машинах с VPN и туннелями это создаст новых проблем больше, чем решит. И на мифы про «mDNS надо просто выключить в фаерволе» — блокировка 5353 не заставит systemd-resolved пойти на unicast DNS, он всё равно не пойдёт, потому что routing-домена нет; вы получите тот же отказ, только медленнее.

Честно про спорное. Единого мнения, как правильно жить с корпоративной зоной .local, в сообществе нет и не будет: мануал systemd-resolved и документация Microsoft прямым текстом не рекомендуют такую зону заводить, а у половины российского малого и среднего бизнеса она заведена лет пятнадцать назад и работает. Обе позиции обоснованы. Моя практическая позиция такая: пока зона .local существует, обслуживайте её явно — routing/search-домен плюс выключенный mDNS на всех Linux-машинах, и никаких «оно само разберётся». А стратегически двигайтесь к нормальному имени, но без героизма и не в ночь с пятницы на субботу.

Если у вас смешанный парк и в планах Linux-станции, macOS или контейнеры — считайте зону .local техдолгом с процентами. Он не взрывается, но каждое новое устройство в сети стоит вам заявки в поддержку.
Порядок действий: Что делать в первую очередь, а на что забить — схема
Порядок действий: Что делать в первую очередь, а на что забить. Открыть схему в полном размере

Частые вопросы

Почему dig отвечает, а ping и браузер — нет?

Потому что это два разных пути. dig — самостоятельный DNS-клиент, он шлёт пакет на UDP/53 напрямую и системный механизм разрешения имён не использует. ping и браузер зовут getaddrinfo(3), а тот идёт по цепочке модулей из /etc/nsswitch.conf. Для имён с суффиксом .local запрос перехватывает systemd-resolved (уводит в mDNS) или nss-mdns и на обычный DNS не отдаёт. Проверяйте не dig, а `getent hosts <имя>`.

Достаточно ли просто выключить mDNS, чтобы .local заработал?

Нет, этого мало. Мануал systemd-resolved говорит, что запросы .local не направляются на DNS-серверы, пока домен не объявлен явно routing- или search-доменом. Выключив mDNS, вы уберёте перехват, но маршрута на корпоративный DNS всё равно не появится. Нужны обе половины: `resolvectl mdns <link> no` и `resolvectl domain <link> corp.local` (либо `~local`), а лучше — то же самое постоянно через NetworkManager.

Чем routing-домен отличается от search-домена?

Search-домен (без тильды) маршрутизирует запросы этого домена на DNS-серверы линка и дополнительно подставляет суффикс к однокомпонентным именам: `app01` станет `app01.corp.local`. Routing-домен (`~corp.local`) только маршрутизирует, суффикс не подставляет. Для корпоративной зоны обычно нужен search-домен. Особый случай — `~.`: он означает «все остальные запросы сюда» и используется как основной линк при активном VPN.

Мои правки resolvectl слетают после перезагрузки. Как сделать их постоянными?

resolvectl меняет состояние службы в памяти, переподключение интерфейса это откатывает. Постоянно — либо через профиль NetworkManager (`nmcli con mod <профиль> ipv4.dns-search "corp.local"` и `connection.mdns 0`), либо drop-in файлом /etc/systemd/resolved.conf.d/50-corp.conf с секцией [Resolve] и строкой `Domains=~corp.local`. Глобальный routing-домен работает и при DNS-серверах из DHCP: resolved выбирает самый длинный совпадающий домен. Для рабочих станций я всё же предпочитаю профиль NetworkManager.

У нас Ubuntu, systemd-resolved настроил, хосты резолвятся, а \\corp.local и само имя домена — нет. Почему?

Скорее всего, в /etc/nsswitch.conf стоит libnss-mdns: `hosts: files mdns4_minimal [NOTFOUND=return] dns`. Модуль отклоняет .local-имена длиннее двух меток, поэтому app01.corp.local проходит до DNS, а двухметочное corp.local он берёт сам, не находит в мультикаст-эфире, отдаёт NOTFOUND — и `[NOTFOUND=return]` обрывает цепочку. Уберите mdns4_minimal и mdns4 из hosts-строки; avahi-daemon для печати можно оставить.

Надо ли переименовывать домен AD, чтобы уйти с .local?

Не обязательно и обычно не стоит. Переименование (rendom/gpfixup) возможно, но это рискованная операция, а с Exchange в лесу за неё лучше не браться. Практичнее завести внутреннюю зону на реальном домене — например corp.example.com, видимую только внутри, — и публиковать там новые сервисы, оставив .local легаси-алиасами. Побочный плюс: на нормальном имени можно выпускать публичные сертификаты, чего с .local не сделать.

Что официально говорят Microsoft и systemd про домен AD в .local?

Обе стороны против. В руководстве Microsoft по выбору корневого домена леса сказано, что незарегистрированные суффиксы вроде .local использовать не рекомендуется, а в статье об именовании доменов — что стоит избегать имён, занятых интернет-стандартными механизмами, с .local в качестве примера. Мануал systemd-resolved напоминает, что RFC 6762 резервирует .local исключительно под Multicast DNS. Работающий домен из-за этого ломать не нужно, но новые зоны заводите на зарегистрированном имени, например corp.example.com.

Столкнулись с похожей задачей? Обращайтесь — решим

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

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 💬 MAX: +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи