Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
Интересно, что Google Public DNS (8.8.8.8) при взаимодействии с зоной dnssec.pw, которую я на днях снабдил ключами с одинаковыми тегами, продолжает возвращать неконсистентные результаты, если спрашивать об отсутствующих в зоне записях. Например, при запросе TXT-записей в dnssec.pw теперь нередко приходят ответы со статусом SERVFAIL, “RRSIG with malformed signature…” – написано в пояснении. Однако есть и ответы со статусом NOERROR (примерно, половина, как ни странно), где, впрочем, пояснение тоже указывает на “RRSIG with malformed signature…”.
Возможно, конечно, что в данном сервисе на разных экземплярах узлов разное программное обеспечение, но есть и другое, несколько более занятное, объяснение: может так быть, что сервис ограничивает количество попыток проверки подписи для каждой итерации. В зоне четыре ключа ZSK, подпись RRSIG на NSEC – одна, на SOA – две. Соответственно, если у резолвера установлено некоторое предельное количество ошибок проверки подписи, то, когда предел достигнут, резолвер прекращает попытки перебора ключей и возвращает SERVFAIL. Если же ключ удалось угадать за меньшее количество попыток, то возвращается NOERROR. Подсчёт строк с сообщениями “RRSIG with malformed signature” в ответах – укладывается в эту гипотезу, но чтобы судить точнее – нужно собрать дополнительную статистику.
Комментировать »
Немного занимательной математики и глобальной DNS.
Насколько велика вероятность, что в доменах первого уровня глобальной DNS совпадут теги разных ключей DNSSEC? Нередко приходится слышать, что так как тег 16-битный, то и вероятность, примерно, 1/65535 (за вычетом особенностей алгоритма вычисления значения тега и пр.). Это не верно. Если рассматривать совпадения внутри набора ключей DNS, то получаем хрестоматийный пример парадокса дней рождения: нам не важно, чтобы повторилось конкретное, заданное значение тега, напротив – требуется совпадение любого значения внутри любой пары, а это совсем другая история, поскольку количество всевозможных пар велико даже в небольших наборах ключей. Поэтому вероятность совпадения тегов DNSSEC-ключей, на практике, очень велика. Иногда ключи просто обязательно совпадут по тегам. Например, в списке доменов первого уровня (корневой зоны DNS) сейчас 1452 имени, то есть, можно составить 1053426 пар (больше миллиона). А это количество (практически) гарантирует, что будут совпадения тегов ключей.
И действительно, если собрать DNSKEY-записи из доменов первого уровня, то окажется, что значений повторяющихся тегов, – то есть, значений, которые встречаются для разных ключей в разных зонах, – сильно больше сотни: у меня получилось 129 таких тегов. Обратите, кстати, внимание, что некоторые ключи разных зон TLD имеют одинаковые теги потому, что это просто одинаковые ключи. Такие повторы отбрасывались. Потому что корректно – сравнивать именно сами значения ключей (как и в прочих случаях использования тегов). Например, различные DNSSEC-ключи с одинаковыми тегами опубликованы в зонах cab и today, в зонах agency, weber и temasek, и во многих других.
(Дополнение: естественно, выше предполагается, что ключи для различных зон генерируются независимо, случайным образом.)
Комментировать »
DNSSEC-подписи, удостоверяющие адресную информацию, размещаются в RRSIG-записях. Ссылка на открытый ключ, нужный для проверки подписи, в RRSIG записывается в виде 16-битного тега (KeyTag), который вычисляется по достаточно простому алгоритму от данных ключа. Соответственно, ключи публикуются в DNSKEY-записях. Можно ли специально подобрать несколько валидных ключей так, чтобы у них были одинаковые теги? Очевидно – можно (ключей много больше, чем тегов). И подбор совсем нетрудно сделать. Более того – даже сохранятся валидные подписи и, условная, “корректность” зоны с точки зрения DNSSEC. “Корректность” тут в кавычках потому, что, вообще говоря, несколько ключей с одинаковыми тегами не должны бы присутствовать в DNS-зоне, поскольку это нарушает логику ссылок из RRSIG. И хорошо бы в таком случае выводить ошибку валидации, но возможен более мягкий подход, который и используется.
Посмотрите, в качестве примера, на DNS-зону dnssec.pw – там я разместил несколько ключей (ZSK – Zone Signing Key), которые имеют одинаковые теги со значением 12345. Два ключа из четырёх ZSK задействованы в подписывании записей, а поскольку подписи можно проверять методом перебора ключей, то и RRSIG – валидируются, если валидатор резолвера справляется с ситуацией. Пятый ключ – это KSK, точка входа. Схема показана на картинке (ниже), которую сформировал весьма полезный сервис DNSViz. Повторяющиеся идентификаторы (id = 12345) выглядят занятно, однако количество вершин графа соответствует количеству ключей, а рёбра – соответствуют структуре подписей. Так что DNSViz не сломался:

