Измерения №12, ноябрь 2019

В поиске несуществующего

Фото аватара
Джефф Хьюстон
Джефф Хюстон

DNSSEC часто считают решением, которое никак не найдет себе проблему. С одной стороны, воз- можность явно проверить достоверность и актуальность ответов на запросы DNS вроде бы должна зачем-то да пригодиться, но вот с практическими примерами беда. Подписание зон DNS по DNSSEC распространяется довольно медленно, как бы показывая, что польза от DNSSEC весьма сомнительна. А такие распространенные примеры, как неподписанное имя www.google.com, тоже вроде бы свидетельствуют, что даже Google не видит особого смысла подписывать такой крупный сайт. Так в чем же может быть польза от DNSSEC?

DNSSEC часто считают решением, которое никак не найдет себе проблему. С одной стороны, возможность явно проверить достоверность и актуальность ответов на запросы DNS вроде бы должна зачем-то да пригодиться, но вот с практическими примерами беда. Подписание зон DNS по DNSSEC распространяется довольно медленно, как бы показывая, что польза от DNSSEC весьма сомнительна. А такие распространенные примеры, как неподписанное имя www.google.com, тоже вроде бы свидетельствуют,
что даже Google не видит особого смысла подписывать такой крупный сайт. Так в чем же может быть польза от DNSSEC?

Некоторые надежды возлагаются на DANE, т.е. доменные ключи в составе DNS. Данные, которые используются для проверки достоверности сертификата доменного имени по TLS, тоже можно публиковать в составе DNS, чтобы клиент мог с помощью DNS проверить данные TLS для удаленного конца соединения, а ответ DNS можно проверить по DNSSEC. Для браузеров эта идея не «взлетела» по ряду причин, связанных с уязвимостью для разнообразных атак посредника (man-in-the-middle attack), а также из-за озабоченности повсеместным применением ключей RSA малого размера в DNSSEC… не говоря уже o том, что все пространство DANE уязвимо для атак ределегирования регистратора. DANE получил кое-какое признание в почтовом сегменте в качестве метода борьбы со спамом, но более масштабные планы внедрения DANE и DNSSEC в дополнение к структуре CA WebPKI или даже на замену ей с треском провалились.

Есть ли у DNSSEC другая прямая польза? Зачем-то еще нам может сейчас потребоваться подписывать доменные имена?

Довольно неожиданный сценарий применения связан с тем, как именно DNS объявляет, что такого-то доменного имени не существует.
Если авторитетный сервер имен DNS обслуживает заранее подписанные зоны, то он не может подписать то, чего нет в статическом файле зоны, а потому не может заранее подписать набор ответов NXDOMAIN на запросы обо всех возможных именах, которые не определены в данной зоне DNS. Вместо этого в DNSSEC определен альтернативный метод: DNSSEC подписывает «пробелы» между именами в зоне, в которой имена упорядочены лексикографически.

Такой метод эффективен даже в сочетании с NSEC3, так как NSEC3 просто переопределяет порядок меток в зоне, чтобы незначительно усложнить ее нумерацию. Ответ NXDOMAIN, подписанный DNSSEC, несет в себе гораздо больше информации, чем «такого-то конкретного имени не существует».
Он подтверждает, что не существует целого диапазона имен, поэтому тот же самый ответ можно использовать для запросов о наличии любых имен из диапазона. Рекурсивный резолвер с поддержкой DNSSEC мог бы кэшировать эти «ответы о пустых диапазонах» и повторно использовать их для любых имен, которые попадают в подобный диапазон, не отправляя запросы авторитетному серверу имен зоны.

Такой процесс кэширования отрицательных ответов пока что довольно непривычен. Но в нем есть большой смысл: он защищает от атак на DNS с использованием случайных имен. Если хакер запрограммирует несколько slave-ботов так, чтобы каждый из них потихоньку кормил DNS-сервер запросами о случайно сгенерированных именах в зоне, которая является мишенью для атаки, то рекурсивные резолверы, не найдя это имя в кэше, будут пересылать запросы авторитет- ному серверу зоны. При достаточно большом числе ботов авторитетный сервер зоны «ляжет», как показала атака на DNS-инфраструктуру DYN в октябре 2016 года.

