Привет, Хабр! C вами сегодня Владимир Кудрявцев, Илья Князев ( @prundukevich) и Иван Пономарев (@ubicawtf).

Несколько месяцев назад вышла статья нашего коллеги Павла Ермолаева (@ermolpa) о том, как освоить Linux за 64 часа, в которой он рассказал о результатах работы нашей команды по исследованию лучших практик импортозамещения. И сегодня мы хотим показать ещё один пример того, что мы подразумеваем под лучшими практиками, и как они помогают в настройке реальной ИТ-инфраструктуры.

Дело было вечером, дебажить было нечего. К нам пришел Анатолий Лысов (@AnatolijL), менеджер продукта ALD Pro, и попросил разобраться, с чего это Linux приходит в такую задумчивость от недоступности первых двух DNS-серверов, в то время как Windows вполне нормально справляется с таким сценарием. «Да, как два байта переслать», – подумали мы. И начался квест длиной в две недели.

Пожалуй, если бы надежное и быстрое разрешение доменных имен не было столь важно для нормальной работы компьютеров в домене, то, возможно, мы и не стали бы закапываться так глубоко, но ответственность обязывала. Для тех, кому нужно «чик-чик—и в продакшн», краткая инструкция по настройке и ключевые выводы собраны в конце статьи. Если же вы считаете, что спешить – только QA насмешить, то приятного вам прочтения.

Материалы будут полезны, даже если вы все ещё используете обычные Linux-системы с ванильными версиями компонентов.

Если вы открыты для общения и не согласны с тем, что старый баг лучше новых двух...

Давайте знакомиться!

Меня зовут Владимир и я давно уже работаю вместе с Ильей: больше 8 лет в компании GDC/ICL Services (Global Delivery Center), мы отвечали за поддержку больших Windows-инфраструктур у крупных зарубежных заказчиков с штатом более 100к человек. В основном Active Directory, DNS, PKI, DHCP, ADFS и далее по стеку Windows-технологий, но и линуксом Илья крепко занялся ещё задолго до того, как это стало мейнстримом, а я присоединился пару лет назад. После ухода зарубежных компаний с российского рынка мы по приглашению Анатолия Лысова подключились к созданию направления R&I в продуктовой команде ALD Pro, а потом с головой ушли в проекты внедрения от Астра Консалтинг. В общем, у нас с Ильей сложился идеальный тандем, как у Джобса и Возняка, Шэлдона Купера и Леонарда Хофстедтера, Винтика и Шпунтика. Илья не может жить без исследований и отладки, а я люблю подушнить, так как для меня крайне важно разобраться в деталях, разложить всё по полочкам и три раза всё перепроверить.

В команде R&I мы познакомились с большим количеством талантливых ребят с совершено разным бэкграундом. Это были и коллеги с колоссальным опытом, и начинающие разработчики с большим потенциалом. Одним из таких подающих надежды талантов был Иван. Мы сразу подключили его к нашему исследованию и ни разу не пожалели. Иван всегда горел разработкой открытого программного обеспечения и увлекался исследованиями, поэтому по завершении обучения на кафедре информационной безопасности он некоторое время проработал как раб на галерах инженером DevOps, и его очень быстро переманили с рынка наши вездесущие эйчары. Наши задачи, конечно, оказались на порядок сложнее, зато у нас тамада хороший и конкурсы интересные. Поэтому, если у вас светлая голова и вы не боитесь применять ее по прямому назначению, не стесняйтесь подать свое резюме в Астру. А ещё в компании есть специальная программа для студентов «Астра-стипендия», но эти истории успеха – тема отдельной статьи.

Ну что, хватит тянуть сервер за локалхост, давайте начинать!

Оглавление

Быстрое и надежное разрешение доменных имен критически важно для обеспечения стабильной работы компьютера в составе домена, поскольку с помощью SRV-записей _ldap._tcp.<имя домена> компьютер извлекает список серверов, а с помощью A-записей понимает, по каким IP-адресам они могут быть доступны. И это не считая того, что даже когда сотрудник работает с простым текстовым документом, сам файл может находиться на удаленном сервере, а доступ к нему осуществляется также по доменному имени.

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

В операционных системах Windows разрешение имён выполняет служба dnscache (DNS-клиент), которая умеет запоминать предпочтительный DNS-сервер и обладает встроенным механизмом кэширования. В мире Linux обычные приложения выполняют разрешение имен с помощью функций из библиотеки glibc, поэтому ответы не кэшируются, и каждый запрос обрабатывается по списку серверов из файла /etc/resolv.conf без закрепления предпочтительного DNS-сервера.

На Хабре уже была серия крайне полезных статей о механизме разрешения доменных имён в Linux от наших коллег из К2Тех (часть1часть2 и часть3), но мы сконцентрируемся больше не на внутренних аспектах реализации, а на логике работы DNS-клиента с таймаутами в системе Windows, и расскажем о том, как в Linux добиться похожего поведения с помощью легкого кэширующего DNS-резолвера — службы systemd-resolved.

Привычный механизм разрешения доменных имён в Windows 

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

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

Рисунок 1 — Обработка DNS-запросов в Windows
Рисунок 1 — Обработка DNS-запросов в Windows
То же самое в табличном виде...

Время с момента получения запроса, сек

