Безопасность и тюнинг DNS в Windows Server

Настраиваем DNS в Windows Server серьёзно и по-взрослому - с учётом всех тонкостей

Привет.

DNS – важная инфраструктурная служба. Настолько, что в предыдущей статье на тему безопасности DNS использовалась специальная иллюстрация:

В принципе, мало что изменилось – поэтому в данной, обновлённой версии статьи про безопасность DNS в Windows Server, я расскажу про то же самое, но уже детальнее. Будет рассматриваться Windows Server 2012 R2 и Windows Server 2016 – оба со всеми обновлениями на апрель 2016 года, для тюнинга будет использоваться ATcmd, в общем – работы много.

Безопасность и тюнинг DNS в Windows Server 2012 R2 и 2016

  • Механизм SocketPool – защищаемся от предсказуемости DNS-порта
  • Secure cache against pollution – защищаемся от отравления DNS-кэша
  • Блокируем раннее обновление кэша – Cache Locking
  • Привязка DNS-сервера к сетевым интерфейсам
  • Удалённое управление DNS-сервером
  • Настраиваем Global Query Block List
  • Отключение обработки рекурсивных запросов
  • Ограничение времени кэширования записей
  • Отключаем AXFR / IXFR трансфер у зон, интегрированных в Active Directory
  • Ограничение числа Resource Record’ов (RR) в ответе DNS-сервера
  • Настройка BIND secondaries
  • Настройка тайм-аута AXFR / IXFR трансфера
  • Настройка времени блокировки AXFR / IXFR трансфера
  • Фильтрация Name checking
  • Механизм Aging/Scavenging в DNS
  • Работа Round Robin и Netmask Ordering
  • Блокировка динамической регистрации по типу RR
  • Настройка EDNS0 в Windows Server 2012 R2
  • Настройка DNS-форвардеров в Windows Server
  • Ускоряем загрузку DNS-зон в Windows Server 2012 R2 и старше

Начнём.

Механизм SocketPool – защищаемся от предсказуемости DNS-порта

SocketPool появился как способ противодействия описанной в KB 953230 уязвимости, называемой иногда “Kaminsky bug”. Суть достаточно проста. В версиях Microsoft DNS до NT 6.1 для отправки данных DNS-сервера стартово инициализировался один сокет, от которого шло взаимодействие (в частности – ответы на UDP-запросы клиентов). Один сокет = разовая инициализация = одинаковый случайный ID транзакции. Это позволяло проводить атаку на перебор вариантов ID и с определённой вероятностью отравить кэш DNS-сервера путём отправки ему “заранее” неправильного ответа на предсказуемый запрос. А после, соответственно, DNS-сервер отдавал бы клиентам неправильную информацию из своего кэша, таким образом перенаправляя трафик туда, куда надо нарушителю.

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

Настройка SocketPool

По умолчанию пул равен 2.500 сокетам (притом, замечу, под пул выделяется одинаковое число и IPv4-портов, и IPv6 – т.е. в сумме по умолчанию зарезервированно 5 тысяч портов), но если ваш DNS-сервер обрабатывает запросы от внешних клиентов – увеличьте пул до 10К (если попробовать больше, выдаст DNS_ERROR_DWORD_VALUE_TOO_LARGE с кодом 9567). В случае, если DNS-сервер локальный – допустим, это DNS-сервер контроллера домена, и к нему обращаются клиенты из внутренней сети – стандартных 2.500 сокетов хватит.

Команда для задания количества сокетов, которые под себя “застолбит” сервис DNS:

Посмотреть текущую ситуацию с выделенными для SocketPool сокетам также можно в сводной информации по расширенным настройкам DNS server’а:

Как видно, параметр этот не одинок – продолжим про остальные.

Возможные проблемы, связанные с SocketPool, и настройка исключений

Возможные проблемы связаны с тем, что DNS Server застолбит под себя много UDP-сокетов, и различное ПО может от этого не иметь возможность сделать то же самое. Известный пример – это WDS (Windows Deployment Services). Эта служба резервирует для себя диапазон портов с 64.000 по 65.000, и в случае, когда DNS Server заберёт нужное число под SocketPool, могут возникнуть проблемы из-за наложения диапазонов DNS и WDS. Они решаемы, благодаря тому, что в WDS, который в Windows Server 2012 R2, встроен механизм динамического выбора портов. Включается он достаточно просто:

