Хроники разваливающихся интернетов. Я, в силу ряда причин, использую DNS-резолвер, который установлен за пределами Рунета. С некоторых пор я заметил, что ряд вспомогательных сервисов для аккаунта Google – недоступны из браузера, из моей локальной сети. А я всё ещё использую для ряда задач почту Google – так исторически сложилось, тем более, что, в отличие от того же “Яндекса”, Google мне пока что эту историческую почту и кучу прочих сервисов под моим доменом (из Рунета, заметьте) предоставляет бесплатно, как ни странно; не знаю, долго ли ещё так будет, но пока что – так; недостатки там тоже есть, кто бы сомневался, но это другая история: а сервис, как минимум, никто за эти десятилетия у меня не отобрал – очень существенный плюс Google, по нынешним временам-то.

Вернёмся, впрочем, к доступности.

Итак, я заметил, что какие-то сервисы через HTTPS недоступны, а они необходимы для нормальной работы веб-интерфейса (там всё управление – через веб). Логичное предположение: так как мой резолвер приходит на авторитативные серверы Google из “иностранной сети”, ему DNS Google отдаёт другие IP-адреса, а именно – адреса, предназначенные для соответствующего региона; и узлы под этими IP-адресами – недоступны из российских сетей. Почему это влияет? Потому что браузером-то я подключаюсь из российской IP-сети. Где именно соответствующий трафик забанен – я уже не стал разбираться: сейчас подобное разбирательство – легко превращается в длительное исследование, так как понять, “что-как-где-почему”, довольно сложно: сети окончательно стали мутными на прикладном уровне. Да, я делал бы ставку на то, что забанено на российском транзите; но, к сожалению, тут нельзя полностью исключать и сторону CDN Google – вообще говоря, агрессивная геобалансировка на стороне крупнейших провайдеров была известна и раньше, иногда, скажем, такая блокировка может быть побочным эффектом маршрутизации для anycast-адресов (отдельная история).

В общем, я просто добавил на сторне своего DNS-резолвера функцию отправки подсети-источника DNS-запроса в ECS, но только для доменов внутри зоны google.com, чтобы авторитативные DNS-серверы на той стороне видели целевой IP-префикс запроса. В Unbound (весьма рекомендую, кстати) избирательная поддержка ECS легко включается. После того, как в запросы добавились ECS – IP-адреса в ответных A-записях стали приходить другие, а сервис Google – тут же заработал из локальной сети. Да, откровенно говоря, не могу исключить, что это совпадение, но посмотрим: в других, – более прозрачных, но аналогичных, – случаях, с которыми я сталкивался, подход с перенастройкой резолвера срабатывал эффективно.



Комментировать »

DNSSEC строится на механизмах цифровой подписи и на иерархии криптографических ключей. Открытые ключи публикуются в DNSKEY-записях. Подписи вычисляются для адресной информации, опубликованной в зоне. Значения подписей публикуются в RRSIG-записях. Ключей и, соответственно, DNSKEY-записей в DNS-зоне может быть несколько. Чтобы доверенным образом проверить подпись, резолвер должен выбрать подходящий ключ. Чтобы упростить поиск подходящего ключа – в RRSIG-записях указывается 16-битный тег, соответствующий ключу. Это и есть тег ключа DNSSEC. (Тег ключа используется также в DS-записи, которая обеспечивает другой важнейший аспект: делегирование в DNSSEC, но ниже речь пойдёт только про RRSIG.)

Значение тега представляет собой простейшую “контрольную сумму” – то есть, сумму октетов DNSKEY-записи, выполненную в определённом порядке (чётные/нечетные и т.д.). Очевидно, что используемый алгоритм вычисления тега тут вообще не имеет особого значения – в теге всего 16 битов, а в ключе, как минимум, 256 битов: коллизии тут всегда будут достигаться легко.

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