Как защищаться от таких DNS-атак со случайной генерацией имен? Создание армии ботов не предотвратить никак. Запретить им выполнять скрипты для автогенерации имен и запросов DNS тоже не получится. А вот поставить барьер на уровне рекурсивного резолвера мы можем, если поручим ему генерацию ответов NXDOMAIN на такие случайные имена, чтобы запросы не передавались на авторитетные серверы. Если зона подписана по DNSSEC, а рекурсивный резолвер выполняет проверку DNSSEC и кэширование NSEC, как описано в RFC 8198, то резолвер будет выдавать ответы на запросы о случайных именах прямо из кэша. В результате большая часть запросов так и не попадет на сервер имен.

Кэширование NSEC на рекурсивных резолверах было проанализировано в лабораторной конфигурации Петром Шпашеком (Petr Špaček) из CZNIC. Петр подавал запросы на рекурсивные резолверы с помощью инструмента повтора запросов и сравнивал конфигурацию с кэшированием NSEC и обычный кэш NXDOMAIN. По его данным, кэширование NSEC оказалось особенно эффективным для борьбы с атаками, основанными на генерации случайных имен.

Кэширование NSEC поддерживает целый ряд изготовителей инструментов рекурсивных резолверов DNS, включая BIND, Unbound и KNOT: либо по умолчанию, либо в качестве опции при настройке.

Измерение кэширования NSEC

Мы в APNIC Labs давно изучаем различные аспекты инфраструктуры DNS и подумали, что было бы неплохо проверить, имеет ли в наши дни смысл реализовывать DNSSEC с кэшированием NSEC. Мы хотели получить ответ на вопрос: насколько сейчас эффективно кэширование NSEC?

Вопрос непростой, поскольку мы пытались измерить то, что не видно с поверхности. Нам нужно было отслеживать те запросы на преобразование несуществующих имен, которые НЕ передаются на авторитетный сервер имен зоны. Иными словами, мы искали отсутствующие ответы на запросы об отсутствующих именах!

И снова мы для этой цели использовали платформу для измерений интернет-рекламы. Платформа рассылает примерно 5-10 миллионов реклам в день по всему «видимому» Интернету, а реклама содержит встроенный Javascript, который указывает «подопытному» выбрать небольшой набор URL. Используя имена DNS, выдаваемые авторитетным сервером имен под нашим управлением, мы можем наблюдать DNS-взаимодействие между рекурсивными резолверами конечного клиента и экспериментальными серверами DNS. Непосредственные действия клиента нам не видны, равно как и то, что происходит в DNS между клиентом и его рекурсивными резолверами: нам видны только наши серверы на нашем конце соединения.

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

Искать запрос, которого не должно быть, непросто, так как в скриптах измерения есть и элемент частичного выполнения, поэтому несуществующие запросы легко спутать с экспериментальным шумом. Для лучшей интерпретации результатов мы использовали двухэтапный процесс DNS, где уникальное имя преобразовывается в ответ CNAME (подписанный по DNSSEC), который сопоставлен с несуществующим именем, и эксперимент использует два прохода: первый для загрузки кэша, а второй для использования кэша. На рис. 1 изображена последовательность прохождения запроса DNS.

Рис. 1. Измерение кэша NSEC: модель запроса DNS.

Тупиковый резолвер в оконечной клиентской системе получает задачу – выполнить преобразование двух доменных имен, оба со случайными метками. Первое имя взято из зоны, подписанной DNSSEC, второе – из неподписанной зоны.

Когда авторитетный сервер имен получает запрос о первом имени, он отвечает записью CNAME, указывающей на имя в другой подписанной зоне. При запросе этого нового имени авторитетный сервер отправляет в ответ код NXDOMAIN. Если в состав запроса входит флаг OK EDNS(0) DNSSEC (бит DO), то авторитетный сервер также возвращает запись NSEC, охватывающую пространство имен зоны нового имени.

Второе имя не подписано и всегда приводит к появлению ответа NXDOMAIN.

Затем скрипт делает паузу в 2 секунды и повторяет те же самые два запроса, но с чуть-чуть измененным именем. Для подписанной зоны ответ CNAME будет использовать имя, которое попадает в диапазон, обозначенный предыдущей записью NSEC. Если рекурсивный резолвер выполняет кэширование NSEC, то он выдаст ответ на основе этой же записи NSEC, не опрашивая авторитетный сервер. В примере на рис. 1 на запрос имени name3.signed2.example можно отправить ответ из локального кэша NSEC.

Мы получили тест, который (в теории) способен показать, где рекурсивные резолверы используют NSEC и где нет. Рекурсивный резолвер с кэшированием NSEC сгенерирует только пять запросов к авторитетному серверу имен, в то время как рекурсивные резолверы без средств безопасности или без кэширования NSEC выдадут запросы на все шесть уникальных имен.