Выполняемое действие

Время ожидания, сек

0

Клиент направляет запрос первому DNS-серверу.

1

1

Если ответ не получен в течение 1 секунды, то запрос направляется второму DNS-серверу.

Если второй DNS-сервер не задан, то запрос будет направлен повторно первому DNS-серверу.

1

2

Если ответ не получен в течение 1 секунды, то запрос направляется третьему DNS-серверу.

Если третий DNS-сервер не задан, то запрос будет направлен повторно второму DNS-серверу, а если и второй DNS-сервер не задан, то первому DNS-серверу.

2

4

Если ответ не получен в течение 2 секунд, то запрос направляется сразу всем оставшимся DNS-серверам, т.е. четвертому и последующим.

4

8

Если ответ не получен в течение 4 секунд, то запрос ещё раз направляется всем DNS-серверам с первого по третий.

2

10

Если ответ не получен в течение 2 секунд, то клиент прекращает попытки выполнения запросов.


Сервер, от которого служба dnscache получит ответ, будет назначен предпочтительным сервером на следующие 15 минут в соответствии с значением параметра ServerPriorityTimeLimit по умолчанию. Настройки DNS-клиента могут быть изменены в ветке реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters.

Повторный выбор предпочтительного DNS-сервера будет выполнен только в следующих двух случаях:

  • через 15 минут по истечении таймаута ServerPriorityTimeLimit;

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

Данная логика позволяет Windows-компьютерам обрабатывать запросы преимущественно через первый DNS-сервер, а в случае сбоев быстро переключаться на работу со следующим DNS-сервером.

Альтернативный алгоритм разрешения доменных имен в Linux

Базовый механизм разрешения доменных имен в библиотеке glibc

Для большинства Linux-приложений, таких как pinggetentwgetcurlapt и др. в роли DNS-клиента выступает функция getaddrinfo() из стандартной библиотеки glibc, которая в своей работе использует диспетчер имен (Name Service Switch, NSS). Подробнее см. статью Как работает DNS в Linux. Часть 1: от getaddrinfo до resolv.conf от К2Тех.

При каждом вызове этой функции выполняется обращение к файлу /etc/nsswitch.conf с настройками системы NSS. По умолчанию в  файле определена строка hosts: files dns, поэтому система NSS проверяет сначала записи из локального файла /etc/hosts (параметр files), а затем переходит к опросу DNS-серверов из файла /etc/resolv.conf (параметр dns) (рис. 2).

Рисунок 2 — Порядок обработки DNS-запросов в glibc
Рисунок 2 — Порядок обработки DNS-запросов в glibc

Системные функции glibc могут использовать до трех DNS-серверов и оперируют такими параметрами как attempts (количество попыток) и timeout (время ожидания). Однако, если вы полагаете, что в документации можно найти подробное объяснение того, как именно glibc работает с таймаутами, то вы ничего не знаете о мире открытого ПО.

Чтобы разобраться, как работают функции glibc, нам потребовалось провести больше 200 тестов с утилитами ping и getent и потратить два дня на препарирование исходных кодов, за что респект Ивану. В итоге мы достоверно подтвердили дискриминацию второго DNS-сервера и привилегированное положение третьего: «Второму DNS-серверу на ответ выделяется только 2/3 от полного таймаута, а сэкономленное время отдается третьему DNS-серверу, поэтому от него ответ ожидается в течение 4/3 таймаута». И, вроде бы, 2/3 + 4/3 = 2, но если значение таймаута не кратно 3, то на округлениях мы можем терять от 2 до 10 секунд.

По умолчанию функция getaddrinfo() использует настройки options attempts:2 timeout:5, поэтому в случае трех серверов порядок разрешения доменных имен будет следующим (рис.3):

Рисунок 3 — Обработка DNS-запросов в библиотеке glibc
Рисунок 3 — Обработка DNS-запросов в библиотеке glibc
То же самое в табличном виде...

Время с момента получения запроса, сек

Выполняемое действие

Время ожидания, сек

0

Попытка 1: клиент направляет запрос первому DNS-серверу.

5

5

Попытка 1: если ответ не получен в течение 5 секунд, то запрос направляется второму DNS-серверу.

Если второй DNS-сервер не задан, то шаг пропускается.

3

(2/3 от таймаута)

8

Попытка 1: если ответ не получен в течение 3 секунд, то запрос направляется третьему DNS-серверу.

Если третий DNS-сервер не задан, то шаг пропускается.

6

(4/3 от таймаута)

14

Попытка 2: если ответ не получен в течение 6 секунд, то запрос повторно направляется первому DNS-серверу.

5

19

Попытка 2: если ответ не получен в течение 5 секунд, то запрос повторно направляется второму DNS-серверу.

Если второй DNS-сервер не задан, то шаг пропускается.

3

(2/3 от таймаута)

22

Попытка 2: если ответ не получен в течение 3 секунд, то запрос повторно направляется третьему DNS-серверу.

Если третий DNS-сервер не задан, то шаг пропускается.

6

(4/3 от таймаута)

28

Если ответ не получен в течение 6 секунд, то клиент прекращает попытки выполнения запросов.


