Механизмы фильтрации DNS-сервера Windows Server 2016

Новый функционал DNS Server в Windows Server 2016 - политики обработки запросов, управление рекурсией и трансфером зон.

Привет.

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

Встроенный в Windows Server компонент DNS прошёл долгий путь развития – но его функциональность, безусловно, ещё далека от совершенства. Шаги в нужном направлении делаются, и сегодня мы поговорим про нововведение в Windows Server 2016 (он же Windows 10 Server, он же Windows Server Threshold, он же CloudOS) – возможность фильтрации и управления обработкой запросов (как на разрешение имён, так и на трансфер зон) на уровне DNS-сервера. Ранее управлять можно было на уровне клиента (см. мою статью про NRPT) – ну а аналога bind’овых view не было.

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

Начнём.

Фильтрация запросов и трансфера зон в Windows Server 2016

  • Зачем фильтровать запросы к DNS-серверу
  • Подготовка к фильтрации запросов – размечаем подсети с клиентами
  • Подготовка к фильтрации запросов – добавляем zone scope
  • Добавляем в зону A-запись, видимую только для определённого zone scope
  • Добавляем к зоне политику обработки запросов
  • Различные варианты применения политик запросов
  • Политики обработки рекурсии
  • Политики передачи DNS-зон
  • Общие правила применения политик

Зачем фильтровать запросы к DNS-серверу

Фильтрация запросов к DNS-серверу нужна для решения ряда базовых задач безопасности и производительности. Например, если ваш DNS-сервер стоит в регионе строго как кэширующий, то ему нет никакого смысла пытаться обрабатывать что запросы не из местных сетей, что из внешней. Равно как и внешний DNS-сервер на площадке провайдера, который нужен для ускорения обработки запросов ваших клиентов, которые находятся вне сети предприятия – ему тоже неплохо бы заниматься только тем, чем надо, а не быть открытым DNS-прокси.   Безусловно, есть базовые задачи фильтрации – например, привязать DNS-сервер только к определённым IP-адресам на определённых интерфейсах, чтобы входящие запросы с других сторон его не интересовали – равно как и можно просто закрыть встроенным Windows Advanced Firewall’ом доступ к портам DNS-сервера. Всё это – также меры фильтрации запросов, но предполагается, что вы их уже используете и нужна более тонкая обработка.   Это мы и сделаем.

Подготовка к фильтрации запросов – размечаем подсети с клиентами

Обычно администратор Active Directory прописывает привязку сетей и подсетей к сайтам Active Directory – для оптимизации скорости логина с рабочих станций и member-серверов. В нашем случае механизм будет не привязан к Active Directory, т.к. фильтровать запросы каждый DNS-сервер в организации может по индивидуальной логике – да и необязательно для этого быть членом домена.   Для того, чтобы определить подмножество адресов, запросы из-под которого будут обрабатываться специфичным образом, нам надо будет сделать следующее – придумать ему название (удобное для нас, чтобы идентифицировать проще) и добавить данную именованную связку имя+сеть в локальный DNS-сервер. Это делается следующим командлетом:   Add-DnsServerClientSubnet -Name "MSK_VLAN_201" -IPv4Subnet 10.1.201.0/24   Синтаксис вполне тривиален – создан объект-“сеть” с именем MSK_VLAN_201 и к нему привязана IPv4-сеть 10.1.201/24. Если хочется привязать IPv6-сеть – используйте -IPv6Subnet.   Эти данные DNS-сервер записал в свою локальную конфигурацию – в частности, в ветку HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ DNS Server \ ClientSubnets:     ОК, теперь надо добавить к DNS-серверу именованные объекты, нужные для применения политик – “zone scope”.

Подготовка к фильтрации запросов – добавляем zone scope