Ожидания

Рекурсивные резолверы с проверкой DNSSEC использует целых 29% пользователей Интернета – на удивление много. Примерно 8% пользователей находятся в смешанной среде резолверов с проверкой DNSSEC и без, так что когда резолвер с проверкой DNSSEC возвращает SERVFAIL, что означает неудачную проверку, тупиковый резолвер повторно отправляет запрос, уже к серверу без проверки. Остальные 21% используют только рекурсивные резолверы с проверкой DNSSEC. (Рис. 2)

Рис. 2. Использование валидации DNSSEC в мире.

Нас в этом контексте интересует более высокая цифра – 29% пользователей, т.к. ответ NXDOMAIN должен приниматься без вопросов, а запись NSEC отправляться на рекурсивный резолвер. Иными словами, даже в частичном сценарии резолвер с проверкой DNSSEC, если запрос к нему отправлен первым, генерирует ответ NXDOMAIN, получив который, тупиковый резолвер пользователя не будет опрашивать другие резолверы.

Рекурсивные резолверы – весьма скособоченная структура: небольшое число резолверов используется непропорционально большим числом пользователей. Где-то 12% пользователей первым делом направляют свои запросы на общедоступные серверы DNS Google, и всего 10 крупнейших резолверов обслуживают треть всех пользователей Интернета.

Верхней границей кэширования NSEC по идее должны быть те же самые 29%, что и у проверки DNSSEC. Исходя из понимания, что общедоступные DNS-резолверы Google выполняют кэширование NSEC, нижняя граница должна быть где-то на 10%. В грубом предположении, что кэширование NSEC на резолверах с проверкой DNSSEC составит где-то 50%, мы получим разумное ожидание того, что примерно 15-20% всех пользователей покажут результаты, коррелирующие с кэшированием NSEC.

Результаты

Результаты эксперимента проиллюстрированы на рис. 3.

Рис. 3. Процент экспериментов, указывающих на кэширование NSEC, по дням.

За 98 дней мы провели наш эксперимент примерно 266 миллионов раз. Паттерны запросов, коррелирующие с кэшированием NSEC, обнаружились в 6-9% случаев, остальные не выказывали признаков кэширования NSEC. Цифры были ниже в рабочие дни и выше в выходные. Когда в конце мая объем показов эксперимента снизился, вместе с ним упала и доля кэширования NSEC.

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

А может быть, наши выводы тоже ошибочны, поскольку в DNS все всегда не так и не то, чем кажется.

Балансировщики нагрузки резолверов и кэширование NSEC

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

Каждый день эти три миллиона измерений передавали запросы DNS где-то к 100 тысячам рекурсивных резолверов, которые, как мы видели, опрашивали авторитетные серверы. За 98 дней мы наблюдали 559 357 различных IP-адресов рекурсивных резолверов: этого и следовало ожидать от длинного конца распределения рекурсивных резолверов в Интернете.

Если сгруппировать эти резолверы по подсетям IPv4 или IPv6 (соответственно /24 или /48), мы насчитаем только 295 546 различных подсетей резолверов. Больше половины резолверов, а точнее, 347 302, если считать по IP-адресам, находятся в общей подсети с другим резолвером или несколькими. Весьма вероятно, что это компоненты фермы. Во многих фермах рекурсивных резолверов применяется техника распределенной балансировки нагрузки, при которой несколько машин-резолверов скрываются за одним сервисным адресом, обращенным к клиенту. Так можно построить масштабируемую систему рекурсивных резолверов DNS, добавляя новые машины для того, чтобы справляться с пиками нагрузки на сервис рекурсивного преобразования.

Как в этих фермах распределяется нагрузка? Цикл и иные простые формы распределения запросов могут привести к плохой производительности системы, особенно в части управления кэшем, но в то же время дают лучшую балансировку нагрузки для определенных паттернов запросов. Говоря более общо, каждая машина для рекурсивного преобразования вынуждена поддерживать и заполнять собственный кэш имен, а последовательность запросов на одно и то же имя может попасть к разным машинам, что сведет к нулю эффективность любого кэша на отдельной машине, если распределение основано на относительной загрузке текущей машины по всем компонентам фермы.