Кроме опций attempts и timeout в конфигурационном файле /etc/resolv.conf может быть определено множество других параметров, которые влияют на алгоритм работы DNS-клиента. Давайте рассмотрим их все чуть подробнее.

  • nameserver — определяет список DNS-серверов. Как можно заметить, список DNS-серверов для glibc является общим и не привязан к сетевому интерфейсу. В некоторых инструкциях в файле /etc/network/interfaces для конкретных сетевых интерфейсов задают такие параметры, как dns-nameservers или dns-search, но они имеют силу только в том случае, если в системе работает служба resolvconf, которая переносит эти настройки в файл /etc/resolv.conf при включении/выключении этих интерфейсов, но логика работы glibc от этого не меняется. 

  • search — определяет список поисковых суффиксов, добавляемых к неполным именам, которые не заканчиваются символом точки.

  • options ndots:n – определяет логику обработки неполных адресов, которые не завершаются символом точки. Если в запрашиваемом адресе количество точек будет соответствовать указанному значению или превышать его, то этот адрес будет интерпретирован сначала как полный адрес, и только затем будут предприняты попытки добавления к нему поисковых суффиксов, которые заданы параметром search. По умолчанию ndots равен 1, поэтому при наличии одной и более точек адрес интерпретируется сначала как полный.

  • options attempts:n – определяет количество попыток обращения к DNS-серверам, причем каждая попытка предполагает полный проход по списку всех DNS-серверов. Для функций glibc допустимыми являются значения 1-5. Значение меньше 1 отключает функцию разрешения имен. Значение более 5 интерпретируется как 5. Например, по умолчанию опция attempts равна 2, поэтому при недоступности указанных DNS-серверов клиент суммарно сделает по два обращения к каждому из них.

  • options timeout:n – определяет время ожидания ответа на отправленный DNS-запрос, прежде чем будет выполнен переход к следующему DNS-серверу. Для функций glibc максимальное значение timeout составляет 30 секунд, и если установить значение больше, то оно будет усечено до максимально допустимого значения. По умолчанию опция timeout равна 5 секундам.

  • options rotate – определяет, что DNS-клиент будет ротировать DNS-серверы, выбирая их случайным образом из списка, чтобы распределить нагрузку. По умолчанию считается, что параметр не задан, поэтому клиент перебирает DNS-серверы по очереди в соответствии с указанным порядком.

Рекомендация

Никакого выбора предпочтительного DNS‑сервера в glibc нет, поэтому, если используется «голая» система Linux без дополнительных сервисов, то мы рекомендуем установить параметр options attempts:1 timeout:1. По нашему мнению, при хорошей доступности DNS‑серверов задержки в одну секунду вполне достаточно для обработки запросов, а дополнительные попытки являются излишними — намного полезнее дать быстрый отказ, чем тратить время на повторные обращения к недоступным серверам.

Если вы будете проверять работу алгоритма утилитой ping, то используйте следующую команду:

time ping dc-1.ald.company.lan. -n -c 1

Пояснения

  • Точка в конце запрашиваемого адреса dc-1.ald.company.lan. указывает, что значение следует интерпретировать только как полный адрес и не пытаться дополнять его поисковыми суффиксами search. Если этого не сделать, то при недоступности DNS-серверов суммарное время ожидания может быть больше в несколько раз по количеству поисковых суффиксов, т.к. система сначала проверит указанный адрес, а затем будет проверять его ещё раз с добавлением поисковых суффиксов.

  • Ключ -n позволит отключить отправку запроса на получение PTR-записи, иначе суммарное время ожидания будет больше в два раза.

  • Ключ -c позволит остановить работу после передачи одного пакета, чтобы трассировка не внесла существенных искажений в итоговые результаты.

Если вы будете проверять алгоритм утилитой getent, то используйте следующую команду:

time getent ahosts dc-1.ald.company.lan.

Пояснение

  • Обращение к базе данных ahosts позволит вам запросить только A-записи. Если же обращаться к базе данных hosts, то будет отправлено последовательно три запроса на получение записей A, AAAА и MX, что увеличит суммарное время ожидания в три раза.

Механизм разрешения доменных имен в утилитах BIND (host, nslookup, dig)

Очень популярные приложения hostnslookup и dig, созданные в рамках открытой реализации DNS от Berkeley Internet Name Domain (BIND), используют собственный DNS-клиент, не обращаясь к системной функции getaddrinfo(), поэтому изменения в файле /etc/nsswitch.conf никак не отразятся на их работе. Подробнее про эти и прочие утилиты можно узнать в статье Как работает DNS в Linux. Часть 3:  Разбираемся с resolv.conf, systemd-resolved, NetworkManager и другими.