Механизмы фильтрации и управления политиками обработки запросов – новые и реализуются через дополнительные объекты, “привязываемые” к конкретному DNS-серверу или зоне на нём. Нам надо будет создать такой объект – мы выберем вариант привязки к зоне и это несложно сделаем:   Add-DnsServerZoneScope -ZoneName "atraining.test" -Name "ScopeMSK_1"   Синтаксис опять же тривиален – создан именованный объект ScopeMSK_1, привязанный к DNS-зоне atraining.test. Замечу, что пока что привязывать такие объекты можно только к зонам, не интегрированным в Active Directory – что намекает на использование в провайдерских и кэширующих сценариях. Можно создать и для другого DNS-сервера – тогда его надо указать в параметре -ComputerName.   Вот что в результате создаст DNS-сервер в реестре:     И в каталоге %WINDIR% \ system32 \ dns \:     ОК, теперь добавим запись, которая будет существовать только для тех, кто подпадёт под данный zone scope (замечу, что мы ещё не привязали клиентский диапазон к scope – это предстоит сделать).

Добавляем в зону A-запись, видимую только для определённого zone scope

Для добавления записи, видимой только в определённом zone scope, нам опять-таки нужен PowerShell – графического интерфейса нет (надеюсь, что пока нет, а к Windows Server 2016 RTM всё ж добавится). Командлет   Add-DnsServerResourceRecord -ZoneName "atraining.lab" -A -Name "server1" -IPv4Address "192.168.0.1" -ZoneScope "ScopeMSK_1"   выполнит эту задачу – запись появится в файле zone scope, который мы только что создали (кстати, её можно туда вписать руками безо всякого командлета, эффект будет такой же).   Теперь соединим вместе всё вышесозданное политикой, говорящей что наконец-то со всем этим делать.

Добавляем к зоне политику обработки запросов

Политика обработки запросов будет уже сложнее, чем первоначальные операции по именованию отдельных сущностей. Что нам надо будет указать в командлете Add-DnsServerQueryResolutionPolicy, помимо очевидного параметра -Name, указывающего имя политики?  

Параметр -ClientSubnet

В данном параметре вы указываете логическое выражение, описывающее то, к кому из клиентов (тех, кто запрашивает) применима данная политика. Логическое выражение содержит две части – EQ и NE. В части eq можно указать одну или более клиентских сетей, притом, если указать несколько, то логика объединения будет “или”. Например:   -ClientSubnet "EQ,MSK_VLAN_201"   укажет, что создаваемая нами политика будет срабатывать в случае поступления запроса из-под адресов, подпадающих под ранее определённый client subnet object с именем MSK_VLAN_201, а вариант   -ClientSubnet "EQ,MSK_VLAN_201,MSK_VLAN_202"   скажет, что срабатывать надо и в случае подпадания под MSK_VLAN_201, и под MSK_VLAN_202. Т.е. вы можете сделать одну политику обработки, привязав к ней пачку разных именованных сетей – это удобно.   Часть NE будет действовать обратно – исключать из множества EQ подмножество. То есть в варианте:   -ClientSubnet "EQ,MSK_VLAN_201,MSK_VLAN_202,NE,SPECIAL_SUBNET_VLAN_201"   запрос будет обработан DNS query-политикой в случае, если он подпадёт под любой из двух указанных диапазонов, но не будет подпадать под SPECIAL_SUBNET_VLAN_201. Можно указать несколько диапазонов после NE – тогда они будут объединяться по логике “если подпадёт под хотя бы один, не обрабатывается”.   Вариантов применения множество – вы можете создать, например, клиентский диапазон из частных сетей, используемых в вашей организации, и запретить ему обрабатываться политикой для разрешения внешних имён в организации – это поможет при split-brain в случае одноимённо названного домена Active Directory и интернет-домена.

Параметр -InternetProtocol

Этот параметр в схожем с предыдущим синтаксисе позволит указать, для запросов, пришедших по каким IP-протоколам будет работать наша политика. Примеры синтаксиса просты:   -InternetProtocol "EQ,IPv4,IPv6"   В этом варианте – для всех.   -InternetProtocol "EQ,IPv4,NE,IPv6"   А тут только для IPv4-запросов. Обратите внимание – речь не про то, какие адреса запрашиваются – т.е. не про A / AAAA записи, например – а про то, каким протоколом пользуется клиент для доставки запроса DNS-серверу. Может возникнуть вопрос – зачем это надо, ведь мы и так в Client Subnet указывали сеть, из неё явно следует, какой протокол будет использоваться? Да, указывали, но Client Subnet – самостоятельный объект, который может включать в себя и IPv4-сеть и IPv6-сеть – а политики могут, используя этот объект (и не плодя дополнительные), различно обрабатывать запросы, пришедшие по разным сетевым протоколам. Следующий параметр будет примерно про это же:

Параметр -TransportProtocol

То же, но не для сетевого, а для транспортного уровня. Запросы на ваш DNS-сервер могут приходить разными способами (про тонкости в части UDP / TCP можно посмотреть в статье про настройку ENDS0 на Windows Server), и можно адресно сказать политике, про какой протокол идёт речь. Синтаксис тот же:   -TransportProtocol "EQ,UDP"   или, если по всем –   -TransportProtocol "EQ,UDP,TCP"  

Параметр -ServerInterfaceIP

Ранее можно было просто привязать службу DNS Server к явно указанным интерфейсам и отдельным адресам на них. Теперь можно ещё лучше – привязать политику к конкретному адресу, на котором слушает запросы DNS Server. Простой пример – например, если у вас развёрнуто шлюзовое решение или просто есть сервер с интерфейсами в несколько L2-сред, вы можете явно указать, что, допустим, при входящем запросе с внешнего адреса не надо ресолвить имена вида “*.ourdomain.local”. Синтаксис прост:   -ServerInterfaceIP "EQ,1.2.3.4"   где 1.2.3.4 – IP-адрес на одном из интерфейсов. Если добавить тот адрес, на котором DNS-сервер не слушает – просто ничего не произойдёт, т.е. этот IP не появится на интерфейсе и не начнёт принимать от всех DNS-запросы.

Параметр -Fqdn

Здесь ситуация ещё интереснее – это фильтр по тому, какое имя разрешает клиент (тип записи здесь не играет роли). При этом, можно использовать wildcard:   -Fqdn "EQ,*.atraining.lab,NE,*.test.atraining.lab"   В данном примере политика обработает запрос, если он про что-то внутри atraining.lab, но что не подпадает под *.test.atraining.lab.

Параметр -QType

Этот параметр поможет дополнительно отфильтровать входящие запросы по типу запрашиваемых записей. То есть можно сделать, допустим, две политики, которая будет реагировать только на запросы MX и выдавать одни адреса почтовых серверов, когда запрос из внутренней сети (например, какому-нибудь серверу надо отправить служебное сообщение на адрес администратора), и другие – когда снаружи (обычный приём почты из внешнего мира). Синтаксис -QType будет уже знаком:   -QType "EQ,A,AAAA"   или   -QType "EQ,A,AAAA,NE,PTR"  

Параметр -TimeOfDay

Это, что исключительно логично, про время суток. Вы можете задать диапазоны (считаться будет во времени сервера, в 24х часовом формате), во время которых запросы данной политикой (если ещё не ошалели от перечня параметров – вот мы всё это время допиливаем политику, которая будет говорить когда, какие запросы, из-под каких сетей и их совокупностей, в какой именно scope у какой именно зоны будут попадать) будут обрабатываться. Формат прост – диапазоны через дефис:   -TimeOfDay "EQ,8:00-21:00"   В этом случае данная политика будет работать только если запрос пришёл на сервер, и на локальных системных часах время от 8:00 до 21:00.

Параметры -ZoneScope и -ZoneName

Тут всё просто – -ZoneName будет указывать имя DNS-зоны, с которой идёт работа, а вот -ZoneScope будет указывать тот zone scope (удобно, кстати, сокращать до звучного zope), для которого это будет применяться. Притом можно задать и несколько – главное, правильно распределить веса для используемых zone scope. Пример:   -ZoneScope "ScopeMSK_1,100"   В этом случае всё просто – данные для ответа политика будет доставать из ScopeMSK_1. Или так:   -ZoneScope "ScopeMSK_1,50,ScopeMSKRes_1,100"

Параметр -ProcessingOrder