Замечу, что данный случай, когда существует штатный способ обойти ситуацию – единичная редкость. Вообще, так как механизм SocketPool резервирует под себя непрерывный блок UDP-портов, находящихся в верхней четверти всего доступного диапазона – т.е. с 49К и до 64К (это лишь 16К портов), то немудрено, что блок в 10К будет занимать много места и, возможно, конфликтовать с другими сервисами на том же хосте. Поэтому есть механизм, который позволяет исключить один или более диапазонов из SocketPool. Это делается специальной настройкой – штатного интерфейса у неё нет, поэтому выглядеть, например, исключение из пула портов диапазона 62000-63000, будет так:

Дополнительной и достаточно хитрой проблемой будет сценарий “Мы когда-то обновлялись с Windows Server 2003”. В этом случае в реестре может остаться технический параметр сетевого стека, актуальный до-NT-6.0 – т.н. MaxUserPort. Данный параметр ограничивает сверху диапазон выдаваемых приложению портов. То есть, если этот параметр есть, Windows Server 2012 R2 поменяет логику выдачи портов для DNS-сервера с “выдавать из диапазона 49K – 64K” на устаревший “выдавать с 1024 порта по MaxUserPort”. Поэтому для нормальной работы этот параметр надо, в случае его присутствия, удалить, он от устаревшей версии Windows Server и сейчас не нужен:

Суммаризируем советы по этому масштабному пункту:

  • Выставляем SocketPool везде в 2.500 – за исключением тех DNS-серверов, которые опубликованы в Интернет. У них – 10.000.
  • Заранее отключаем устаревшее управление диапазоном выделяемых портов, которое MaxUserPort. Оно нам сейчас только мешает и всё путает.
  • В случае острой необходимости используем исключения из диапазона SocketPool, чтобы не конфликтовать с другими сервисами, которые тоже хотят зарезервировать для себя ‘слушающие ‘UDP-порты.

Теперь двигаемся дальше.

Secure cache against pollution – защищаемся от отравления DNS-кэша

Идея этой настройки, появившейся ещё в Windows NT 4.0, и включенной по умолчанию с Windows Server 2003, проста. Она состоит в том, чтобы читать из ответа DNS-сервера только запрашиваемые ранее сведения, и игнорировать остальные. Рассмотрим пример.

Допустим, на DNS-сервер пришёл запрос от клиента – “хочу A-запись с именем msdn.microsoft.com”. DNS-сервер посмотрел в зонах, расположеных на нём – не нашёл. Потом посмотрел у себя в кэше – тоже нет. ОК, на DNS-сервере включена рекурсия. Он запрашивает другой сервер (например, DNS провайдера или какой-нибудь публичный) и ждёт ответ. И сервер присылает ему ответ – вида “msdn.microsoft.com доступен по адресу 1.2.3.4”. Но иногда сервер хочет помочь – вдруг следующим запросом Вы захотите microsoft.com? И он присылает не только msdn.microsoft.com, но и ту информацию, которую он выяснил попутно – адрес microsoft.com. По умолчанию ответ обрабатывается и добавляется в кэш, т.к. предполагается, что сервер хороший, и присылает только полезную и нужную информацию.

Но жизнь жёстче.

Поэтому надо включать параметр secure cache against pollution, чтобы исключить даже теоретическую возможность получения недостоверной информации из DNS-ответа.

Проще всего сделать это через консоль управления сервером – открыть Properties, вкладку Advanced и установить нужное значение.

Блокируем раннее обновление кэша – Cache Locking

Механизм Cache Locking появился в Windows Server 2008 R2 и, по сути, является дополнительной мерой безопасности для защиты от “Kaminsky bug”. Работает Cache Locking просто – на какое-то время запрещает обновление успешно закэшированных записей. Параметр задаётся в процентах – допустим, если установить его в 50, то в случае, если Ваш сервер закэширует какую-нибудь запись, TTL которой равен 6 часам, все попытки обновить её на протяжении первых 3х часов будут игнорироваться. Установка параметра в 100, как понятно, приведёт к блокировке всех запросов на обновление имеющихся в кэше записей. Это – рекомендованное значение данного параметра, т.к. обычно Вы запрашиваете какую-то DNS-запись, сервер узнаёт про неё информацию и кэширует – перезапись “на лету”, пока не истекло время кэширования, не предполагается.

Настраиваем данный параметр:

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

Привязка DNS-сервера к сетевым интерфейсам