Вместе с тем, утилиты BIND используют общие настройки из файла /etc/resolv.conf, интерпретируя их в некоторых случаях очень своеобразно. С документацией у проекта BIND немного лучше, поэтому нам хватило всего двухсот тестов и даже в код смотреть не пришлось, ну если совсем чуть-чуть. Фиксируем результаты:

  • nameserver — так же, как для glibc, определяет список DNS-серверов;

  • search — так же, как для glibc, определяет список поисковых суффиксов, добавляемых к неполным доменным именам, которые не заканчиваются точкой;

  • options ndots:n – так же, как для glibc, определяет логику обработки неполных адресов и использует значение 1 по умолчанию. Но при этом есть существенное отличие: если в запрашиваемом адресе количество точек будет соответствовать указанному значению или превышать его, то этот адрес будет интерпретирован только как полный адрес, а не «сначала как полный». Это означает, что при недоступности DNS-серверов утилиты BIND не будут предпринимать попытки добавления к запрашиваемому адресу поисковых суффиксов, поэтому указывать точку в конце адреса при выполнении запросов не требуется;

  • options attempts:n – так же, как для glibc, определяет количество попыток и использует значение 2 по умолчанию. Но при этом есть ряд существенных отличий:

    • нумерация попыток начинается с нуля, поэтому при значении attempts:2 по умолчанию будет выполнено не два, а три цикла обращений к серверам. При значении attempts:3 уже четыре цикла. При значении attempts:4... о, да вы схватываете на лету! Таким образом получается, что для утилит BIND опция определяет, скорее, «количество повторных попыток» (retries), а не «количество попыток» (attempts);

    • если установить значение attempts:0, то оно будет интерпретировано как attempts:1, и ничего не сломается, т.е. в этом случае будет выполнено до двух циклов обращения к DNS-серверам. Но не спешите расстраиваться, вам всё ещё доступна возможность «выстрелить  себе в пятку»: если вы установите отрицательное значение, то утилиты BIND всё-таки перестанут работать!

    • значение attempts не ограничено сверху 5 попытками. Вы можете использовать любое положительное целое число, но это для тех, кому платят по часам, т.к. при недоступности DNS-серверов увеличение этого параметра приведет только к увеличению общей продолжительности обработки запросов;

  • options timeout:n — так же, как для glibc, определяет время ожидания ответа на отправленный DNS-запрос, но резолвер BIND реализует более сложную логику работы с таймаутами, которая позволяет значительно ускорить обработку запросов в условиях недоступности DNS-серверов:

    • если резолвер не получит ответ от DNS-сервера за 1 секунду, то обращение будет направлено параллельно к следующему серверу;

    • следующая серия DNS-запросов (следующая попытка) не начнется, пока не будут получены ответы на запросы, отправленные в рамках предыдущей серии;

  • options rotate – точно так же, как для glibc, определяет, что DNS-клиент будет ротировать DNS-серверы, выбирая их случайным образом из списка, чтобы распределить нагрузку. По умолчанию считается, что параметр не задан, поэтому клиент перебирает DNS-серверы по очереди в указанном порядке.

Утилиты BIND как функции glibc могут работать только с тремя DNS-серверами, и в случае трех серверов и настроек по умолчанию порядок разрешения доменных имен будет следующим:

Рисунок 4 — Обработка DNS-запросов в утилитах BIND
Рисунок 4 — Обработка DNS-запросов в утилитах BIND
То же самое в табличном виде...

Время с момента получения запроса, сек

Выполняемое действие

Время ожидания, сек

0

Попытка 0: клиент направляет запрос первому DNS-серверу.

1

1

Попытка 0: если ответ не получен в течение 1 секунды, то запрос направляется второму DNS-серверу.

Если второй DNS-сервер не задан, то шаг пропускается.

1

2

Попытка 0: если ответ не получен в течение 1 секунды, то запрос направляется третьему DNS-серверу.

Если третий DNS-сервер не задан, то шаг пропускается.

5

7

Попытка 1: если ответ не получен в течение 5 секунд, то запрос повторно направляется первому DNS-серверу.

1

8

Попытка 1: если ответ не получен в течение 1 секунды, то запрос направляется второму DNS-серверу.

Если второй DNS-сервер не задан, то шаг пропускается.

1

9

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

Если третий DNS-сервер не задан, то шаг пропускается.

5

14

Попытка 2: если ответ не получен в течение 5 секунд, то запрос повторно направляется первому DNS-серверу.

1

15

Попытка 2: если ответ не получен в течение 1 секунды, то запрос направляется второму DNS-серверу.

Если второй DNS-сервер не задан, то шаг пропускается.

1

16

Попытка 2: если ответ не получен в течение 1 секунды, то запрос направляется третьему DNS-серверу.

Если третий DNS-сервер не задан, то шаг пропускается.

5

21

Если ответ не получен в течение 5 секунд, то клиент прекращает попытки выполнения запросов.


Если вы будете проверять алгоритм утилитой host, то используйте следующую команду:

time host -t A dc-1.ald.company.lan

Пояснения

  • Ключ -t позволит  запросить только A-запись. Если же его не указывать, то будет отправлено три запроса на получение записей A, AAA, MX, что увеличит суммарное время обработки запроса в три раза. При недоступности сервера это не повлияет на время ожидания.

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


Если вы будете проверять алгоритм утилитой nslookup, то используйте следующую команду:

time nslookup -q=A dc-1.ald.company.lan

Пояснение

  • Ключ -q=A позволит  запросить только A-запись. Если же его не указывать, то будет  отправлено два запроса на получение записей A и AAAA, что увеличит  суммарное время обработки запроса в два раза.

Обратите внимание, что при полной недоступности сервера запрос на получение AAAA-записи к нему не отправляется, поэтому в таком сценарии значение этого параметра не повлияет на общее время ожидания.