Другой, не менее полезный, сервис для анализа DNSSEC – DNSSEC Analyzer – проверки для данной зоны тоже выполняет корректно, но в таблице результатов совпадающие идентификаторы могут запутать несколько больше, чем на графе GraphViz:

Валидирующие резолверы должны справляться с подобной конфигурацией ключей, однако Google Public DNS (8.8.8.8) возвращает в статусе информацию о “некорректном формате RRSIG”, но ответ всё равно снабжается флагом AD (Authentic Data), обозначающим, что проверка подлинности DNSSEC прошла успешно – впрочем, это соответствует действительности: подписи и цепочка в зоне dnssec.pw сейчас верные.
Комментировать »
Официальное сообщение КЦ .RU/.РФ о вчерашней проблеме с DNSSEC: “возникшая коллизия ключей, в причинах которой в настоящее время продолжают разбираться специалисты Технического центра интернет (ТЦИ) и MSK-IX, привела к временной недоступности зоны .RU для части интернет-пользователей”.
Комментировать »
Одна из ключевых особенностей DNSSEC в том, что подписываются и данные об отсутствии делегирующих DNSSEC-записей (DS-записи) для зон, находящихся уровнем ниже. Поэтому, если у вас валидирующий резолвер, то проблема с подписями в DNSSEC может затронуть и те зоны, в которых DNSSEC нет. (Кстати, а особенность DNS – в том, что это всеобъемлющая для Интернета (и не только) технология, которую мало кто замечает, пока всё работает.)
Комментарии (1) »
DNSSEC предоставляет механизм удостоверения адресной информации в DNS, что требует подтверждения факта отсутствия ответа на запрос. Собственно, это особенность не столько DNSSEC, сколько любой подобной криптографической системы: необходима возможность криптографического подтверждения, что какие-то записи действительно отсутствуют, потому что иначе активный аткующий может просто удалить из DNS-ответов записи, обеспечивающие безопасное делегирование (DS-записи), тем самым сымитировав отсутствие DNSSEC в атакуемой зоне. Отсутствию записей и имён в терминах DNS соответствует NXDOMAIN (нет имени) и NODATA (нет данных записи запрошенного типа). NXDOMAIN – это когда спросили имя test.example.com, а его в зоне example.com нет. NODATA – спросили TXT-запись для test.ru, имя test.ru есть, но ему не соответствует TXT-записи (NODATA это ANSWER:0 со статусом NOERROR, если в терминах BIND).
Так вот, DNSSEC работает с электронными подписями, однако подписать пустое множество здесь нельзя (хотя бы потому, что все пустые множества одинаковые, а это означает, что подобную подпись можно будет скопировать и применять в контексте отсутствия любой записи). Так что типовая реализация DNSSEC как бы подписывает конкретные “дыры”, но для этого заключает их в некоторую внешнюю конструкцию.
Например, для NXDOMAIN “подписываются” два ближайших имени, между которыми оказалось бы запрашиваемое, если все имена в зоне упорядочить. Известно, что эта реализация позволяет третьей стороне проиндексировать имена, существующие в зоне, поскольку ответ на запрос со специально составленным несуществующим именем позволяет видеть соседние существующие имена – это называется DNSSEC zone walking (индексация зоны), и предоставляет хрестоматийный материал для обучения студентов направления “Информационная безопасность”, но не более. Строго говоря, есть два основных варианта решения проблемы “подписывания дыр”: они называются NSEC и NSEC3, а последний предоставляет больше защиты от индексации зоны, однако сейчас это всё лишь иллюстративные детали, поскольку вообще странно считать, будто заведомо публичные записи в зоне должны быть защищены таким странным способом от “обнаружения” – см., впрочем, про “принцип Керкгоффса“. Предложены способы, предотвращающие индексацию зоны путём “подставных” ответов, содержащих специально сгенерированные имена.
Для NODATA подписывается перечень существующих записей для запрошенного имени, а логика близка к NXDOMAIN, но на практике реализовать можно более удобным способом (см. ниже). Сопроводительная информация о границах “дыр” передаётся в записях NSEC (или NSEC3, но в этой заметке рассматривается только NSEC – дальше будет понятно, почему).
При полностью динамической работе DNS на стороне авторитативного сервера всякое противодействие индексации зоны требует динамических подписей. Однако в таком случае обработка NXDOMAIN быстро превращается в проблему, поскольку требуются дополнительные вычисления. Особенно, если в зоне много имён. Грубо говоря, если у вас есть миллион записей с именами хостов в некоторой базе данных, то уже для обнаружения соседних имён придётся строить какой-то индекс и так далее. Если же состав записей постоянно изменяется, а ответ зависит и от видимых характеристик клиента, и от текущего состояния большей системы на стороне сервера, то вычисление NXDOMAIN может вылететь в копеечку (в том числе, из-за большого размера ответа с подписями). Оригинальное решение тут первыми применили в Cloudflare, ещё в 2016 году. Решение основано на модификации логики обслуживания DNSSEC – предлагается, фактически, исключить понятие отсутствующего имени или отсутствующей записи, что позволит генерировать виртуальные подписи на лету (но, обратите внимание, это не отменяет кэширования сгенерированных ответов).
Иными словами – сервер выдаёт “нечестные” ответы. Например, сервер не отвечает резолверу со статусом NXDOMAIN вообще, а вместо этого использует вариант NODATA: на запрос о реально не существующем в зоне имени сервер отвечает, что есть имя, состоящее из префикса \000., приписываемого к запрошенному имени, то есть, это как бы граница (которой в реальной зоне нет), а ответ поэтому содержит одну NSEC-запись; подпись же вычисляется на лету. Для случая “настоящего” NODATA – всё работает аналогично: сервер отвечает, что есть все мыслимые ресурсные записи, кроме той, которую запросил резолвер. Например, если резолвер спрашивает A-запись, то авторитативный ответ будет содержать указание в NSEC на существование NS, SOA, TXT, LOC, SRV и прочих DNS-записей, но не A-записи. Это тоже позволяет генерировать ответы динамически. То есть, авторитативный сервер “обманывает” резолвер, но делает это для того, чтобы экономить вычислительные ресурсы (поэтому механизм называется black lie – вместо white lie, однако это детали литературной терминологии).
Всё это несложно сейчас увидеть снаружи на примере Cloudflare: попробуйте взять dig и проверить самостоятельно на той или иной зоне, поддерживающей DNSSEC на авторитативных серверах Cloudflare. Такая реализация не только позволяет работать с динамической DNS, но и экономит место в ответах (другой существенный способ экономии – ECDSA, которую только и использует Cloudflare, так как ECDSA-подписи короче RSA).
Насколько такой метод универсален и эффективен? Для больших, постоянно изменяющихся наборов DNS-данных, эффективен, однако требует программного решения собственной разработки. При этом, если DNS-зона не особенно часто изменяется, то смысла в динамическом вычислении подписей меньше. Для многих зон обычным является изменение содержания DNS-записей, скажем, раз в месяц (или даже раз в год). С другой стороны, динамическая “подмена” NXDOMAIN может защитить от индексации зоны.
Вычисление подписи на лету означает, что секретный ключ и реализация алгоритма подписи применяются гораздо чаще, чем при “статическом” варианте. Однако это вопрос модели угроз. Так, для атак, использующих побочные каналы утечки, требуется, чтобы можно было вызывать реализацию криптосистемы много раз (естественно, за разумный промежуток времени). Существенным подспорьем тут будет возможность получать подписи на данных известного атакующему состава и в выбранном формате – это, отчасти, как раз и позволяет реализация подмены NXDOMAIN на NODATA. Впрочем, каких-то огромных практических рисков на этом направлении не просматривается.
Комментировать »
Пишут про перехват TLS-трафика сервиса Jabber.ru, без ведома администраторов: это практическая атака, судя по подробному описанию – там всё как положено: MITM в TLS и подмена серверного сертификата на тоже валидный. Как пишут, выпуск сертификата, скорее всего, проведён при помощи перехвата трафика, идущего на оригинальный сервер – подменные сертификаты попали в CT-логи, в описании есть на них ссылки (это сертификаты Let’s Encrypt, конечно).
Вообще, побороться с подобной подменой, когда возможен перехват трафика на уровне хостера (а это практически всегда так), весьма сложно. Единственный более или менее эффективный способ – прямая авторизация серверных ключей клиентом по отпечаткам, однако, это сложно, плохо масштабируется, ну и так далее. (Отмечу, что применительно к Jabber/XMPP – есть схемы с защитой точка-точка, между пользователями – OMEMO, например). Certificate Transparency (CT), CAA и подобные технологии, направленные на УЦ, от таких атак не особо защищают: CT, несомненно, полезно, но часто работает постфактум, потому что, как минимум, нужно клиентам проверять метки в сертификатах; и это, если вообще считать, что CT тут работает – технически, выпустить быстрый подменный сертификат УЦ может без меток логов, ничто этому не мешает; да и метки можно сделать без публикации в логах, если есть ключи от этих логов; но, конечно, это всё существенно усложняет процесс. Что касается CAA-записей: да, это полезно, но для УЦ, технически, отказаться от проверки CAA ещё проще, чем проигнорировать CT-логи и SCT-метки.
(Ссылка: описание инцидента от OpenNet на русском.)
Дополнение: понятно, что УЦ, в такой конфигурации атаки, ни при чём – УЦ не имеет возможности в рамках сетевых протоколов отличить подменный узел от настоящего с точностью, превышающей перенаправление сетевого трафика в локальной сети хостера; естественно, автоматически выпускаемые TLS-сертификаты для веба не могут служить инструментом защиты от подобных атак, это и не планировалось, никакие CT тут не помогут; возможность активного и полного перехвата трафика с подменой – автоматически приводит к возможности выпустить TLS-сертификат с соответствующим именем хоста через УЦ TLS; перехват трафика – позволяет подменить данные и при DNS-проверке, это даже в чём-то проще, но перехватывать нужно трафик к DNS-серверам и/или от них (и не должно быть поддержки DNSSEC, да).
Комментарии (4) »
Обычно, DNS-резолвер должен работать внутри VPN-сервиса – то есть, это может быть буквально обособленный резолвер, используемый именно в составе VPN (желательно, с DNSSEC). Но так делается далеко не всегда. Напомню, что DNS-резолвер (в данном случае, речь про рекурсивный резолвер) – это сервис, который проводит опрос серверов DNS, отыскивая, например, IP-адреса по именам узлов – адрес, по которому нужно браузеру обращаться к веб-серверу под именем test.ru. Резолвер выполняет то, что называется рекурсивным опросом: обращается к авторитативным DNS-серверам разных уровней. Эти серверы видят IP-адрес резолвера, но не клиента резолвера, который (вероятно) будет подключаться к сервису по обнаруженному в DNS адресу. При этом, для целей балансировки нагрузки на “целевой” сервис, DNS-серверу удобно было бы знать что-то о клиенте, для которого работает конкретный резолвер – потому что балансировка выполняется именно для клиента сервиса, а не для клиента DNS (сервис доменных имён (DNS) в этот момент уже на нужной стороне отработал). Это особенно актуально для больших открытых сервисов DNS-резолверов, например, Google Public DNS, так как эти сервисы обслуживают клиентов из самых разных точек сети. Чтобы как-то помочь оптимизации, довольно давно придумали расширение DNS под названием EDNS Client Subnet (ECS).
Данная технология (ECS) позволяет резолверу передать в сторону авторитативного сервера сведения об IP-подсети клиента, который обратился с запросом. Проще говоря – авторитативный сервер увидит IP-адресный блок, который соответствует клиенту, находящемуся за резолвером, что позволит определить провайдера. ECS как раз поддерживается Google Public DNS (и не только). Предполагается, что авторитативный сервер, определив провайдера клиента резолвера, сможет применить какие-то правила оптимизации. Если VPN используется для сокрытия IP-адреса пользовательского подключения, но DNS-трафик направляется не через VPN в какой-то DNS-сервис, то наличие ECS в этом сервисе (при прочих равных) означает, что внешние авторитативные DNS-серверы увидят скрываемую подсеть. Об этом нередко забывают.
Технический пример (не учитывающий NAT и другие тонкие настройки): предположим, клиентское устройство использует провайдерский доступ с адресом 10.11.12.13, ему соответствует подсеть 10.11.12.0/24; выход из VPN использует подключение с IP 10.22.22.22 (подсеть 10.22.22.0/24); DNS-трафик направляется напрямую (не через VPN) резолверу 10.53.53.53, резолвер поддерживает ECS. Тогда, при попытке определить значение A-записи (адрес), внешние серверы DNS узнают, что к ним подключается резолвер с адресом 10.53.53.53 для клиента из подсети 10.11.12.0/24. А вот на веб-сервере, к которому обращение произойдёт через VPN, адрес клиента будет виден как 10.22.22.22 – внешняя точка VPN. Естественно, если DNS-трафик маршрутизируется устройством через VPN, то внешний DNS-сервис с ECS сможет передать наружу только подсеть точки выхода VPN (10.22.22.0/24), поскольку именно адрес из этой подсети он видит в качестве источника запроса. Но лучше, конечно, если вообще используется собственный резолвер без ECS в составе VPN-сервиса, потому что возможны и другие каналы утечки метаинформации.
Комментировать »
Если вы управляете авторитативным сервером глобальной DNS, то в логах можете увидеть “странные” запросы с именами, составленными из букв в разном регистре (см. скриншот).