Общепринятый подход к распределению потока запросов – хешировать имя запроса и адресовать запросы на одно и то же имя одной и той же машине.
При таком подходе у каждой машины формируется систематический кэш запрашиваемых имен, а вся конструкция может быть очень эффективно настроена. Хеширование имен работает и для имен, «определенных» в DNS (т.е. ответы DNS кэшируются каждый раз на той же самой машине), и для «неопределенных» имен (статус «имя не существует» тоже каждый раз кэшируется на той же самой машине).
А что с кэшированием NSEC и нашим экспериментом NSEC?

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

Что случится, если два этих имени попадут на две разных машины, входящих в кластер резолверов? Оба запроса станут попаданиями мимо кэша и дойдут до авторитетного сервера, пусть и с разных резолверов. А мы, увидев запросы к авторитетному серверу, сделаем вывод, что кэширование NSEC не используется – и, возможно, ошибемся (см. рис. 4).

Как в более общем виде взаимодействуют балансировщики нагрузки резолверов и кэширование NSEC?

У вопросов о DNS, заданных в таком виде, обычно не бывает четкого
«черно-белого» ответа, и наш случай – не исключение: тут тоже однозначного ответа не дашь. Для корневой зоны каждая машина-резолвер быстро набирает полный набор записей из ответов NSEC. Но если зона используется не так часто, запросы «на наполнение кэша» с ответами NSEC могут оказаться распределены по всей ферме, а потому не дать крупного выигрыша от кэширования NSEC. Возможно, неожиданно низкий результат

Рис. 4. Балансировщики нагрузки по хешам имен запросов и кэширование NSEC на «фермах» резолверов

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

В обычной ситуации при опросе имен, невысоко стоящих в иерархии DNS, кэширование NSEC может не дать ощутимого эффекта в плане нагрузки на авторитетные серверы. Кроме того, чем ниже количество запросов, тем ниже эффективность кэширования NSEC. Этим объясняется и снижение процента кэширования NSEC, которое мы наблюдали, когда самих экспериментов стало меньше.
Однако наш сценарий – редкие спорадические запросы – не та ситуация, в которой кэширование NSEC призвано дать значительную выгоду. Если на серверы зоны идет масштабная атака случайными именами, то сочетание большого числа запросов и хеширующего балансировщика нагрузки приведет к тому, что все машины в составе фермы быстро «выучат» все содержимое зоны, после чего рекурсивные резолверы смогут гасить атаки с помощью кэширования NSEC.

Проверка сценария атаки звучит как увлекательное продолжение нашего эксперимента: можно проанализировать уровни интенсивности запросов и их воздействие на эффективность
кэширования на фермах резолверов. Но в наши задачи не входит развертывание DNS-атаки с использованием случайных имен на базе нашей измерительной платформы, даже если объектами атаки станут наши собственные серверы – поэтому мы не сможем измерить эффективность кэширования NSEC в более жестких условиях на реальном Интернете.
Возможно, такие вещи лучше изучать методом моделирования.

Источник: «Looking for What’s Not There»

Выводы

Кэшировать NSEC на рекурсивных резолверах, пожалуй, имеет смысл. Если рекурсивный резолвер уже выполняет проверку DNSSEC, то для него не будет большой разницы в том, чтобы кэшировать диапазоны записей NSEC вместо имен запросов. Нагрузка на рекурсивный резолвер вроде бы не должна вырасти, а с другой стороны, появится возможность повысить эффективность кэширования.
Однако если в этом и заключается весь эффект, то можно вспомнить аргумент о «верблюде DNS». Да, возможно, мы сумеем чуть-чуть повысить общую эффективность работы DNS, но ценой добавления еще одной программной функции, которой нужно управлять, а стоимость пожизненной возни с дополнительным функционалом в коде преобразования DNS все-таки ненулевая для каждой такой дополнительной функции. Так стоит ли овчинка выделки?
С другой стороны, мы вообще мало что можем противопоставить DNS-атакам с использованием случайных имен. Такие атаки могут быть чрезвычайно просты в развертывании, и, как мы видели по предыдущим атакам такого типа, достаточно большая армия ботов позволяет очень просто и легко обрушить DNS- инфраструктуру Интернета. В нынешней среде DNS стала очень концентрированной службой, где считанное количество авторитетных серверов имен обслуживает большой набор имен DNS, связанных с популярными сервисами. Эффективная атака всего лишь на одного оператора подобной службы, как мы видели в октябре 2016 года на примере DYN, может оказаться исключительно действенной. В таком сценарии кэширование NSEC может пригодиться. Возможно, перекрытие значительной уязвимости в инфраструктуре DNS стоит всевозрастающих затрат на очередное дополнение к функции преобразования DNS.