По умолчанию DNS-сервер слушает трафик и реагирует на запросы со всех интерфейсов. Это включает в себя все IPv4-адреса и все IPv6 (как unicast’ы, так и link local’ы). Да и при добавлении нового интерфейса он будет сразу же использоваться службой DNS. Имеет смысл из соображений предсказуемости переключить эту настройку на явное указание адресов, на которых DNS-сервер будет принимать трафик. Например, если в инфраструктуре не используется IPv6, а DNS Server настроен “по умолчанию”, и на его интерфейсах включен сетевой компонент IPv6, он (DNS Server) будет обрабатывать запросы, пришедшие на адрес link local (вида fe80::идентификатор хоста), что является в указанной ситуации не нужным и не должно, согласно принципу Уильяма Оккама, существовать. Также не очевидно, что в случае установки нового сетевого соединения с хоста, на котором запущена служба DNS Server, подразумевается, что надо сразу же начать обрабатывать запросы клиентов, пришедшие на новопоявившийся интерфейс.

Как настраивается привязка DNS-сервера к сетевым интерфейсам

Необходимо зайти в настройки DNS Server, выбрать Properties и на вкладке Interfaces в явном виде выбрать только те адреса, на которые нужно принимать dns-запросы. Вот так:

Удалённое управление DNS-сервером

DNS-сервером можно управлять дистанционно через три технологически различных способа – это прямое подключение по TCP/IP (в данном случае, по сути, обычно и называемое RPC), отправка команд через Named Pipes и локальный вызов процедур (LPC). Имеются в виду, безусловно, способы подключения именно к службе и COM-объектам DNS-сервера, а не к хосту, на котором эта служба запущена. Так вот, если ваш DNS-сервер администрируется не всеми из них – а так обычно и бывает – то лишние надо выключать. Если это, допустим, опубликованный наружу DNS-сервер, который установлен на отдельной виртуальной машине, и управление осуществляется путём подключения администратора по RDP, то ничего, кроме LPC (чтобы MMC-консоль работала) серверу не нужно. Если это инфраструктурная виртуалка, к которой подключаются удалённой оснасткой, то ей надо только RPC поверх TCP/IP, никакие named pipes ей не нужны. Данная настройка (для случая с LPC) будет выглядеть так, иные варианты делаются по аналогии:

Настраиваем Global Query Block List

Глобальный блок-лист имён – достаточно интересная штука. Необходимость его использования вызвана тем, что в случае использования хостами динамической регистрации DNS-имён возможна ситуация, когда злонамеренный участник зарегистрирует well-known имя, которое используется сетевой службой (например, wpad или isatap). Имя другого компьютера или сервера ему зарегистрировать, в случае существования оных и включённого механизма secure updates, не дадут, а вот wpad допустим – пожалуйста, ведь сервера с таким именем нет, это служебный идентификатор. А после – данный компьютер будет отвечать на запросы пытающихся автоконфигурироваться клиентов вида “а дайте мне настройки” по адресу “http://wpad.имя_домена/wpad.dat”, отдавая им то, что посчитает нужным. Это неправильно. Ну и второй вариант злонамеренного использования – удалённый пользователь может получить информацию об инфраструктурных сервисах, запросив эти технические resource record’ы. Соответственно, GQBL нужен для того, чтобы отсечь эти возможности.

Как этот механизм будет работать? Рассмотрим вариант для наличия в GQBL стандартного имени wpad.

При добавлении имени в GQBL будут игнорироваться запросы для всех типов записей (это важно – не только A и AAAA, а всех) для всех зон, для которых данный сервер является authoritative. То есть, допустим, если на сервере есть зоны domain.local и _msdcs.domain.local, то запросы wpad._msdcs.domain.local и wpad.domain.local, несмотря на фактическое наличие/отсутствие данной записи, будут возвращать ответ, что запись не найдена.

Замечу, что если что – это можно обойти, если создать зону с именем wpad.domain.local и в ней – пустую запись нужного типа. В именах зон проверка не происходит. Уязвимостью это не является, т.к. удалённо динамически зарегистрировать зону нельзя.

Запросы для других зон (не находящихся на сервере) под это подпадать не будут (т.е. wpad.externaldomain.ru под этот механизм не подпадёт).

Интересным является также момент про то, как данный механизм работает с логами. При первой блокировке в журнал пишется событие, где написано, что запрос от такого-то клиента заблокирован по причине нахождения искомого в GQBL. После запись уже не ведётся. Это не баг, а защита от простейшей атаки – переполнения журнала путём отправки огромного количества запросов на предсказуемо блокируемый FQDN. После перезапуска сервера счётчик сбросится на нуль и опять – первая блокировка будет записана в журнал, далее – нет.

Теперь настройка.

Настройка Global Query Block List на Windows Server 2012 R2

Включить этот фильтр на уровне сервера просто:

Задать содержимое – тоже несложно. Можно задать весь лист целиком, редактировать каждую запись отдельно – увы, только через реестр:

Отключение обработки рекурсивных запросов

Данная опция нужна только в одном сценарии – когда ваш DNS-сервер нужен исключительно для разрешения имён в тех зонах, которые на нём расположены, и не обслуживает произвольные запросы клиентов. Это, говоря проще, выделенная машина – например, для поддержки интернет-доменов предприятия, или в случае делегирования провайдером reverse lookup’ов (см. Создание обратной зоны с нестандартной маской).

В упомянутых случаях DNS-сервер должен отвечать исключительно на один тип вопросов – про те зоны, которые ему явно известны и локально находятся. Абстрактные же запросы вида “а поищи-ка мне вот такое вот имя” не нужны и приводят к потенциальной DoS-атаке.

Отключение рекурсии выглядит так:

Как понятно из названия, вместе с ней отключаются и форвардеры – это логично, т.к. серверу без рекурсии форвардеры не нужны – он принципиально не обрабатывает запросы, для которых может понадобиться запрос какого-либо другого сервера.

Ограничение времени кэширования записей

Записи, которые DNS-сервер получил от других DNS-серверов, не только передаются запрашивающим клиентам, но и кэшируются на сервере. Время кэширования указано в самой записи – у неё есть личный TTL.

В ряде случаев имеет смысл сделать работу более динамичной и ускорить актуализацию записей, установив максимальный TTL для всех RR’ов на сервере. Простой пример – некто установил огромный TTL (например, 42 дня), а по факту запись иногда меняется. В этом случае пока запись не устареет в кэше, ваш DNS-сервер будет давать неверный/устаревший ответ. Проще указать некую верхнюю границу – допустим, сутки – и записи с любыми TTL не будут храниться в кэше дольше этого срока, и сервер будет их запрашивать. Ничтожный рост трафика (один доп.пакет в день) гораздо лучше, чем, допустим, три недели испытывать проблемы с электронной почтой, потому что кто-то обновил MX, но забыл, что TTL выставлен огромный, поэтому изменение по факту применится очень нескоро. Этому, кстати, способствует тот момент, что в интерфейсе Microsoft DNS Server изменение TTL у DNS-записи доступно только в расширенном режиме работы. Вот как окно редактирования DNS-записи выглядит обычно:

А вот как в случае, когда в меню View включён пункт Advanced:

Не забывайте про то, что нужно выставлять разумные TTL у записей. Ну а теперь как ограничить максимальный срок жизни записи в кэше DNS-сервера:

86400 – это секунд в сутках, как понятно.

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

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

Я поставлю время кэширования негативного ответа в 5 минут:

Отключаем AXFR/IXFR трансфер у зон, интегрированных в Active Directory

В том случае, если все сервера, на которых находится определённая зона, расположены на контроллерах Active Directory, то наличие возможности трансфера зоны стандартным способом – AXFR / IXFR запросом по TCP 53 является уязвимостью, так как может помочь потенциальному злоумышленнику узнать дополнительные сведения об инфраструктуре. Притом достаточно простым способом – например, подключившись при помощи nslookup и выполнив команду ls. Нормальная же репликация зоны происходит через механизмы LDAP-репликации Active Directory.

Отключаем просто – открываем свойства (Properties) у нужной DNS-зоны, выбираем вкладку Zone Transfers:

Это надо сделать не только у зон, интегрированных в Active Directory, но и у всех копий зоны, находящихся на secondary-серверах, с которых не забирают копию другие secondary-сервера.

Ограничение числа Resource Record’ов (RR) в ответе DNS-сервера

Данная настройка позволит обойти одну редкую, но неприятную проблему, связанную с разным поведением DNS-клиентов. Суть проста – в случае, когда в ответ надо добавить много записей, и, несмотря на EDNS0 и прочие ухищрения, они не влезают, у ответа ставится бит “неполный” – т.н. “truncation bit”. По идее, после получения ответа с таким битом, запрашивающий должен насторожиться и переспросить повторно, но уже по TCP (не забывайте, DNS-сервер умеет отвечать на запросы не только по UDP), чтобы получить не-урезанный ответ. Однако так поступают не все клиенты. Более того, высока вероятность того, что где-то в цепочке передачи рекурсивного запроса кто-то один не будет поддерживать запросы/ответы по TCP, поэтому информация просто потеряется – грубо говоря, клиент, получив не полный ответ, а урезанный, запросит иным способом, а в ответ – тишина, в результате клиент может решить, что имя просто не разрешилось полноценно.