Если теги разных ключей в зоне не совпадают (обычно, в добропорядочной зоне, это так и есть, но см. ниже), а в RRSIG – указано верное значение, то, конечно, это ускоряет процесс выбора ключа и проверки подписи. Проблема в том, что вычислительные затраты на проверку подписи по “пробному ключу” сильно меньше, чем затраты на обработку специально неверно сконфигурированной зоны с совпадающими тегами ключей. И ещё хуже, что неверная интерпретация свойств тегов регулярно приводит к масштабным сбоям в практике DNSSEC – отламываются целые большие TLD (это было в зоне .RU, это же теперь было и в .DE, которая в несколько раз больше).

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

Естественно, штатный способ выбора ключа состоит в сравнении тегов: если в зоне единственный ключ с совпавшим значением тега, и этот ключ не даёт доверенной подписи для заданной RRSIG-записи, то, понятно, другие ключи можно не проверять. Почему? Потому что спецификация требует, чтобы тег, указанный в RRSIG, совпадал с тегом ключа. Заметьте, что нигде не сказано, что соответствие должно быть один к одному – тег-ключ. Но даже в случае такого совпадения, это всё равно будет пробная проверка подписи – просто, в штатной конфигурации, используется единственная итерация. Всё потому, что тег не обязательно соответствует одному ключу.

Из обратной ситуации, то есть, из того, что ключи должны соответствовать тегам, но разные ключи могут иметь одинаковый тег, и выводится DoS-атака: в зоне может быть несколько ключей с одинаковыми значениями тега и резолвер должен перебирать эти ключи для проверки RRSIG, которая теперь ссылается единственным тегом на множество ключей. При этом, RRSIG-записей может быть много. И криптосистем тоже может быть несколько. Это известная DoS-атака под названием KeyTrap (CVE-2023-50387).

А из обобщения принципа, что теги недопустимо использовать в качестве идентификаторов ключей при вычислении подписи (а лишь как первый шаг, сужающий набор для перебора, при проверке подписи) и публикации ключей в DNS-зоне, выводится угроза штатной подмены ключа в процессе подписывания зоны: из-за того, что схему ломает единственное совпадение пары значений тегов, вероятность совпадения для разных ключей, результатом которого будет сбой – очень и очень велика. То есть, в схеме подписи, для её вычисления, использовался один ключ, но где-то рядом сохранился второй ключ, с совпавшим тегом, и в зоне будет опубликован этот второй, неподходящий ключ. Но неподходящий он – по значению подписи, не по значению тега – значение тега-то, как раз, подходит под RRSIG, а поэтому простая проверка на соответствие тегов, на уровне, что в зоне есть ключи с тегами из RRSIG, успешно пройдёт. К сожалению, из-за особенностей DNSSEC, такая проверка имеет весьма небольшую пользу: ключи должны строго и по тегу сходиться, и по подписи.



Комментировать »

В DENIC опубликовали некие сведения о причинах недавней поломки DNSSEC в зоне .DE (DENIC – оператор). Как ни странно, но, похоже, причина именно в некорректном использовании тегов ключей. Я как раз в прошлой записке по этой теме такое и предположил: “возможно, тоже перепутали ключ из-за совпадающих тегов”. Выходит, что снова использовали теги для индексирования ключей в процессе подписи. Теги – могут запросто совпадать у разных ключей. К сожалению, как это нередко бывает, в опубликованном пояснении формулировка расплывчатая:

Consequently, for the same “key tag” (33834), three different key pairs were generated instead of a single one, of which only the public key of a single pair was stored in the DNSKEY RR, meaning that only about a third of the RRSIG RRs could be validated. (В результате, для одинакового “тега ключа” (33834) были сгенерированы три разных ключевых пары вместо одной, из которых только открытый ключ единственной пары был размещён в DNSKEY-записи, что привело к тому, что только треть из RRSIG-записей могли быть валидированы.)