Это приоритет данной политики – он нужен, если несколько политик обработки запроса подпадут под условия. Выиграет та, у кого он минимальный.

Параметр -Action

Ключевой параметр – что делать-то, если запрос пробрался сквозь дебри условий. Вариантов будет три. Первый – ALLOW – разрешить обработку запроса. Второй – тихо проигнорировать – IGNORE. И явно ответить, что сервер не хочет обрабатывать запрос – т.е. отправить SERV_FAIL – третий вариант, DENY.   Теперь наконец-то включим нашу политику:   Add-DnsServerQueryResolutionPolicy -Name "MSKUsers" -Action ALLOW -InternetProtocol "EQ,IPv4" -ClientSubnet "EQ,MSK_VLAN_201" -ZoneScope "ScopeMSK_1,100" -ZoneName "atraining.test"   Смотрим, как она выглядит локально:     Вполне прилично – да и править, если что, всё понятно где и как. Увидеть факт, что она привязалась к конкретной зоне и работает (да и вообще все политики, которые есть на этой зоне) можно так:   Get-DnsServerQueryResolutionPolicy -ZoneName "atraining.test"   Теперь, когда к нам придёт запрос с IP-адресом из диапазона 10.1.201.0/24, мы обработаем его исходя из содержимого ScopeMSK_1.   Если после хочется отключить или заново включить политику (не удаляя её и не вводя заново) – есть удобная пара командлетов:   Enable-DnsServerPolicy -Level Zone -ZoneName "atraining.test" -Name "MSKUsers"   и Disable-DnsServerPolicy с достаточно очевидным синтаксисом.   Обратите внимание, сейчас мы разбираем работу и привязку политики к конкретной DNS-зоне. Можно применять политики и на уровне сервера.

Различные варианты применения политик запросов

Например:

Имитируем управляемый netmask ordering

Механизм netmask ordering есть в DNS server с незапамятных времён. И работает вроде просто – но вот привязан к классовым сетям и не даёт возможность детально описать структуру современной сети. Поправим это, например, так:   Предполагаем, что есть организация, где несколько регионов, и надо выдавать всем клиентам правильный IP-адрес локального DFS-хранилища файлов (например, DP для SCCM 2012):   Add-DnsServerClientSubnet -Name "MSK_VLAN_Users1" -IPv4Subnet 10.1.201.0/24   Add-DnsServerClientSubnet -Name "SPB_VLAN_Users1" -IPv4Subnet 10.2.11.0/24   Add-DnsServerClientSubnet -Name "NSK_VLAN_Users1" -IPv4Subnet 10.3.1.0/24   Теперь на сервере заведём zone scope’ы для всех регионов:   Add-DnsServerZoneScope -ZoneName "firma.local" -Name "ScopeMSKUsers1"   Add-DnsServerZoneScope -ZoneName "firma.local" -Name "ScopeSPBUsers1"   Add-DnsServerZoneScope -ZoneName "firma.local" -Name "ScopeNSKUsers1"   Добавим варианты адреса сервера для каждого региона:   Add-DnsServerResourceRecord -ZoneName "firma.local" -A -Name "filesrv" -IPv4Address "10.1.201.252" -ZoneScope "ScopeMSKUsers1"   Add-DnsServerResourceRecord -ZoneName "firma.local" -A -Name "filesrv" -IPv4Address "10.2.11.100" -ZoneScope "ScopeSPBUsers1"   Add-DnsServerResourceRecord -ZoneName "firma.local" -A -Name "filesrv" -IPv4Address "10.3.1.2" -ZoneScope "ScopeNSKUsers1"   И теперь политики обработки запросов:   Add-DnsServerQueryResolutionPolicy -Name "MSKUsers1" -Action ALLOW -InternetProtocol "EQ,IPv4" -ClientSubnet "EQ,MSK_VLAN_Users1" -ZoneScope "ScopeMSKUsers1,100" -ZoneName "firma.local"   Add-DnsServerQueryResolutionPolicy -Name "SPBUsers1" -Action ALLOW -InternetProtocol "EQ,IPv4" -ClientSubnet "EQ,SPB_VLAN_Users1" -ZoneScope "ScopeSPBUsers1,100" -ZoneName "firma.local"   Add-DnsServerQueryResolutionPolicy -Name "NSKUsers1" -Action ALLOW -InternetProtocol "EQ,IPv4" -ClientSubnet "EQ,NSK_VLAN_Users1" -ZoneScope "ScopeNSKUsers1,100" -ZoneName "firma.local"   Enable-DnsServerPolicy -Level Zone -ZoneName "firma.local" -Name "MSKUsers1"   Enable-DnsServerPolicy -Level Zone -ZoneName "firma.local" -Name "SPBUsers1"   Enable-DnsServerPolicy -Level Zone -ZoneName "firma.local" -Name "NSKUsers1"   Теперь у нас для запроса из каждого региона (в который мы можем добавить сколько хочется каких нужно сетей) будет отдаваться свой адрес сервера filesrv.firma.local – и всё в явном виде прописано и под контролем.   Можно придумать и схему с усилением безопасности (DNS-сервер отвечает верно только для известных ему сетей – если где-то в организации будет новая сеть, из которой начнут приходить запросы, он не ответит, пока явно её не пропишут в ClientSubnet), и с шлюзом с несколькими интерфесами (запросы из-под внешнего интерфейса разрешают atraining.ru в адрес внешнего сайта, а из-под других интерфейсов – в адрес ближайшего к спрашивающему DC), и много другого. Но мы продолжим изучать другие варианты политик – запросами клиентов всё не ограничивается.