Чтобы минимизировать вероятность этой ситуации, нужно сделать ряд шагов.

Первым делом – разберитесь с максимальным размером UDP-ответа. Чем лучше разберётесь – тем ниже вероятность возникновения упомянутой ситуации.

Вторым – проверьте, все ли ваши DNS-сервера отвечают по TCP. Для этого в ATcmd есть встроенный тест – команда test dns ports, которой надо лишь указать имя домена (например, локального домена Active Directory) – она найдёт все NS-сервера за этот домен, и попробует запросить у каждого и UDP- и TCP-вариант ответа. Обеспечение возможности клиентов посылать вашим DNS-серверам запросы через TCP – это тот минимум, который вы можете сделать, т.к. не можете влиять на все DNS-сервера в рекурсивной цепочке. Примитивный подход “DNS работает только через UDP, через TCP только трансфер зон, поэтому TCP за исключением трансфера надо блочить на firewall’е” не работает – вы решите массу проблем и уберёте непонятные сбои, если клиенты смогут нормально переспрашивать DNS-сервер по TCP.

А теперь можно и ограничить число RR в DNS-ответе. Я поставлю 28 (это максимальное ограничение).

Это обозначает то, что я уверен, что у меня нет ни одной записи, которая разрешается сразу в более чем 28 ответов, но если таковые есть (допустим, чужие, после рекурсивного запроса) – клиенту будет возвращаться не “сколько влезло плюс пометка, что влезло не всё”, а только 28 лучших. Сценарий с возвратом большого числа записей возможен, в принципе, в паре основных случаев – когда запрашивается разрешение имени какого-то высоконагруженного ресурса (в ответе пачка A и AAAA), или когда во внутренней сети запрашивается Active Directory-специфичная корневая или SRV запись (допустим, за корень домена в DNS регистрируются все DC – поэтому в больших доменах очевидна ситуация, когда ответ на вопрос “а кто у нас хост за domain.local” возвращает опять же большую пачку A- и AAAA-записей). В этом случае нужно оперировать настройками сервера по части приоритета выдачи только нужных ответов, а не всех, и максимально избегать линейного решения ситуации “вот тебе в ответ на запрос 250 A-ответов про все DC в домене, делай что хочешь”.

Настройка BIND secondaries

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

Для настройки этой опции нужно выбрать свойства (Properties) у сервера DNS, там – вкладку Advanced, а после выбрать соответствующий параметр:

Выключение BIND SecondariesВыключение BIND Secondaries
(кликните для увеличения до 414 px на 480 px)
Учебный центр Advanced Traininginfo@atraining.ru

Настройка тайм-аута AXFR / IXFR трансфера

По умолчанию трансфер DNS-зоны считается несостоявшимся, если тайм-аут со стороны отвечающего сервера превысил 30 секунд бездействия. Этот параметр можно и нужно править – например, снизить до 15 секунд, чтобы раньше “отсекать” ситуации, когда сервер не осуществляет трансфер, а просто подключился и сидит. Хорошие DNS-серверы так себя не ведут, действуют быстро и закрывают TCP-сессию тоже оперативно. Правим:

Настройка времени блокировки AXFR / IXFR трансфера

Одной из загадок в поведении Microsoft DNS Server, обнаруживаемой в начале использования, является то, что после удачной передачи зоны с одного сервера на другой, и быстрого рефреша консоли нажатием F5, вылезает ошибка “Всё, трансфер зоны сломался”. В самом деле, чему там ломаться-то в такой ситуации?

Ломаться действительно нечему – просто срабатывает механизм защиты primary DNS от перегрузки. Логика следующая:

  • Допустим, что у нас есть DNS-зона, которая расположена на 1 primary DNS-серверах и на 100 secondary. Притом все secondary обновляют её исключительно с primary, т.е. никакой иерархии secondary нет.
  • Один из secondary начинает скачивать зону. Пока он это делает, в эту же зону хочет записаться dynamic update какой-либо записи. Допускать этого нельзя, поэтому на зону на время трансфера накладывается write lock.
  • Зона успешно передана – write lock снят, записи в зону произведены, и primary уведомляет всех secondary (через механизм DNS Notify), что есть изменения. Все они приходят качать зону, она опять блокируется от записей.