Ну, то есть, можно предположить, что раз только треть валидировалась, значит – остальное подписывалось другими секретными ключами, из пар, имевших один и тот же тег открытого ключа, а ПО ссылалось на ключи по значению тега (чего делать при подписывании нельзя категорически). Тут может возникнуть сомнение: как же тогда так получилось, что для трёх разных ключей совпал тег? Да, чтобы тег заведомо совпал для ключей, сгенерированных на небольшом интервале времени, ключи нужно специально перебирать (но и это нетрудно – там всего-то 16 битов в теге). Но дело в том, что ключи подписи зоны постоянно заменяются при штатной работе, так что эти пары с совпавшими тегами скорее всего были старыми ключами, сгенерированными ранее, и не удалёнными из системы. Теги же совпадут с большой вероятностью, так или иначе, если просто генерировать ключи штатным образом – только будет несколько дольше по времени: вероятность там много больше, чем 1/65535, как продолжают думать, – ведь это типовое воплощение парадокса дней рождения.

Собственно, в недавней записке об аварии DNSSEC в .DE я поэтому и упомянул конфликты тегов ключей DNSSEC, которые теги используют не по назначению. Цитата:

В DNSSEC выбрана неудачная система тегирования ключей при помощи 16-битных номеров, которые, понятно, то и дело совпадают для разных ключей; данные теги нельзя использовать в качестве индекса при выборе ключей для подписи, об этом написано в RFC, об этом много писал и говорил я, и не только я, но теги всё равно регулярно используют с такой целью; однако насчёт данного случая с DE – не факт, что в этом была проблема.

Оказалось – в этом и была проблема. Что тут ещё сказать? Бывает, конечно: ведь с пониманием сложных процессов – сейчас трудности везде.



Комментировать »

В домене .DE на некоторое время сломались подписи DNSSEC. Сейчас уже пишут, что починили. Возможно, тоже перепутали ключ из-за совпадающих тегов. (Лирическое отступление: в DNSSEC выбрана неудачная система тегирования ключей при помощи 16-битных номеров, которые, понятно, то и дело совпадают для разных ключей; данные теги нельзя использовать в качестве индекса при выборе ключей для подписи, об этом написано в RFC, об этом много писал и говорил я, и не только я, но теги всё равно регулярно используют с такой целью; однако насчёт данного случая с DE – не факт, что в этом была проблема.)

Интересна тут реакция Cloudflare, как оператора одного из самых распространённых в этих интернетах сервиса DNS-резолвинга – 1.1.1.1: в Cloudflare, после локализации ошибки на стороне DE, валидацию DNSSEC для этой зоны просто отключили. Ну, то есть, очередной пример реальной ценности DNSSEC в современой глобальной DNS: если что не так, то систему валидации принято отключать; но, конечно, не просто так отключать, а информированно отключать.

Есть даже RFC 7646, который, кто бы мог подумать, прямо предписывает так делать. Естественно, речь тут идёт об операторах DNS-сервисов, которые могут убедиться, что, мол, “это не атака подмены”, а это DNSSEC сломали сами администраторы ключей, очередной раз. Хотя, строго говоря, достоверно определить, что подписи стали расходиться не из-за атаки, а из-за ошибки – весьма и весьма сложно: атака могла быть на уровне оператора реестра, например. Может ли тут что-то с уверенностью – и, главное, быстро, – сказать внешний наблюдатель, даже если он оператор резолвера? Ну, это вряд ли. Остаётся полагаться на ответы оператора реестра и, что называется, кликать виртуальную универсальную кнопку “Всё равно продолжить” для всех пользователей своего “валидирующего” резолвера. Такая вот нынче стала на практике эта технология – DNSSEC. Ничего не поделать.



Комментировать »

Хроники разваливающихся интернетов и проблем с диагностикой разваливания. Понадобилось тут проверить один технологический артефакт в связке DNS+TLS, для чего я поднял виртуальный сервер у одного из провайдеров (не буду назвать, это не важно) и установил там BIND в качестве авторитативного DNS-сервера для тестовой зоны. И вот – BIND работает, а TXT-записи, в ответ на DNS-запросы снаружи, не приходят. Локально, на том же хосте, – приходят ответы TXT. С другими запросами – SOA, NS – всё хорошо, ответы приходят и наружу. TXT – не приходит. Но не приходит – по UDP. А зато по TCP – приходит.

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