Для того, чтобы увидеть расширенный вывод в утилите nslookup можно использовать дополнительные ключи: в Linux ответы от сервера можно получить с помощью ключа -deb (или -d2 для вывода сообщений отладки), в Windows параметр -d1 покажет подробную информацию об ответе сервера, а параметр -d2 добавит в вывод информацию, которую утилита запрашивает у сервера.

Механизм разрешения доменных имен в службе sssd

Как мы уже сказали, для обеспечения стабильной работы компьютера в составе домена критически важно, чтобы доменные имена разрешались быстро, надежно и обязательно через собственный DNS-сервер домена. Для разрешения доменных имен служба sssd, также как утилиты BIND, использует собственный DNS-клиент, не обращаясь к системной функции getaddrinfo(), поэтому изменения в файле /etc/nsswitch.conf никак не отразятся на работе sssd. Параметры конфигурационного файла /etc/resolv.conf служба sssd интерпретирует следующим образом:

  • nameserver — точно так же, как для glibc, определяет список DNS-серверов;

  • search — точно так же, как для glibc, определяет список поисковых суффиксов, которые будут добавляться к неполным доменным именам, которые не заканчиваются точкой. Использование поисковых суффиксов можно отключить в конфигурационном файле /etc/sssd/sssd.conf с помощью параметра dns_resolver_use_search;

  • options ndots:n — точно так же, как для glibc, определяет логику обработки неполных адресов: если в запрашиваемом адресе количество точек будет соответствовать указанному значению или превышать его, то этот адрес будет интерпретирован сначала как полный адрес, и только затем к нему будет предприняты попытки добавления поисковых суффиксов, которые заданы параметром search;

  • options attempts:n — не используется. Служба sssd предпринимает только одну попытку обращения ко всем DNS-серверам, а следующую попытку выхода из автономного режима служба sssd предпримет по истечению таймаута, заданного параметром offline_timeout (по умолчанию 60 секунд) + случайная задержка продолжительностью от 0 секунд до offline_timeout_random_offset (по умолчанию составляет 30 секунд). Параметр offline_timeout_random_offset можно настроить в конфигурационном файле /etc/sssd/sssd.conf, начиная с версии ALSE 1.8, поскольку требуется обновление до SSSD 2.5;

  • options rotate — точно так же, как для glibc, определяет, что нужно ротировать DNS-серверы, выбирая их из списка случайным образом, чтобы распределить нагрузку.

Для настройки баланса между производительностью и надежностью разрешения имен в секции домена конфигурационного файла /etc/sssd/sssd.conf можно использовать следующие параметры:

  • dns_resolver_server_timeout — максимальное время (в миллисекундах) ожидания ответа до перехода к следующему DNS-серверу. По умолчанию параметр имеет значение 1000 миллисекунд.

  • dns_resolver_op_timeout — максимальное время (в секундах) ожидания для разрешения одного DNS-запроса (например, разрешение имени хоста или получение SRV-записей) до перехода к следующему имени. Это значение должно быть больше значения параметра dns_resolver_server_timeout. По умолчанию параметр имеет значение 3 секунды.

  • dns_resolver_timeout — максимальное время (в секундах) получения ответа от резолвера. При достижении этого лимита служба sssd переключает домен в автономный режим. Это значение должно быть больше значения параметра dns_resolver_op_timeout. По умолчанию параметр имеет значение 6 секунд.

  • try_inotify — позволяет включить/отключить отслеживание изменений в конфигурационном файле /etc/resolv.conf через механизм inotify. По умолчанию параметр имеет значение TRUE. Параметр имеет смысл только в том случае, если система поддерживает функцию inotify.

  • lookup_family_order — порядок выбора сетевых протоколов для разрешения имен. Допустимые значения:

    • ipv4_first — сначала использовать IPv4, в случае неудачи — использовать IPv6 (это значение используется по умолчанию);

    • ipv4_only — использовать только IPv4;

    • ipv6_first — сначала использовать IPv6, в случае неудачи — использовать IPv4;

    • ipv6_only — использовать только IPv6.

  • dns_resolver_use_search_list — определяет, должна ли служба sssd пытаться дополнять доменные имена поисковыми суффиксами. По умолчанию используется значение TRUE, что может привести к задержкам в обработке запросов при неправильных настройках DNS. Например, если в файле /etc/sssd/sssd.conf в параметре ipa_server указать короткое имя, то служба sssd будет по очереди подставлять все известные суффиксы и проверять доступность полученных имен.

  • ldap_opt_timeout — значение параметра определяет время в секундах, за которое должен быть получен ответ на синхронный LDAP-запрос. Этот параметр напрямую не связан с настройками DNS, но если в качестве бэкенда используется обычный LDAP-сервер, то операция разрешения имен будет частью синхронного запроса на подключение к LDAP-серверу, поэтому значение ldap_opt_timeout должно быть обязательно больше значения dns_resolver_timeout.

Возможности службы systemd-resolved

В операционной системе Astra Linux есть служба systemd-resolved и сервер dnsmasq, которые как DNS-клиент Windows способны запоминать предпочтительный сервер и кэшировать DNS-ответы, включая ненайденные результаты (негативный кэш). Если хотите чёрный пояс по вопросам кэширования в DNS, читайте статью Как работает DNS в Linux. Часть 2: все уровни DNS-кэширования.

