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

Механизм расширений EDNS0, а также OPT Cookies, взаимодействие с DNSSEC и настройка + тестирование всего этого в корпоративной сети

Привет.

Протокол DNS существует очень давно – с самой зари Интернета – и за время своего бытия оброс множеством дополнительных расширений и дополнений. Про одно из них – EDNS – мы и поговорим сегодня.

Я предполагаю, что на начало чтения статьи Вы знакомы с работой DNS и профильной терминологией хотя бы на уровне базового курса Microsoft 20410D. Настройки буду делать на Windows Server 2012 R2 со всеми патчами – хотя все эти опции идентично работают и реализуемы начиная с Windows Server 2008 R2, а некоторые и ещё раньше. Для настроек буду использовать ATcmd последней версии – Вы можете использовать как эту утилиту, так и любой другой способ/инструмент; способ выполнения действий некритичен.

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

  • Что такое и зачем нужен EDNS0
  • Тестим EDNS0 с нашего хоста, используя nslookup
  • Тестим EDNS0, используя автоматизированную утилиту ATcmd
  • Включаем EDNS0 на Windows Server
  • Настраиваем максимальный размер датаграммы EDNS0 на Windows Server
  • Таблица поддержки EDNS0 у других серверов: настраиваем
  • Если наш сервер не поддерживает новые расширения DNS
  • Что внутри у OPT-поля

Что такое и зачем нужен EDNS0

Механизм DNS, спланированный и стандартизированный к 1987 году (RFC 1035), безусловно, не мог на момент создания учитывать все перспективные изменения в требованиях, использовании, безопасности и прочем, что неразрывно связано с развитием сети Интернет. Изначально возможностей расширения было заложено в него крайне немного (разве что свои типы RR), поэтому вполне логично, что со временем появилась необходимость в его расширении. EDNS0, появившийся в 1999 году (через 12 лет после стандартизации DNS, RFC 2671), был призван решить этот вопрос, с чем неплохо справляется до сегодняшнего дня – правда, вместо превращения в EDNS1 (драфт которого в природе есть, но вообще не особо кому-то нужен), начал развиваться в ширину, обрастая опциями и применениями – RFC 6891 – но данный процесс для рабочего стандарта вполне нормален.

Что же добавляет EDNS0? В принципе, основным нововведением в нём является добавление нового типа псевдо-записи – OPT. Это специфичный тип RR-записи, которая не несёт DNS-данные (поэтому и “псевдо”), а нужна исключительно для стандартизации обмена служебной информацией. В подавляющем большинстве случаев использования в ней передаётся один блок информации – запись о максимальном обрабатываемом размере DNS-датаграммы.

Данный пункт действительно является важнейшим по простой причине – так как на момент разработки DNS сети были ещё очень медленные, а также в них было множество устаревших на данный момент протоколов канального уровня (сильно различавшихся технически и логически), то датаграмма DNS, в целях повышения её выживаемости в ходе путешествия по Интернету, ограничена размером в 512 байт (чтобы вместе с заголовками транспортного и сетевого уровня не первышать 576 байт). По сути, всё сделано для того, чтобы датаграмма выжила в среде с самым мелким MTU и без поддержки фрагментации. Понятное дело, что в современной ситуации, когда в DNS-ответ может быть добавлена пачка адресов (одно имя теперь часто, для отказоустойчивости, разрешается в несколько адресов сетевого уровня), притом крупных в плане занимаемого места – например, IPv6, ну и всякие дополнительные данные, например DNSSEC’овские RRSIG и DSKEY, да или просто TXT, такое ограничение (“не более 512 байт DNS-данных а то вдруг не дойдёт”) крайне неудобным.

Неприятностей добавляет простая проблема, исходящая из природы UDP – дело в том, что в случае отправки запроса или ответа отправитель, в случае тишины после, никак не сможет понять, что произошло – был ли пакет потерян по случайной причине, или отброшен промежуточным узлом по причине несоответствия максимальному размеру MTU, или потерялся по причине необходимости фрагментации на каком-то отрезке пути, а фрагментация DNS-пакета не получилась, или какой-либо другой. Плюс не надо забывать, что датаграммы от клиента к серверу, а после – в обратном направлении, совершенно необязательно будут идти по одной и той же трассе. В результате возможно множество различных неприятных ситуаций, вида “клиент отправил запрос серверу – сервер отработал, отправив ответ – ответ не дошёл, потому что великоват в части MTU, а клиент ошибочно думает, что сервер технически недоступен”, или “сервер отправил запрос другому серверу – запрос не дошёл, потому что тот сервер не поддерживает EDNS0 – клиент, изначально отправивший запрос, предполагает, что ближайший к нему сервер не работает, т.к. прошёл тайм-аут ожидания ответа”, и многих других. Поэтому понимание и представление о том, как всё это работает, резко помогает понять множество “странных багов DNS”.