Видимо, так вот решили “гибко” (может, даже с новомодным ИИ) побороться с источниками DoS-атак: широко известно, что TXT-записи являются носителем трафика для DoS-атак, так как эти записи могут содержать большой объём данных, а если “подспуфить” UDP, подставив чужой адрес, то большие пакеты поедут в сторону этого, чужого, адреса. Другие типы записей – обычно не считаются носителями трафика для DoS.

Да, строго говоря, фильтровать-то нужно по “подспуфленным” UDP, а не по единственному признаку TXT – подобная грубая фильтрация DNS-ответов приводит к тому, что в такой сети невозможно держать авторитативный NS: без TXT сейчас никуда – и почта их использует, и валидация при выпуске TLS-сертификатов. Зато получилась очередная практическая демонстрация того, как эти интернеты становятся непрозрачными даже не только на уровне протоколов, но на уровне некоторой “внутрипротокольной” семантики. Да, конечно, такая вот, – типа, “гибкая и интеллектуальная”, – фильтрация была и раньше, в том числе, по DNS-ответам. Это просто свежий практический пример.

Кстати, хотя есть и другие варианты DNS-записей, которые могут содержать большие объёмы ответов – см. DNSSEC, например, – но с TXT – проблема более чем известная: в зонах бывает много TXT, скажем, в google.com сейчас 13 записей почти на килобайт, и это – ещё совсем не много; кроме того, что-то ещё и забывают почистить, так что записи накапливаются. Естественно, извлекать откуда-то из целевой зоны толстый набор TXT-записей может и открытый рекурсивный резолвер, не обязательно держать авторитативный сервер: фильтруется оно одинаково.



Комментарии (2) »

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

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

Вот тут и возникает “странная дилемма DNSSEC”: ECDSA, без сомнения, вариант прогрессивный, по сравнению с RSA, но против алгоритма Шора – стойкость имеющейся RSA выше (2048 бит против 256), а криптосистемы с постквантовой стойкостью – тут пока и не рассматриваются.



Комментарии (2) »

Кстати, в продолжение предыдущей записки: в какой последовательности нужно отключать DNSSEC-записи? Прежде всего – нужно удалять DS-записи из вышестоящей зоны. Дело в том, что именно DS-запись, которая содержит отпечаток ключа, говорит валидирующим резолверам о том, что данная зона “делегирована безопасно”.

Это самый важный момент: делегирующие ответы, с NS-записями, в DNSSEC не подписываются – в этом нет никакого смысла, потому что доверие в DNSSEC формируется по цепочке ключей, а не по адресам/именам серверов. (Собственно, как и во всякой подобной криптографической схеме.) Поэтому подписываются в DNSSEC записи, указывающие на ключи. В случае делегирующего ответа – это DS-запись. Более того, так как необходимо обеспечить криптографическое удостоверение факта отсутствия DS-записи для заданного имени, удостоверяется и то, что конкретной, по имени, DS-записи нет.

Теперь перейдём к процессу отключения DNSSEC. Речь, естественно, о полноценной поддержке, когда DS-записи присутствуют по всей цепочке до корня DNS. Так вот, самая распространённая ошибка – удаление DNSSEC-записей в самой, целевой зоне, без удаления DS-записей в делегирующей зоне. Так делать нельзя потому, что, с точки зрения валидирующего резолвера, тут же развалится доверенное делегирование. Возникает вот какая конфигурация: в ходе рекурсивного опроса резолвер получает DS-запись из делегирующей зоны, и параметры этой записи удостоверены DNSSEC-подписями из делегирующей зоны (по всей цепочке делегирования); однако из целевой зоны резолвер не может получить соответствующего ключа DNSSEC (в DNSKEY-записи), поэтому резолвер определяет, что DNSSEC-цепочка нарушена и возвращает ошибку валидации адресной информации – зона перестаёт работать. При этом, для невалидирующего резолвера, всё “работает” – ведь такой резолвер ничего не знает ни про DS-записи, ни про DNSKEY, ни про подписи (RRSIG). Поскольку сейчас распространённые сервисы DNS-резолвинга валидируют DNSSEC, – например, так делают 1.1.1.1 и Google Public DNS, – то и зона, для которой “повисла DS-запись”, отваливается для многих и многих пользователей.