Такие “качели” приводят к тому, что зона непрерывно крутится в цикле “накопить пачку отложенных записей – массово раздать зону”. По сути, ради каждого единичного обновления все сервера подрываются полностью передавать зону (мы ж не уверены, что у всех есть IXFR). Вот для блокировки этого и нужен данный параметр. Время блокировки считается просто – количество секунд, по факту потраченное на последний успешный трансфер зоны (параметр хранится для каждой DNS-зоны на DNS-сервере отдельно), домножается на коэффициент, и результирующее число – это тот интервал, когда все запросы на трансфер будут безусловно отвергаться (в логах у secondary вы увидите событие 6525, “primary server refuses zone transfer”). Если этот параметр установить явно в нуль, то механизм полностью выключится – вы можете сделать так в случае, если подобная защита не нужна (малое число DNS-серверов), тогда ваша зона будет актуализироваться максимально быстро. Я просто уменьшу данный параметр с 10 (значение по умолчанию) до 3 раз – т.е. если зона передаётся за 3 секунды, следующие 9 секунд все запросы на трансфер будут отклоняться.

Фильтрация Name checking

Настройка Name Checking на уровне DNS Server’а указывает на то, по каким критериям будут фильтроваться имена в запросах. То есть в случае, если имя в запросе подпадает под выбранную логику проверки – запрос обрабатывается, если нет – то считается ошибочным и отбрасывается. Вариантов настройки будет четыре:

Вариант Strict RFC (ANSI)

В запрашиваемых именах могут быть только символы, которые указаны в RFC 952 и RFC 1123. Т.е. подмножество семибитовых ASCII-символов, case insensitive, по сути – только английские буквы, цифры и минус/тире/дефис.

Вариант Non RFC (ANSI)

Strict RFC плюс подчёркивание.

Вариант Multibyte (UTF8)

Имена могут быть в Unicode (RFC 2181).

Вариант All Names

Фильтрация не производится, сервер пытается обработать все полученные строки.

Что выбрать? Тут всё достаточно сложно. Ситуаций много. Например, если ваш DNS-сервер держит исключительно внешние зоны, в которых нет хостов с именами, использующими символы национальных алфавитов, и предназначен он лишь для этой задачи (т.е. на нём нет рекурсии), то имеет смысл использовать Non RFC. Для обычного сервера, который кэширует запросы клиентов, подойдёт Multibyte. Отключать фильтрацию целиком нецелесообразно.

Фильтрация по размеру FQDN – каждый компонент не более 63 байт и все в сумме – не более 255 – всегда сохраняется и не редактируема.

Наглядный пример – то, что на картинке, может быть только на сервере, который настроен не на Strict RFC / Non RFC:

Если у данного сервера поменять настройку на Strict RFC и сделать на зоне Reload, то запись тихо пропадёт – сервер проигнорирует её при загрузке. А если после вернуть настройки на All Names и опять сделать Reload – запись опять появится.

Как настраивается фильтрация Name Checking в Windows Server 2008 R2 DNS

Для настройки этой опции нужно выбрать свойства (Properties) у сервера DNS, и там – вкладку Advanced, а после выбрать необходимый режим.

Механизм Aging/Scavenging в DNS

Динамически добавленные в DNS-зону записи не умеют пропадать сами. Это не баг, это так положено. В WINS (который NBNS) (не к ночи он будет помянут) этот механизм был штатным, а вот в DNS – увы. Поэтому фирма Microsoft добавила данный механизм в свою реализацию DNS Server. Как он будет работать?

У каждой динамически зарегистрированной записи будет указываться time stamp – время последнего успешного изменения этой записи. После, на протяжении no-refresh time (по умолчанию – 7 дней), все обновления этой записи будут игнорироваться. В оригинале, когда этот механизм был в WINS, это было нужно, чтобы информация о записи “расползлась” по инфраструктуре, сейчас делается с другими целями. Когда no-refresh time закончится, у записи начинает бежать обратный отсчёт – refresh-time. Это время, в течении которого запись должна обновиться. Если она не обновится за это время (по умолчанию – тоже 7 дней), то она является кандидатом на удаление. И вот тут-то, если на уровне сервера включен механизм Scavenging of stale records, такие записи будут удаляться. Делается это раз в сутки (если включен автоматический режим), либо вручную.

Этот механизм полезен, т.к. при должной настройке будет эффективно удалять ненужные DNS-записи, например, переименованных или удалённых из домена рабочих станций.

Не забывайте, что механизм включается и на уровне сервера, и на уровне зоны. Чтобы механизм функционировал, необходимо включить его и там и там. Т.е. и зона должна одобрять идею автоматической очистки, и конкретный сервер знать, что периодически надо удалять записи, не обновлённые уже X дней.