Давайте попробуем протестировать работу EDNS0.

Тестим EDNS0 с нашего хоста

Чтобы проверить работоспособность EDNS0, необязательно быть DNS-сервером. Это можно сделать и при помощи утилиты nslookup.

Первым делом – запустим nslookup и скажем, что нас будут интересовать только ответы TXT-типа. Это просто:

set type=TXT

Теперь запросим (я предполагаю, что Ваш nslookup уже нацелен на тот сервер, который Вы хотите тестировать – если нет, то настройте его явно командой server) специальный хост – rs.dns-oarc.net. В качестве ответа Вы должны получить что-то вида:

или

Изучим. По сути, каждый из ответов состоит из 6 строк, три последних из которых явно говорят, когда и откуда проводился тест, а также какой максимальный размер EDNS0-датаграммы заказывался. Хорошо заметно, что источником запроса является провайдерский сервер – т.е. тестовый сервер, который rs.dns-oarc.net, фактически тестирует возможность отправки EDNS0-датаграмм до узла 218.77.159.18, являющегося адресом DNS-сервера провайдера – я даже, благодаря специфике китайской сети, в которой нахожусь, точно не могу сказать, где он, но где-то недалеко:

Теперь про первые три строки в ответе rs.dns-oarc.net. Они, по сути, отображают цепочку CNAME вида rst.xAAAA.rs.dns-oarc.net -> rst.xBBBB.xAAAA.rs.dns-oarc.net -> rst.xCCCC.xBBBB.xAAAA.rs.dns-oarc.net, где AAAA BBBB CCCC – это размеры, в байтах, удачно обработанных DNS-ответов. По сути, это некое “пингование” EDNS0-запросами с игрой внутри RR OPT, по аналогии с пингом пакетами с запрещённой фрагментацией с целью методом проб и ошибок выяснить PMTU. На картинках заметно, что размер плавает очень сильно – так бывает в провайдерских сетях, где не всё настроено однотипно. В моём случае оба ответа, в общем, плохие – хорошим считается ответ, где будет показано, что отработала датаграмма в 4К. Очень плохим будет вариант, когда нет ни одного ответа более 1.4К – это значит, что где-то на пути банально не работает фрагментация и всё, что не влезает в стандартный MTU ethernet’а, не выживает – так что у меня просто плохо, а не очень.

Теперь попробуем тестировать более цивилизованным способом.

Тестим EDNS0, используя автоматизированную утилиту ATcmd

Для упрощения тестирования в ATcmd есть диагностический контекст – test, в котором поддерживается несколько типовых сценариев опроса DNS-серверов на предмет поддержки EDNS0:

Это режим local, когда утилита автоматически тестирует все DNS-сервера данного хоста, режим прямого указания одиночного IP-адреса сервера и режим, когда указывается FQDN домена Active Directory – и утилита последовательно подключается к NS-серверам и тестирует их. Данный режим очень удобен для больших предприятий, и позволяет увидеть работоспособность EDNS-обмена с различными серверами с точки зрения конкретного хоста.

В общем, думаю, Вы оценили количество потенциальных проблем, которые будут, если оставить данный вопрос на самотёк – поэтому пора приступать к настройкам работы EDNS0 в сети предприятия.

Включаем EDNS0 на Windows Server

Включение механизма EDNS0 не так очевидно, как кажется. Первое, что надо отметить – Ваш сервер, если это Windows Server 2003 и выше, умеет принимать и обрабатывать EDNS0-ответы – т.е. не пугается ни бОльшего размера датаграммы, ни наличия специфичной OPT-записи. А начиная с Windows Server 2008 R2, механизм EDNS включен по умолчанию. Включать же мы будем, фактически, добавление в запросы другим DNS-серверам дополнительной “тестовой” OPT-записи. Цель – чтобы по их ответу на этот запрос было понятно, поддерживают они EDNS0 или нет.

Для включения этого механизма, EDNS Probes, да и вообще работы с EDNS, у нас будет специальный субконтекст – edns:

Работа с EDNS0 через ATcmdРабота с EDNS0 через ATcmd
(кликните для увеличения до 677 px на 343 px)
Учебный центр Advanced Traininginfo@atraining.ru

Включим механизм командой ednsprobes:

Совет по части этого параметра будет простым – включайте его со стороны своего сервера только убедившись, что “большие” EDNS-ответы технически могут добраться до него снаружи. Ключевое – разница между “наш сервер поддерживает и декларирует остальным серверам, что умеет” и “технически возможно прохождение датаграммы бОльшего размера, чем 576 байт”. Плохо, если Ваш сервер будет всем показывать, что может, но отправляемые ему датаграммы будут теряться, не доходя до него.

Настраиваем максимальный размер датаграммы EDNS0 на Windows Server

По стандарту EDNS0 мы добавляем в каждую DNS-датаграмму специальную RR, которая имеет тип OPT – добавляем в любое место, и только один раз. В этой RR и содержится информация о том, датаграммы какого размера мы можем “переваривать”. Понятное дело, что просто так выставлять этот параметр большИм не имеет смысла и даже вредно – в начале статьи мы выясняли, что фактический размер успешно принимаемой датаграммы зависит, скорее, не от нашего сервера, а от форвардера. Поэтому имеет смысл декларировать такой размер, который проверен экспериментально – я выставлю удвоенный размер стандартной DNS-датаграммы, 1280 байт (этот размер рекомендован в RFC 6891):

Замечу, что при комплексной настройке поддержки EDNS0 сетью, данный параметр, допустим, на сетевых устройствах, надо делать максимально возможным (рекомендуется 4096 байт). Их задача – просто не фильтровать “слишком большие пакеты”, поэтому не удивляйтесь, что корректная настройка будет выглядеть именно так – на промежуточных сетевых устройствах “чем больше, тем лучше”, а на конечном DNS-сервере – “только столько, сколько экспериментально доказано, что влезает, и не более”.

Таблица поддержки EDNS0 у других серверов: настраиваем

В памяти у каждого Windows DNS Server есть табличка, которая ведёт учёт – кто из других серверов поддерживает EDNS. Это нужно для оптимизации работы – ведь каждый раз выяснять перед форвардингом одиночного запроса клиента, поддерживает ли конкретный DNS-сервер EDNS или нет – и долго и накладно по трафику. Поэтому идея проста – если у нас работает механизм EDNS Probes, кэшируем результаты его работы в табличке, которую называем Remote Server Table. Она расположена в оперативной памяти и с её точки зрения у серверов будет 4 статуса:

  • Unknown: поддержка EDNS не определена, стартовый статус у любого сервера-соседа в табличке.
  • Not supported: EDNS в явном виде не поддерживается – мы ему тестовый пакет с OPT, он нам ответ без OPT в явном виде, и не более 576 байт в сумме.
  • Ok: EDNS в явном виде поддерживается.
  • Maybe not supported: Пока от этого сервера ни разу не было получено ответа, который можно разобрать (т.е. или ответов не было вообще, или они были malformed с точки зрения формата DNS).

Вот все статусы, кроме первого, будут держаться в табличке столько, сколько мы скажем в настройках параметра EDNS timeout. После истечения этого времени статус будет сброшен на Unknown и процесс определения поддерживаемости EDNS0 запустится снова.

Для настройки этого у нас есть параметр, который в современных ОС по умолчанию равен 15 минутам, называется он ednstimeout. Мы выставим его в 86400 (это секунд в сутках), так как логично, что нет смысла слишком часто спрашивать у других серверов о том, поддерживается ли ими EDNS0 или нет:

Если наш сервер не поддерживает новые расширения DNS

Возможен такой вариант – наш сервер расположен за не управляемыми нами firewall’ами, которые в явном виде не любят, чтобы DNS-пакеты были больше 512 байт. Со своей стороны мы поддержку EDNS0 выключили и поэтому наши пакеты всегда нормально уходят наружу, но вот внешние сервера про такую особенность нашей сети не знают и пытаются присылать нам пакеты с дополнительными опциями. В случае, если наш сервер не понимает, что от него хотят, по умолчанию в нём включается механизм защиты от DoS-атаки “неправильными” DNS-запросами. Механизм работает просто – после приёма пакета, который не удаётся полностью обработать (допустим, в нём неизвестная RR), все другие запросы и ответы с IP-адреса, откуда пришёл этот пакет, не будут обрабатываться целую минуту. В общем-то, данный механизм иногда полезен – но чаще нет; например, если у большой организации на площадке у провайдера стоит свой DNS-сервер, который аккумулирует все форвардинги от внутренних серверов организации, и к нему придёт один такой запрос, то он откажется на минуту обрабатывать все запросы с этого же адреса, а в типовом сценарии этот адрес-источник – это адрес NAT-транслятора, за которым десятки, а то и сотни клиентов. В этом случае DoS сомнителен, и одиночный неправильный пакет можно и просто отбросить, отметив в логах, не останавливая обработку.