Поэтому, прежде чем удалять поддержку DNSSEC непосредственно в зоне, нужно удалить DS-запись из делегирующей зоны. Например, в случае example.net – это будет DS-запись в зоне .net. После успешного удаления – нужно подождать какой-то разумно-максимальный срок TTL. Скажем, сутки.

Какая конфигурация получится после того, как делегирующая DS-запись удалена, а в целевой зоне осталась поддержка DNSSEC (ключи и подписи)? После того, как делегирующая зона обновится, в ней появится набор записей, подтверждающих, что DS-запись отсутствует. Вообще, подтверждение отсутствия записи представляет собой в DNSSEC отдельную задачу, которая решается разными способами, но сейчас это не важно – главное: способ подтверждения, при помощи подписи, есть. Теперь валидирующий резолвер может удостовериться, что DS-записи нет, и что зона делегирована “небезопасно”. Соответственно, можно не пытаться проверить DNSSEC-подписи для информации с авторитативных серверов этой зоны. И в такой конфигурации – уже можно без проблем удалить поддержку DNSSEC из целевой зоны: валидирующие резолверы не сломаются.

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



Комментарии (2) »

В продолжение предыдущей записки: можно ли вообще обойтись без доменного имени для веб-сайта? Можно, но это доставит некоторых дополнительных проблем, да и “игра” получается с другими правилами. В принципе, сейчас уже можно автоматом заказывать и выпускать TLS-сертификаты для IP-адресов от хорошо известного (доверенного в “коробочных” браузерах) УЦ – это сертификаты от Let’s Encrypt, на шесть дней валидности.

Наличие TLS-сертификата и выделенного IP-адреса позволяет поднять веб-сервер с доверенным TLS прямо по IP-адресу, без использования доменного имени. Вот, посмотрите, я сделал для примера – должно работать в любом распространённом веб-браузере:

185.39.19.199.

Этот URL – использует https, но указан просто IPv4-адрес, а не имя хоста/доменное имя. Сертификат я за несколько секунд выпустил при помощи утилиты certbot и профиля shortlived, всё при nginx в качестве веб-сервера, вот так:

certbot certonly \
--preferred-profile shortlived \
--ip-address 185.39.19.199 \
--webroot --webroot-path /var/www/html/

Да, конечно, нужен выделенный IP-адрес. На одном адресе, в такой схеме, может отвечать только один веб-ресурс (ну, если не использовать хитростей, напоминающих ECH). IP-адрес принадлежит тому или иному оператору, и оператор может его забрать, поменять, перенаправить трафик. Всё то же самое верно и при использовании доменного имени: с той лишь разницей, что, в случае доменного имени, поменять/забрать/перенаправить – касется и домена, и IP-адреса (адресов). Но при прямом использовании IP-адресации не нужна поддержка DNS для соединения с конкретным сайтом из браузера (тут речь именно про конкретный процесс из области веба, так-то, без DNS, не работает и IP тоже).

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

Понятно, что главная-то проблема с таким использованием IP-адресов – это то, что пользователю сложно запомнить обычный адрес. А адресов вида 1.1.1.1 или 8.8.8.8 – очень мало по определению. Кроме того, наверняка будут проблемы с ПО для веба, которое ПО может быть заточено под имена хостов. (Точно будут проблемы с почтовым ПО, но это не веб.)

И всё же, хотя бы возможность простого выпуска TLS-сертификатов для IP-адресов может тут оказаться полезной.

(Но я пока что не планирую переводить dxdt.blog на “чистую” IP-адресацию. Хотя, кто знает.)



Комментировать »