Политики обработки рекурсии

Ещё одним нововведением будут политики обработки рекурсивных запросов. Суть проста – в случае, если приходящий запрос имеет бит “хочу рекурсию” (т.е. клиенту нужен финальный ответ, а не любая помощь в нахождении оного), теперь можно повлиять на то, и будет ли рекурсивный запрос для нужного подмножества query вообще обрабатываться (т.е. разрешат ли рекурсию или пришлют отбой клиенту), и на какие форвардеры уйдёт запрос. Т.е. это более гибкий вариант conditional forwarders плюс новая фильтрация. Такие политики будет применимы только на уровне сервера.   Посмотрим, как это делается.   Вначале надо создать именованную группу forwarder’ов – к ней мы будем привязывать политику обработки запросов.   Add-DnsServerRecursionScope -Name "PartnerADForest1" -Forwarder 178.159.49.228 -EnableRecursion $true   Эта политика будет указывать, что когда запрос будет удовлетворять всем запросам, то он будет перенаправлен на заданный IPv4-адрес. Адресов может быть и несколько – через запятую. Параметр -EnableRecursion будет указывать на то, будет ли запрашиваться рекурсия для отправленного запроса. Если этот параметр скинуть в $false – то запрос уйдёт на адрес, но ответ будет приниматься только если отвечающий сервер является держателем зоны, из которой выдаётся ответ – т.е. дальнейшая передача запроса кому-нибудь ещё отменяется.   Теперь можно сделать политику, которая скажет, что запросы от определённой группы клиентов (как указать тучу других параметров – см.выше) могут, если уже прописан форвардинг (это важно – политики именно указывают как обрабатывать запросы), уходить по указанному адресу.   Add-DnsServerQueryResolutionPolicy -Name "MSKUsersPartnerTrust1" -ApplyOnRecursion -Action ALLOW -ClientSubnet "EQ,MSK_VLAN_Users1" -RecursionScope "ScopeMSKUsers"   Особенностей, как видно, всего две – добавление параметра -ApplyOnRecursion, который укажет, что речь про политику, связанную с рекурсией, и параметр -RecursionScope (вместо -ZoneScope), который привязывает к политике конкретную группу форвардеров.   Можно, кстати, также повлиять на то, как обрабатывается стандартный список форвардеров в DNS-сервере – он выступает под именем точки:   Set-DnsServerRecursionScope -Name . -EnableRecursion $true   Т.е. например выключить рекурсию на нём, лично. В стандартном интерфейсе этого нет:     Впрочем, больше настроек форвардинга и раньше реализовалось через PowerShell (см. статью про безопасную настройку DNS Server, пункт про настройку форвардеров).   Теперь вы можете достаточно тонко настроить работу, связанную с ситуацией “пришёл запрос, а локально наш DNS-сервер на него ответить не может” – опять же, указывая IP-сети, время, входящие интерфейсы, и многое другое. Да и безопасность сделать повыше – например, у вас есть партнёр со своим лесом Active Directory, с которым у вас forest trust. Раньше вы могли прописать conditional forwarder на все его DNS, доступные снаружи, да и всё. Теперь вы можете детально прописать – запросы из каких подсетей должны иметь возможность туда уходить (например, есть принтерная подсеть или management vlan, где строго интерфейсы сетевых устройств – им-то зачем?), плюс добавить отключение рекурсии – ведь если вы спрашиваете у DNS-сервера соседа, у которого зона partnerdomain.local, про хост dc1.partnerdomain.local – какой смысл в рекурсии? У кого он переспросит, если он авторитативен за эту зону?   Так что штука безусловно полезная. Продолжим, впереди – трансфер зон.