Для управления этим в Windows Server тоже есть опция – мы вынесли её в субконтекст EDNS. Выключим эту защиту, чтобы обработка запросов не останавливалась в случае разового malformed packet:

Что внутри у OPT-поля

Давайте посмотрим, что ещё полезного умеет делать EDNS, чтобы не запомнить случайно, что он может только декларировать максимальный обрабатываемый размер датаграммы.

У OPT RR есть двубайтовый заголовок, указывающий назначение OPT. Обычно используется нуль – именно в этой ситуации OPT несёт на себе информацию о максимальном размере датаграммы.

Единица и двойка заняты под черновики “невыстреливших” стандартов DNS Long-Lived Queries и DNS Update Leases, которые были призваны улучшить работу DNS, развивая механизм Service Discovery и улучшая работу динамических обновлений.

Тройка занята расширением NSID – описывается оно в RFC 5001, краткая суть применения – способ идентификации DNS-серверов в кластере (т.е. тот, кто работает с одним IP-адресом DNS-сервера, может добавить OPT RR с NSID и в ответ сервера добавят в таком же виде OPT RR с третьим кодом, где в payload напишут свои уникальные идентификаторы – например, реальные, а не кластерные IP-адреса). Этот стандарт, в отличии от предыдущей пары DNS-SD, принят.

Четвёрка в принципе не занята, но на неё претендует ещё один из механизмов DNS-SD – так называемый Sleep Proxy, механизм работы которого выглядит так – “пусть каждый сервер, который захочет вздремнуть в плане экономии электричества, вышлет на специальный сервер-будильник специальный EDNS-пакет, где укажет свой MAC, на который он готов принять пробуждающий сигнал Wake-on-Lan, и пароль для пробуждения, чтобы не будил кто попало”. Затейливая схема, притом застолблённая фирмой Apple (https://tools.ietf.org/html/draft-cheshire-dnsext-multicastdns-07), поэтому будем относиться к ней с осторожностью.

Значения с 5 до 7 используются новой модификацией DNSSEC (про связь DNSSEC и EDNS0 я напишу отдельно), решаемая задача – клиент, благодаря:

  • OPT 5 – DNSSEC Algorithm Understood (DAU).
  • OPT 6 – DS Hash Understood (DHU).
  • OPT 7 – NSEC3 Hash Understood (N3U).

может информировать DNSSEC-сервер о том, какие алгоритмы он, клиент, поддерживает, что, в случае поддержки и кэширования этой информации на DNSSEC-сервере, во-первых резко снижает количество сбойных итераций (нет ситуации “отправляем клиенту всё слабее и слабее хэшированную запись, пока он не сможет переварить принятое”), от чего вырастает скорость работы, во-вторых снижает нагрузку на сервер.

Девятка в OPT отдана под новый стандарт RFC 7314, EDNS Expire, суть которого в том, чтобы помочь корректно отслеживать expire-таймеры в SOA-записях DNS-зон не только в случае двухуровневой иерархии, когда все secondary-сервера забирают зону с authoritative, но и когда существует граф secondary, забирающих зону у других secondary.

Остальные значения, с 10 по 65000 включительно, никак не обозначены – простор для расширений присутствует. В общем-то механизм действительно простой и удобный, поэтому, возможно, что-то ещё полезное сможет появиться в ближайшее время. Значения от 65001 до 0xFFFE будут, по сути, частными – можно свободно использовать их для своих локальных задач, либо каких-то экспериментальных. Например, Google использует их для работы механизма OPT Cookies. Ну а все единички – 0xFFFF – будут зарезервированны для будущих поколений.

Да, и ещё – есть перспективный стандарт по оптимизации работы цепочек DNS-форвардеров: https://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02, который развивают серьёзные парни из Google, Akamai и OpenDNS, но он уже тема для совсем другого разговора.

Заключение

Обычно изучение работы EDNS – например, на авторизованных курсах Microsoft – выглядит как упоминание на одном слайде, вида “это такая штука чтобы датаграммы больше были”. Остальное – почему, зачем, как применять, как тестировать, как анализировать работу, как связано с DNSSEC – остаётся в стороне. Надеюсь, что этой краткой экскурсией в данную технологию, количество “белых пятен” было немножко уменьшено.

Удач!

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

Ruslan V. Karmanov

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