Благодаря влиянию ACME и Let’s Encrypt, сейчас стала очень популярной схема подтверждения права управления доменом (DCV) через DNS, но при помощи размещения CNAME-записей. Речь про запрос TLS-сертификатов средствами автоматизации – скриптами (acme.sh, certbot и др.). Напомню, что DCV здесь состоит в проверке размещения TXT-записи с кодом подтверждения под заданным именем в DNS-зоне (это метод DNS-01). ACME использует специальный префикс: _acme-challenge.

Однако CNAME – это не TXT-запись, а способ перераспределить проверку в другую DNS-зону (см. детали ниже). Вообще, протокол ACME в данном сценарии не требует ни использования, ни даже поддержки CNAME. Но такая поддержка массово используется, и её сейчас принято обосновывать тем, что можно, мол, “не предоставлять доступ к исходной зоне скриптам автоматизации”. Использование CNAME – вообще плохая практика, а особенно плохая практика – это использование CNAME в процессе DCV. Что, конечно, не мешает массовому распространению. Вообще, с подобным использованием CNAME, – то есть, в DCV, – связана пара занятных технических моментов, о которых забывают.

Момент первый: постоянно путают синоним (алиас) и основное имя в CNAME. Дело в том, что CNAME – это Canonical NAME (каноническое имя), и каноническим является именно значение записи, а не имя-носитель. Имя-носитель – это и есть алиас, что бы там ни писали в инструкциях к средствам автоматизации ACME. Если для example.com в CNAME-записи указано 1.2.3mega-blah-blah.example.net, то вот это вот 1.2.3mega-blah-blah.example.net и есть основное имя. При использовании в ACME предлагается настроить CNAME для префикса _acme-challenge. Например, _acme-challenge.example.com в 1.2.3mega-blah-blah.example.net. Но и тут алиасом, в терминах DNS, будет _acme-challenge.example.com, префикс не влияет на отношение значений записей. Такова семантика CNAME.

Соответственно, получается, что проверка проводится для другого имени, не для того, которое указано в ACME-аккаунте при запросе DCV. Сертификат, в итоге, выпускается для одного имени, а проверка – фактически пройдена для совсем другого: для той зоны, которая назначена канонической при помощи CNAME. Дело в том, что CNAME-запись, при интерпретации резолвером, должна приводить к перезапуску процесса рекурсивного опроса для канонического имени, то есть, для значения из CNAME. Да, может показаться, что это технические придирки: всё равно же CNAME-запись должна быть размещена в исходной зоне, совпадающей с именем из DCV. Но нет, не так тут всё просто: CNAME может показывать на совсем другую зону, контроль над которой позволяет проходить DCV и выпускать сертификаты для прочих имён, в том числе, алиасов может быть много – это каноническое имя, по определению, одно. Если домен канонического имени (того, куда указывает CNAME) будет утрачен, переделегирован-перехвачен, или ещё что-то, то это административное изменение прямо коснётся авторизации TLS-сертификата для исходной зоны-алиаса. Происходит подмена самой сути DCV.

Естественно, можно рассуждать иначе: если утрачено каноническое имя, то нужно удалить CNAME-запись в алиасе; тем более, что так как сертификаты сейчас “короткие”, утрата канонического имени обнаружится быстро. Это верно. Более того, имея контроль над исходной зоной (в которой CNAME) – можно будет попробовать отозвать сертификаты для этой зоны, если такие были выпущены при помощи подхвата CNAME. (Один из штатных способов отзыва сертификата в ACME – прохождение DCV для имён из сертификата; но нужно предъявить сам сертификат, и должно всё сойтись по составу имён – то есть, если в подставном сертификате указана ещё какая-то зона, то могут быть проблемы с отзывом.) Однако это всё только теоретические рассуждения, в стиле “как должно быть”, а на практике, как говорится: ну, на практике-то – и про CNAME-зоны забывают, и про обновление имён, и про отзыв.