DNS-серверы должны игнорировать регистр символов имени из состава запроса. Записи dXdT.RU. и dxdt.ru. – должны считаться совпадающими. Есть, впрочем, свои особенности: DNS-ответ включает в себя и имя из запроса, а одно из толкований требования об “игнорировании регистра” состоит в том, что если регистр игнорируется, то его можно игнорировать и в ответе. То есть, с одной стороны, ответ должен содержать имя в точно таком же формате, в каком оно поступило в запросе (обычно, так и происходит), с другой стороны, если считается, что при сравнении регистр не имеет значения, то имена dXdT.RU. и dxdt.ru. – равны, а поэтому можно в ответ смело писать dxdt.ru. (или DxDt.ru., например).
Тем не менее, регистр символов довольно давно предложено использовать в качестве носителя дополнительной информации – для рандомизации состава запроса. Это создаёт ещё один инструмент для защиты от атак на DNS, которые используют поддельные ответы, опережающие соответствующий запрос по времени. Подобная атака состоит, например, в том, что в адрес рекурсивного резолвера отправляется большое количество пакетов, имитирующих ответ на DNS-запрос от авторитативного сервера, но содержащих подменные данные, например, IP-адрес сервера злоумышленника в A-записи. (DNS использует UDP, поэтому такая подмена возможна на уровне транспорта.) Если рекурсивный резолвер не сможет отличить подменный пакет от настоящего, – который, хотя бы, соответствует запросу, – то в локальный DNS-кэш попадёт подставное значение, оно и будет передаваться узлам, использующим данный резолвер (это называется “отравление кеша”). Естественно, для того, чтобы атака сработала, резолвер должен ожидать ответ об атакуемой зоне, но это не так трудно организовать: есть очень популярные зоны, запросы об именах в которых регулярно возникают; кроме того, нужный запрос может быть отправлен в резолвер самим злоумышленником. Последний вариант хорошо подходит для популярных открытых сервисов DNS, таких, как Google Public DNS, где, как раз, рандомизация регистра букв широко используется (собственно, запросы со скриншота – пришли из этого сервиса).
Как рандомизация регистра символов помогает защитить DNS-ответы? Довольно очевидным способом: резолвер отправляет запрос, в котором символы имени указаны в разном регистре, тем самым кодируя некоторое битовое значение (понятно, что строчная буква может кодировать единицу, а заглавная – ноль); закодированное значение резолвер запоминает и проверяет совпадение регистра в полученном ответе. Тогда, если ответ сгенерировал кто-то, кто реально видел запрос, то этот кто-то сможет подставить правильный код в регистр символов. Схема не защищает от отправки ответа раньше настоящего авторитативного сервера (или вместо этого сервера), но от отправки ответа раньше запроса – защищает. Рандомизация параметров DNS-запроса, снижающая предсказуемость параметров ответа, реализуется в DNS и другими способами. Прежде всего, это номер порта источника (номер порта – 16-битное значение), кроме того, в запросе есть поле Transaction ID (ещё 16 бит). Регистр букв имени может добавить заметное количество значимых битов. Если, конечно, технология поддерживается на стороне авторитативных серверов. И если кто-то не решил “посигналить” строчными/заглавными в обратную сторону. В общем, много “если”. (Напомню, что полноценную защиту от подмены ответов предоставляет DNSSEC.)
Комментарии (2) »
Предположим, что некоторые интернет-измерения, проводимые с использованием веба, полностью основаны на уникальном имени хоста, которое генерируется под каждый запрос. Это очень удобный способ создания информативного маркера, переходящего между протоколами. Имя нетрудно встроить, например, в адрес источника файла изображения, ссылка на которое входит в состав кода веб-страницы. Почему подходит именно имя хоста? Потому что оно же будет использоваться клиентом и в DNS, и в HTTP. А вот часть URL, соответствующая адресу документа, уже в DNS не ходит. Другими словами: используем в браузере (условный) URL https://123dio.cba.example.net/an-img.gif, где полезные данные кодируются в части 123dio.cba. Строка 123dio.cba.example.net отправится и в DNS, где будет узнана специальным сервером, и в HTTP, а вот an-img.gif – в DNS не попадёт, а поступит только на веб-сервер, отвечающий под 123dio.cba.example.net. Соответственно, насыщение HTTP-запросов полезной информацией, которую мы хотим видеть и в DNS, должно происходить через имена хостов.
Однако возникает неприятная проблема с HTTPS: дело в том, что для установления соединения с браузером сервер под “странным” именем 123dio.cba.example.net должен предъявить TLS-сертификат, валидный для этого имени, но имя-то каждый раз разное, поэтому сертификатов не напасёшься (если их выпускать через тот или иной УЦ, признаваемый браузерами). Использование открытого HTTP тут не рассматриваем – такие условия: хотя бы потому, что страница-носитель загружается по HTTPS. Что можно сделать? А можно, например, совсем отказаться от установления TLS-соединения на стороне сервера и при этом не потерять полезных данных. Нам не требуется реально обрабатывать HTTP-запрос и возвращать файл изображения, нам нужно только зафиксировать на сервере имя хоста, а это имя в HTTPS/TLS передаётся клиентом в начальном сообщении, да ещё и в открытом виде (это как раз и есть SNI TLS). Так что серверный сертификат тут просто не нужен: сервер записывает имя хоста из SNI и – прерывает соединение с тем или иным кодом ошибки TLS.
(Дополнение – 30/04/2023: в комментариях справедливо указывают на wildcard-сертификат для имён вида *.example.net. Однако тут такой сертификат не сработает, поскольку для DNS-части измерений важны кодирующие имена минимум в двух уровнях, то есть, *.*.example.com, а wildcard-сертификат закрывает только один уровень. Несколько уровней – входят в качестве требования в изначальную задачу, оставшуюся здесь за скобками.)
Комментарии (4) »
Подписи DNSSEC в глобальном корне DNS появились в 2010 году. Это подписи криптосистемы RSA, которая сейчас считается устаревшей. Ввод DNSSEC прошёл в таком режиме, который не содержал даже механизма обновления корневых ключей – этот механизм внедрили существенно позже. Корневой ключ заменили, но криптосистема осталась той же – RSA. И вот, в 2023 году ICANN “планирует начать процесс подготовки” внедрения новых криптосистем в корневой зоне DNS: на днях опубликовали сообщение о создании рабочей группы. Можно предположить, что в корне DNS появится ECDSA, а может быть даже и что-то из разряда EdDSA (но этот вариант, конечно, вряд ли).
Комментировать »
Новый