Рассмотрим подробнее службу systemd-resolved, в которой реализован следующий алгоритм разрешения доменных имен:

  • резолвер начинает обработку запроса с обращения к предпочтительному серверу. Если служба systemd-reolved была перезапущена, то предпочтительным сервером назначается первый DNS-сервер по списку;

  • обращение к DNS-серверам выполняется по кругу (round robin): если DNS-сервер окажется недоступен, то запрос будет направлен к следующему серверу по списку. При достижении конца списка служба перейдет к его началу;

  • при проверке каждого следующего сервера этот сервер назначается предпочтительным, поэтому при получении ещё одного параллельного запроса его обработка начнется с того сервера, на котором остановился поток, обрабатывающий предыдущий запрос;

  • резолвер попеременно выполняет попытки подключения по UDP с таймаутом 5 секунд и по TCP с таймаутом 10 секунд;

  • в рамках проверки каждого протокола резолвер совершает по 3 попытки с полным обходом всех DNS-серверов. Общая продолжительность попытки зависит от количества серверов, служба поддерживает более трех DNS-серверов;

  • обработка запроса прекращается по достижении 24 попыток разрешения запрашиваемого имени через серверы из списка либо по достижении лимита времени обработки запроса в 120 секунд;

  • все указанные значения (5 секунд ожидания для UDP, 10 секунд ожидания для TCP, 3 попытки обхода DNS-серверов, 24 попытки на разрешение запроса и общее время ожидания в 120 секунд) определены в программном коде как константы и их нельзя переопределить через конфигурационный файл.

А еще этот алгоритм дополнительно усложняется, если DNS-сервер поддерживает DNSSEC или DNS over TLS: в таком случае резолвер будет совершать несколько дополнительных подключений по этим протоколам. И как-то так, через хитро закрученную... висту, оно и работает, поэтому мы даже не станем пытаться рисовать график.

В Astra Linux Special Edition 1.7 служба systemd-resolved уже установлена вместе с systemd, но по умолчанию отключена.

$ sudo systemctl status systemd-resolved.service
systemd-resolved.service - Network Name Resolution
   Loaded: loaded (/lib/systemd/system/systemd-resolved.service; disabled; vendor preset: enabled)
  Drop-In: /usr/lib/systemd/system/systemd-resolved.service.d
           └─resolvconf.conf
   Active: inactive (dead)
     Docs: man:systemd-resolved.service(8)
           https://www.freedesktop.org/wiki/Software/systemd/resolved
           https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
           https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients

Включить службу systemd-resolved в ALSE 1.7 можно через systemctl командой enable с ключом --now, который сразу запустит службу:

$ sudo systemctl enable -now systemd-resolved.service
Created symlink /etc/systemd/system/dbus-org.freedesktop.resolve1.service → /lib/systemd/system/systemd-resolved.service.
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-resolved.service → /lib/systemd/system/systemd-resolved.service.

В Astra Linux Special Edition 1.8 служба находится в отдельном deb-пакете systemd-resolved из основного репозитория main, который нужно дополнительно установить с помощью пакетного менеджера:

$ sudo apt install systemd-resolved
...
$ apt policy systemd-resolved
 systemd-resolved:
   Установлен: 252.17-1~deb12u1astra.se3+ci2
   Кандидат:   252.17-1~deb12u1astra.se3+ci2
   Таблица версий:
  *** 252.17-1~deb12u1astra.se3+ci2 900
         900 https://download.astralinux.ru/astra/frozen/1.8_x86-64/1.8.2/uu/1/repository-main 1.8_x86-64/main
 amd64 Packages

Служба systemd-resolved запускает бинарник /lib/systemd/systemd-resolved и  начинает прослушивать порты 53/TCP и 53/UDP на адресах IPv4 127.0.0.53 и IPv6 :::5355.

$ netstat -ntlupaW | grep resol
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      13665/systemd-resol
tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      13665/systemd-resol
tcp6       0      0 :::5355                 :::*                    LISTEN      13665/systemd-resol
udp        0      0 127.0.0.53:53           0.0.0.0:*                           13665/systemd-resol
udp        0      0 0.0.0.0:5355            0.0.0.0:*                           13665/systemd-resol
udp6       0      0 :::5355                 :::*                                13665/systemd-resol

Чтобы переключить операционную систему Linux на использование кэширующего сервера systemd-resolved в некоторых инструкциях предлагается установить пакет libnss-resolve, который содержит модуль libnss_resolve.so.2, позволяющий перехватывать системные вызовы на разрешение имен через NSS и обрабатывать их напрямую через systemd-resolved, отправляя этой службе запросы по шине DBus. После установки пакета в файле /etc/nsswitch.conf в параметре hosts перед обращением к dns появится вызов модуля resolve:

$ cat /etc/nsswitch.conf | grep hosts
hosts:          files resolve [!UNAVAIL=return] dns

Рекомендация

Поскольку служба sssd и ряд других приложений (таких как hostnslookupdig) не обращаются к системным вызовам, а отправляют запросы к DNS-серверам напрямую, мы не рекомендуем устанавливать пакет libnss-resolve и использовать его NSS-модуль, т.к. это только усложнит процесс отладки.

Для переключения службы NetworkManager на использование кэширующего сервера systemd-resolved в некоторых инструкциях предлагается создавать символическую ссылку, которая будет указывать на файл /run/systemd/resolve/stub-resolv.conf. В этом случае служба NetworkManager автоматически поймет, что ей нужно переключиться на работу с systemd-resolved:

ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