Политики передачи DNS-зон

Внутри организации, когда есть Active Directory, этот вопрос решён уже давно – DNS-записи будут отдельными объектами AD, и будут реплицироваться так же, как все остальные. Но в случае наличия других DNS-серверов – которые вне Active Directory, например в DMZ или на площадке у провайдера, вопрос поднимается вновь. Раньше можно было поработать с тайм-аутами и AXFR/IXFR передачей зон, ну и со всякими уведомлениями и прочим (см. про безопасную настройку трансфера зон в DNS Server), но теперь можно и просто зафильтровать именно запросы на трансфер.   Многие спросят – но ведь это можно и на обычном Windows Advanced Firewall, просто 53 TCP закрыть для неправильных адресов, да и всё. Это ошибка – DNS-сервер по 53 TCP обрабатывает не только трансферы, но и запросы на разрешение имён, да и закрыть только по критерию принадлежности к IPv4-сети – не очень. Политики позволят закрыть именно трансферы и с доп.параметрами для тонкой настройки условий.   Add-DnsServerZoneTransferPolicy -Name "AllowOnlyDCTransfer" -Action IGNORE -ClientSubnet "NE,OurDCNetwork"   Этот командлет будет тихо игнорировать все запросы, которые придут и не подпадут под объект OurDCNetwork (это, допустим, наша внешняя сетка в датацентре, из-под которой наши сервера оттуда общаются с серверами в организации). Можно и явно отправлять SERV_FAIL – для этого IGNORE надо заменить на DENY. Можно добавить -ServerInterfaceIP, -TransportProtocol, и многие другие параметры – выбирайте.   Не забывайте только, что политика добавляется сразу включённой – этого можно избежать, добавив ключ -Disabled, ну а после включить тем же командлетом Enable-DnsServerPolicy.

Общие правила применения политик

Политики обработки рекурсии будут срабатывать только если пришёл запрос с битом “хочу рекурсию”, и только если не получилось ответить на него локально.   Политики обработки запросов будут уровня сервера и уровня зоны. Политики уровня сервера будут применяться первыми и ограничены только запретительными действиями – а на уровне зоны уже можно будет работать с логикой “разрешить только указанным”. Последними будут срабатывать политики обработки рекурсии.   Приоритет обработки задаётся параметром -ProcessingOrder – самой главной, в случае если несколько политик подпали под критерии, будет политика с минимальным числовым приоритетом.   Не путайте приоритет с весом – в варианте -ZoneScope "ScopeMSK_1,50,ScopeMSKRes_1,100" запросы будут распределяться между zone scope согласно соотношению весов (в примере – 1/3 в ScopeMSK_1, 2/3 запросов – в ScopeMSKRes_1).   А в остальном – в общем, всё логично и несложно.

Напоследок

Новый функционал – очень гибкий и полезный. Он и даёт новые возможности, и улучшает уровень безопасности. Так что ждём релиза Windows Server 2016 и применяем.   Удач!  

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

Ruslan V. Karmanov

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