Включать данный механизм полезно ещё по одной причине. Мало того, что он будет удалять устаревшие записи. Он ещё будет, вводя no-refresh interval, уменьшать трафик репликации Active Directory. Т.е. если за время no-refresh interval придёт запрос на динамическое обновление записи, и в нём не будет ничего нового, кроме продления срока жизни, то без механизма aging/scavenging этот запрос будет отработан и в зону будет произведена запись (бессмысленная), что вызовет репликацию раздела Active Directory, в котором находится эта запись. А в случае, если механизм будет включен, сервер посмотрит, и если запрос не будет содержать никакой новой информации (ну, например, машину просто перезагрузили – она ту же A-запись пытается зарегистрировать, по сути – просто сбросить time stamp), он будет проигнорирован. Это никак не повлияет на качество работы DNS, а вот новую репликацию не инициирует. Профит!

Как включается Aging/Scavenging в Microsoft Windows Server 2008 R2 DNS

Первое – включаем на уровне сервера. Этот пункт находится в настройках сервера (Properties), вкладке Advanced, снизу. Время, задаваемое там – это критерий очистки. Т.е. раз в сутки сервер, на котором это включено, будет находить все динамически зарегистрированные записи, которые не обновлялись указанное в настройках время, и удалять их. Можно указать этот параметр достаточно большим – я указываю 30 дней, если рабочая станция месяц не обновляла свою запись – наверное, смысла жить в DNS ей больше нет. Вернётся – заново зарегистрирует.

Второе – включаем на уровне зоны. Задаём no-refresh и refresh интервалы. Обычно стандартное время менять не нужно. В общем, всё.

Работа Round Robin и Netmask Ordering

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

Как будет вести себя DNS-сервер в зависимости от их настроек:

  • Если оба параметра выключены, то клиенту в ответ на запрос возвращается всегда одинаковый комплект A- и AAAA-записей, порядок их не меняется.
  • Если включен только Netmask Ordering, то из списка всех A- и AAAA-записей хоста будут выбраны те, у кого первые N бит совпадают с source address клиентского запроса, и эти записи будут помещены в верх списка по критерию “чем больше бит совпало, тем лучше”. Обратите внимание на то, что source address – это, в случае рекурсии, всё время одинаковый адрес вашего DNS-сервера, который форвардит запросы наружу, поэтому фактически Netmask Ordering нужен только на сервере, к которому напрямую подключаются клиенты, и хорошо подходит, допустим, для задачи “дай список DC за домен”, где клиент и DC в региональном филиале скорее всего будут в одном сегменте сети.
  • Если включен только Round Robin, то A- и AAAA-записи в ответе перемешиваются каждый раз, благодаря чему простые реализации DNS client’ов, которые берут первый попавшийся ответ, математически ровно распределяют попытки подключения между хостами.
  • Ну а если включены оба режима, то вначале отработает Netmask Ordering, а не подпавшие под него записи будут перетасованы Round Robin’ом.

Данные параметры полезные и выключать их особо не требуется – вреда от них нет.

В случае же, если вам нужно исключить какой-либо тип RR из ротации round robin – т.е. надо, чтобы записи именно этого типа отдавались клиенту вот именно в одном и том же порядке всегда – то есть специальная команда:

Посмотреть исключённые в данный момент типы записей можно как обычно, командой show dnsserver.

Блокировка динамической регистрации по типу RR

В зонах, где разрешена динамическая регистрация, возможно указание того, какие именно типы записей можно обновлять динамически, а какие – нет. Это логично – разрешая динамическое обновление зоны (что безопасное, что обычное), администратор обычно подразумевает, что туда могут регистрироваться новые хосты. А вот что можно удалённо записать произвольную SOA, NS, или сделать NS-делегирование – это, в общем, неправильно.

Для управления этим есть параметр updatetypes, текущие настройки его можно посмотреть той же командой show dnsserver:

Вывод show dnsserver в atcmdВывод show dnsserver в atcmd
(кликните для увеличения до 705 px на 454 px)
Учебный центр Advanced Traininginfo@atraining.ru

Задавать его придётся битовой маской, где каждый бит – это разрешение или запрет для динамической регистрации определённого типа RR. В одном DWORD собраны настройки и для всех зон, поддерживающих только безопасные обновления, и для всех зон, поддерживающих обычные динамические обновления:

Практический пример применения этого параметра – допустим, у вас есть домен Active Directory с названием kontora.local. Вы хотите, чтобы все сетевые принтеры в фирме были подключены не по IP-адресам, а по DNS-именам. Принтеры умеют, получив новый адрес от DHCP, динамически зарегистрироваться в DNS – но не умеют делать это безопасно, т.к. не имеют учётной записи в Active Directory. Ради принтеров ослаблять безопасность основной DNS-зоны домена – неправильно. Можно сделать субдомен prn.kontora.local и сказать принтерам регистрироваться в нём. Но тогда неплохо бы подстраховаться, чтобы они регистрировали именно A-записи, а вот например NS чисто технически обновить было бы нельзя (чтобы не было атаки на добавление rogue-DNS, в котором под A-записями принтеров будут скрываться узлы, которые будут делать что-то нехорошее).

Настройка EDNS0 в Windows Server 2012 R2

Данный блок настроек, из-за своей неочевидности и необходимости подробно разобрать лежащие в их основе технологии, вынесен в отдельную статью на нашей Knowledge Base – https://www.atraining.ru/edns0-windows-server/. Относится он скорее к тюнингу, чем к безопасности, но это никак не снижает его нужности.

Настройка DNS-форвардеров в Windows Server

Стандартное окно, где можно добавить форвардеры – очень простое.

В случае работы с conditional forwarders, которые появились с Windows Server 2003, вам разве что добавляется возможность повлиять на тайм-аут запроса – мол, если за это время DNS-сервер не ответит, запрос считается пропавшим без вести.

Но на самом деле возможностей настройки – гораздо больше.

Командлет Set-DnsServerRecursion поможет настроить более тонкую обработку рекурсии. Какие у него будут параметры?

Параметр -SecureResponse

Данный параметр очень ценный – он будет указывать, проверять ли ответ удалённого сервера на возможность cache pollution. То есть, допустим сценарий – вы сделали conditional forwarder, который говорит, чтобы все запросы вида *.atraining.ru перенаправлялись на адрес 178.159.49.230. Обычно подобные conditional forwarder’ы используются как обеспечение разрешения партнёрских внутренних DNS-зон в рамках forest trust – поэтому простой вопрос – а есть ли смысл, чтобы хост 178.159.49.230 передавал информацию дальше, если не найдёт у себя? По идее нет – вы указываете DNS-серверы партнёра, которые являются authoritative за его зону. Вот, используя этот параметр, можно указать – как в данном случае будет вести себя ваш сервер, получив ответ – поверит в любом случае или удостоверится, что присылающий сервер является авторитативным за зону, из которой пришёл ответ.

Параметр -Timeout

Стандартный тайм-аут ответа удалённого сервера – 15 секунд. Вы можете повлиять на этот параметр – увеличив его (тогда далёкие сервера будут успевать отвечать), или уменьшив (тогда нерабочий сервер будет определяться быстрее).

Параметр -AdditionalTimeout

Это – плюсик к предыдущему параметру, показывающий, что если в запросе будет бит рекурсии, то надо дополнительно подождать – ведь удалённый сервер может куда-то сбегать и спросить. Стандартно это дополнительные 4 секунды, как у гранаты Ф1 (хотя сейчас они от 3.2 секунд бывают, так что DNS server чуток тормознее). Если настраиваете региональный DNS-сервер, который пробрасывает запросы по VPN до центрального офиса – возможно, надо увеличить данный параметр, это положительно повлияет на уменьшение false negative в кэше сервера.

Параметр -RetryInterval

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

Ускоряем загрузку DNS-зон в Windows Server 2012 R2 и старше

Hotfix 3038024 приносит новую функциональность в DNS server в Windows Server 2012 R2 и старше. Заключается она в альтернативном механизме подгрузки зон и решении проблем с “зависшим” форвардером (это когда DNS server при наличии более одного форвардера почему-то после тайм-аута первого не пробует второй). Ключевое – действует этот метод только для серверов, которые подгружают зоны из файлов, а не из Active Directory – т.е. данный приём нужен только для проксирующих и держащих внешние зоны DNS-серверов.

До установки 3038024 обязательно установите апрельский update rollup. Microsoft пишет, что хотфикс меняет загрузку зон только в случае, если DNS-сервер стартует с параметром “Load zone data on startup: From registry” (это когда BootMethod будет равен 2), по факту же работает всегда – поэтому, кстати, этот хотфикс добавлен в Windows Server 2016 сразу же, как часть функционала.

В общем, пока всё.

Заключение

Надеюсь, что данная статья поможет Вам корректно и эффективно настроить сервис DNS в инфраструктуре предприятия. Ну, а про DNSSEC (как и ранее про EDNS0) – напишем отдельно. Удач!

Возможно, вам будет также интересно почитать другие статьи про DNS на нашей Knowledge Base

Ruslan V. Karmanov

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