Но данный способ мы не рекомендуем, т.к. он является, скорее, резервным, чем основным. Мы советуем в секции main конфигурационного файла /etc/NetworkManager/NetworkManager.conf определить параметры dns=systemd-resolved и rc-manager=symlink явным образом:

$ cat /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile
dns=systemd-resolved
rc-manager=symlink
[ifupdown]
managed=false

Рекомендация

Указывайте необходимость интеграции службы NetworkManager со службой systemd-resolved явно через параметры dns=systemd-resolved и rc-manager=symlink.

Чтобы изменения вступили в силу, нужно перезапустить службу NetworkManager:

sudo systemctl restart NetworkManager

После рестарта служба NetworkManager впишет адрес локального кэширующего сервера 127.0.0.53 в файл /etc/resolv.conf:

$ cat /etc/resolv.conf
# Generated by NetworkManager
search ald.company.lan
nameserver 127.0.0.53

Список необходимых DNS-серверов служба NetworkManager будет передавать в службу systemd-resolved напрямую через шину DBus. Текущее состояние резолвера можно будет посмотреть командой resolvectl status (или аналогичной командой systemd-resolve --status):

$ resolvectl status
...
Link 2 (eth0)
      Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
DefaultRoute setting: yes
       LLMNR setting: yes
MulticastDNS setting: no
  DNSOverTLS setting: no
      DNSSEC setting: allow-downgrade
    DNSSEC supported: yes
  Current DNS Server: 10.0.1.11
         DNS Servers: 10.0.1.11
          DNS Domain: ~.
                      ald.company.lan

Также может быть полезна при отладке команда resolvectl statistics (показывает, насколько используется кэш службы systemd-resolved).

Оптимизация настроек загрузки службы systemd-resolved

Учитывая важность функции разрешения имен для современных компьютеров, служба dnscache запускается в Windows автоматически при загрузке операционной системы и также автоматически перезапускается в случае падения. В процессе работы службы кэш очищается автоматически по мере старения записей в соответствии со значением их TTL (Time to Live), но полной очистки кэша при включении/выключении сетевых интерфейсов или изменении DNS-серверов не происходит. По указанной причине в домене настоятельно не рекомендуется использовать технологию "DNS Split", когда клиенты получают разные DNS-записи при работе из офиса и за пределами локальной сети. Полностью очистить DNS-кэш на Windows-компьютерах можно только вручную с помощью команды ipconfig /flushdns.

При настройке службы systemd-resolved на Linux-компьютере мы включили ее командой systemctl enable, поэтому при загрузке операционной системы эта служба и так будет запускаться автоматически. Для того, чтобы служба ещё и перезапускалась автоматически при падении, нам нужно будет настроить параметры Restart и RestartSec. Также, во избежание проблем с очередностью загрузки служб, установим ещё параметр Before, чтобы служба sssd запускалась гарантированно после загрузки службы systemd-resolved. Изменения будем вносить с помощью команды edit утилиты systemctl:

$ sudo systemctl edit systemd-resolved.service

В редакторе нужно определить следующее содержимое drop-in сниппета:

[Unit]
Before=sssd.service
[Service]
Restart=on-failure
RestartSec=2s

Сниппет будет сохранен в файле /etc/systemd/system/systemd-resolved.service.d/override.conf, изменения в конфигурации службы будут применены автоматически утилитой systemctl при выходе из редактора, поэтому вызывать systemctl daemon-reload вручную не потребуется.

Рекомендация

Настраивайте автоматический перезапуск службы systemd-resolved и зависимость от службы sssd.

Оптимизация настроек службы sssd

Исходя из особенностей алгоритма разрешения имен службами sssd и systemd-resolved, в секции домена настроек службы sssd рекомендуется задать следующие параметры:

  • dns_resolver_server_timeout — определяет максимальное время ожидания ответа от одного сервера (в миллисекундах). Если используется служба systemd-resolved, то она является единственным DNS-сервером (stub-резолвером), указанным на рабочей станции, поэтому значение необходимо установить в соответствии с максимальным временем ожидания этой службы. Так как максимальным временем ожидания ответа от сервера службой systemd-resolved является 5 секунд, то при наличии 3 серверов имён максимальное время опроса при недоступности всех 3 серверов составит 15 секунд или 15000 миллисекунд;

  • dns_resolver_op_timeout — определяет максимальное время ожидания на разрешение одного имени несколькими серверами (в секундах). Так как DNS-сервер один, выставлять значение больше, чем dns_resolver_server_timeout, не имеет смысла, поэтому ставим 15 секунд;

  • dns_resolver_timeout — определяет максимальное время для службы DNS на разрешение имен (в секундах). Следует выставить параметр равным разрешению двух DNS-имен, так как при невозможности автоматического обнаружения контроллера домена по SRV-записям служба sssd перейдет к разрешению имени того контроллера, через который хост был присоединен к домену (15 с * 2 = 30с).

Рекомендация

Используйте в конфигурации файла /etc/sssd/sssd.conf следующие параметры:

[domain/ald.company.lan]
dns_resolver_server_timeout = 15000
dns_resolver_op_timeout = 15
dns_resolver_timeout = 30
...