Момент второй: реальный доступ к зоне. Из первого момента, с каноническим именем, легко выводится этот второй: да, использование CNAME предлагают в качестве решения проблемы “расползания реквизитов доступа”. Мол, не хочется давать скриптам ACME доступ к редактированию нашей важной доменной зоны, поэтому пропишем CNAME и дадим доступ в другую зону, не такую важную. Но, как бы, смысл DCV – проверка права управления доменной зоной, а тут – это право управления прямо предлагают не выдавать, а подменить саму зону средствами DNS. Опять же, такая трактовка – не “перегиб”: дело в том, что управление зоной должно, если по-хорошему, подтверждаться при каждом выпуске сертификата (ну, хорошо, с некоторым интервалом по времени действия успешной проверки), а CNAME, направленная на каноническое имя – это долгий и универсальный вариант, не привязанный к выпуску сертификата вовсе. Для чего, собственно, использование CNAME и затевается. Опять противоречие.

Кстати, тут полезно вспомнить, что есть и суперновая версия DNS-проверки в ACME – с “постоянной” привязкой ACME-аккаунта к имени: вот где совсем не место CNAME (но черновик RFC пока что их не запрещает явно).

CNAME-записи – одни из самых сложных по поведению в DNS, а их использование – источник неожиданных проблем. В случае DCV, семантика и принципы интерпретации CNAME вообще противоречат основной логике проверки права управления через DNS. Что касается других решений: во-первых, ACME-префикс можно делегировать на отдельные NS, без всяких CNAME; во-вторых, для размещения TXT-записей вовсе не обязательно передавать полные права управления DNS-зоной каким-то скриптам. Это всё решения на стороне, заказывающей DCV. Но самое правильное, конечно, это не следовать CNAME при проверке DCV на стороне систем УЦ.



Комментарии (1) »

В рамках “ренейминга”, связанного с миграцией сайта с доменов .ru, сделал субординатные имена авторитатвиных серверов DNS для dxdt.blog. “Субординатные” – означает, что имена авторитативных серверов (NS) находятся в той же зоне, которая делегирована на эти серверы: например, ns1.example.com, ns2.example.com для example.com. Такую схему именования ещё иногда называют “красивые NSы”. В случае dxdt.blog, имена NS-ов – в зоне dxdt.blog.

Соответственно, делегирующий ответ с такими именами обязательно содержит так называемые glue-записи – то есть, записи с информацией об IP-адресах NSов. Иначе рекурсивный опрос не будет работать, так как зациклится. Я об этом писал неоднократно, в том числе, про сложную рекурсию, связанную с перекрёстными зависимостями.

Например, сама зона .blog размещена на NS-ах с субординатными именами:

alex@garlic-crusher:~$ dig blog. -t NS @a.root-servers.net
[...]
;; AUTHORITY SECTION:
blog.			172800	IN	NS	a.ns.nic.blog.
blog.			172800	IN	NS	d.ns.nic.blog.
blog.			172800	IN	NS	c.ns.nic.blog.
blog.			172800	IN	NS	b.ns.nic.blog.

;; ADDITIONAL SECTION:
[...]

– здесь имена авторитативных серверов в ns.nic.blog., пусть для корневой зоны это и не имееет большого значения (см. ниже). Да, субординатные имена популярны, однако мне подобная схема именования не очень нравится. Другой вариант, из зон верхнего уровня, можно наблюдать в .ru:

alex@garlic-crusher:~$ dig ru. -t NS @a.root-servers.net
[...]
;; AUTHORITY SECTION:
ru.			172800	IN	NS	a.dns.ripn.net.
ru.			172800	IN	NS	d.dns.ripn.net.
ru.			172800	IN	NS	f.dns.ripn.net.
ru.			172800	IN	NS	b.dns.ripn.net.
ru.			172800	IN	NS	e.dns.ripn.net.

;; ADDITIONAL SECTION:
[...]

Однако, если говорить строго, то окажется, что любое имя в глобальной DNS Интернета так или иначе связано с “субординатными” NS-ами: потому что в делегирующих ответах, в качестве основного состава, могут быть только хостнеймы – имена серверов, и в какой-то момент рекурсивного опроса DNS обязательно возникнет проблема “курицы и яйца”. Более того, в DNS наступление такой проблемы можно откладывать до уровня корневой зоны, но вот IP-адреса серверов корневой зоны – распространяются по рекурсивным резолверам тем или иным способом, отличным от DNS (исторически – это всем известный hints-файл), именно для того, чтобы система заработала при первоначальном запуске.



Комментировать »

В 2023 году я писал на dxdt.ru об одном из эффективных, для DNSSEC, способов динамического удостоверения факта отсутствия DNS-записи (или DNS-имени), который, в частности, применяют в Cloudflare. В конце 2025 года этот способ, с некоторыми добавлениями и обновлениями, получил спецификацию RFC 9824.

В частности, RFC 9824 вводит “мнимую” DNS-запись NXNAME (TYPE128) – это запись-сигнал об отсутствии в DNS-зоне запрошенного имени. Причина для введения такого сигнала в том, что упомянутый способ в принципе не позволяет отвечать со штатным для DNS статусом NXDOMAIN. Почему? Потому что весь смысл состоит в “подделывании” состава ответа, но, так сказать, с благими целями: при получении запроса о несуществующем имени, авторитативный сервер отвечает так, как если бы для этого имени нет DNS-записей в зоне: ANSWER: 0 и флаг NOERROR. В терминах DNS такой ответ называется NODATA – то есть, это корректный DNS-ответ без статуса ошибки, но пустой – не содержащий никаких ответных, – в блоке ANSWER, грубо говоря, – записей (естественно, это не означает, что DNS-ответ в целом не содержит записей: пуст только блок ANSWER, но записи в ответе есть, это дополнительные, “авторитативные” записи – SOA, NSEC и т.д.).

Однако, логически, NODATA – это не NXDOMAIN. Статус NXDOMAIN специально предназначен для указания на отсутствие самого имени. Действительно, если нет имени, то для него не может быть и никаких DNS-записей. Понятно, что и NODATA укладывается в схему, но с той лишь точностью, что NODATA – это отсутствие записи конкретного типа, пусть для несуществующего имени и нельзя разместить никакую запись, никакого типа. То есть, NXDOMAIN – мощнее, поскольку указывает на отстутствие самого имени. (Это всё может показаться сложным. Если так, то это не кажется: DNS вообще весьма и весьма непростая система. Зато, заметьте, что здесь очередной раз обыгрываются различные трактовки понятия “пустое множество”.)

Для того, чтобы в новой схеме отличить ситуацию, когда действительно нет записей, от ситуации, когда нет имени, как раз и служит новая запись-сигнал NXNAME. Авторитативный сервер указывает NXNAME в составе полей NSEC-записи, если нет DNS-имени. NSEC – это запись, обозначающая “границу” зоны (в данном случае – фиктивную границу), NSEC нужна для того, чтобы было что подписывать, так как нельзя подписывать пустое значение. Технически, подписать-то можно, но такую подпись легко скопировать и применять к отсутствию любых записей в DNSSEC, то есть в безопасной DNS-зоне: это как раз пример того, что все пустые множества одинаковые, а окрашивать можно только пустые коробки, вот как в случае с NXNAME/NODATA и NXDOMAIN.

Здесь играет роль ещё одна нетривиальная особенность DNS, которую мало кто понимает. А именно: в DNS распространены ситуации, когда возникают заведомо пустые, но поименованные, фрагменты имени. Предположим, что есть имя a.b.c.example.com, для которого указана A-запись. Это имя находится в зоне example.com, но A-запись указана только для a.b.c. Как трактовать имя b.c.example.com (без a.)? Оно, вроде как, есть, потому что в DNS полное имя строится в форме иерархии лейблов, разделяемых точками. Но, не менее “вроде как”, этого имени и “нет”, потому что для него в принципе не указаны никакие записи: из “полных” имён тут будет только example.com и a.b.c.example.com. Для корректной обработки такого случая, в схеме, где NXDOMAIN-ответ невозможен, нужен сигнал, позволяющий отличить несуществование имени от несуществования записи для этого имени. Это и есть NXNAME.

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



Комментарии (2) »