Краткая инструкция по настройке кэширования DNS в домене

Включите службу systemd-resolved и добавьте ее в автоматическую загрузку:

sudo systemctl enable --now systemd-resolved.service

Включите интеграцию между службами NetworkManager и systemd-resolved, добавив параметры dns и rc-manager в конфигурационный файл /etc/NetworkManager/NetworkManager.conf:

[main]
plugins=ifupdown,keyfile
dns=systemd-resolved
rc-manager=symlink
[ifupdown]
managed=false

Перезапустите службу NetworkManager, чтобы изменения вступили в силу:

sudo systemctl restart NetworkManager

Определите параметры перезапуска и зависимость от службы sssd. Откройте для этого сниппет dropp-in службы systemd-resolved на редактирование:

sudo systemctl edit systemd-resolved.service

Определите следующее содержание файла:

[Unit]
Before=sssd.service
[Service]
Restart=on-failure
RestartSec=2s

Оптимизируйте параметры разрешения имен в конфигурационном файле /etc/sssd/sssd.conf для работы со службой systemd-resolved:

[domain/ald.company.lan]
dns_resolver_server_timeout = 15000
dns_resolver_op_timeout = 15
dns_resolver_timeout = 30
...

Перезапустите службу sssd, чтобы изменения вступили в силу:

sudo systemctl restart sssd

Ключевые выводы

Операционная система Linux разрабатывалась в первое время как ОС для веб-серверов и серверов баз данных с высокой сетевой связанностью, поэтому ее базовые настройки не были оптимизированы для персонального использования, особенно в сценариях носимых устройств. Однако в дальнейшем система, конечно же, значительно продвинулась в этом направлении: была создана служба NetworkManager с графическим апплетом (2004 год), которая обеспечивает автоматическое переключение устройств на доступные беспроводные сети, в составе системы инициализации и управления сервисами systemd появилась служба systemd-resolved (2010 год), способная взять на себя роль полноценного DNS-клиента, а между службами NetworkManager и systemd-resolved была выполнена тесная интеграция (2016 год).

Кроме того, служба systemd-resolved была не первой: эту же задачу можно решить ничуть не хуже с использованием более тяжеловесной функциональной службы dnsmasq. Тем не менее настройки по умолчанию всё ещё находятся в гравитационном поле предыдущего опыта, и чтобы вырваться к новым звездам, нам нужно выбрать действительно лучший способ настройки и разогнать его использование до третьей космической, что мы и называем лучшими практиками.

Мы считаем, что разработчики программного обеспечения должны брать на себя ответственность не только за написание надежного кода, но и за выработку рекомендаций по использованию открытых компонентов, на базе которых они создают свои решения. Иначе получается, что все необходимые компоненты есть, а как приготовить из них достойное блюдо, неизвестно. И мы крайне благодарны инженерам нашего сообщества ALD Proфессионалы за помощь в обсуждении этих рекомендаций, их проверку в реальной инфраструктуре и конструктивную критику. За последний год продуктовая команда организовала десять фокус-групп на 300+ участников, и результаты каждой из них помогли сделать ALD Pro лучше, поэтому текущая зрелость продукта - это наша общая победа!

Вместе с тем, одних только рекомендаций далеко не достаточно. Нужно, чтобы эти рекомендации появлялись в открытом доступе, за что спасибо Вячеславу Нигай и его команде, которая оперативно вносит эти наработки в открытый курс по службе каталога ALD Pro. Важно, чтобы эти рекомендации начинали применяться в реальной ИТ-инфраструктуре, и тут уже не обойтись без помощи наших партнеров: интеграторов, которые помогают внедрять лучший опыт, и обучающих центров, которые могут обеспечить трансфер компетенций. Коллеги, огромное спасибо вам за эту неоценимую помощь. Совместными усилиями проекты замещения становятся вполне реальны и достижимы!

Комментарии (3)


  1. rearranged
    09.10.2025 08:56

    Хороший материал! Спасибо! Отлично расширяет область практического применения! Погружает в реальные условия эксплуатации со спецификой Astra и Windows


  1. ildarz
    09.10.2025 08:56

    Если настройками определено три DNS-сервера, то порядок разрешения имён по умолчанию выглядит следующим образом 

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

    ptions attempts:1 timeout:1. По нашему мнению, при хорошей доступности DNS‑серверов задержки в одну секунду вполне достаточно для обработки запросов

    Априори я не был бы так уверен. Допустим, в локалке для доменного сервера это так, но некэшированные запросы адресов из "чужих" доменов могут проходить сложными путями. Было бы интересно помониторить среднестатистический корпоративный комп на предмет времени разрешения имен, конечно. :)


    1. prundukevich
      09.10.2025 08:56

      Касательно Windows - в статье, на которую вы ссылаетесь, описан упрощённый алгоритм. Да и мы у себя тоже упрощали. Когда проверяли, добавляли до 10ти DNS-серверов и штуки 4 сетевые карты, если я правильно помню.
      По большому счёту с одной стороны редко, когда используется больше 2-3х серверов на сетевую (это уже был чисто академический интерес "а как оно там на самом деле"). А с другой стороны важно было именно, что винда а) перебирает, б) "залипает" на успешно ответившем.