Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
У меня в GitHub тоже есть аккаунт, которым, впрочем, я почти не пользуюсь. Но это не отменяет важности GitHub, конечно. Я под своим там аккаунтом довольно давно опубликовал реализацию шифра “Кузнечик” с оптимизацией на ассемблере Go (гораздо более новая версия, с поддержкой ARM64, есть у меня на сайте, если это вообще кому-то нужно). Кроме того, на GitHub я как-то выложил Runic32 – реализация Base32 на алфавите из англосаксонских рун (“футарк/футорк”, условно говоря). Этот проект является шуточным – потому что как-то зашёл разговор о том, что “TLS-сертификаты отображаются какими-то крючками”: ну, вот, при помощи утилты runic32 можно сертификаты записывать прямо рунами (если есть Unicode).
При этом, как ни странно, но аккаунт в данной “социальной сети” GitHub (известная филологическая английская шутка) я завёл для того, чтобы написать в один из проектов IETF, которая IETF, следуя странной моде, перенесла основную часть своей деятельности по подготовке стандартов в GitHub (спорное решение, мягко говоря). К сожалению, реальность такова, что, фактически, сейчас без GitHub мало что из “рабочих вопросов”, для меня, обходится: начать с того, что с GitHub среди разработчиков принято тянуть очень много из критически важных библиотек, а какие-то библиотеки – просто негде взять удобным способом: скажем, вот полезнейшая CIRCL от Cloudflare.
Я сам сторонник того, чтобы написать всё своё. Да, именно так, и большой плюс – если на ассемблере. Однако, такое нынче – это из области фантастики. В нынешней ситуации – подобный подход не находит понимания в широких массах современных разработчиков на ЯВУ, а приводит только к смешкам и попыткам кидаться штампами вроде “зачем нам изобретать велосипед”, при том, что разработка с нуля – это не изобретение велосипеда, а попытка велосипед сделать самостоятельно, научившись делать велосипеды, а не педалировать чужие. Ну да ладно, тема для другой записки. (Кстати, например, сейчас даже весьма квалифицированный, – реально, – разработчик (не кодер) – ассемблера не знает, да и требовать такого знания – это считается лишним.) В общем, поскольку с таким положением приходится мириться, то и важность “социальной сети” GitHub становится совершенно бесспорной и – растёт дальше. Проблема, конечно, что это централизованный сервис, который, в рамках “битвы за банхаммер”, все хотят отломить. Но, к сожалению, это не уменьшает практической важности. Более того, во многих крупных проектах нынче только через GitHub принимают сообщения об ошибках и прочие технические запросы, что ещё усиливает центральное положение GitHub.
Comments Off on Про GitHub
Даниэль Стенберг (утилита curl) сообщает, что “страшная-ужасная” система поиска уязвимостей в ПО Mythos нашла в коде утилиты curl “пять” “подтверждённых уязвимостей” (“подтверждённых” – по мнению данного ИИ-LLM), которые, после проверки разработчиками, превратились в одну действительно подтверждённую уязвимость с низким уровнем опасности. Четыре остальных представленных описания – это ложные срабатывания и обнаруженная ошибка, – не уязвимость, – в коде. Результат никак не превосходит уже имеющиеся на стороне разработки curl инструменты.
Занятно, что Mythos сейчас, в рамках “маркетингового трюкачества”, продвигают на правах настолько “опасной системы”, что её нельзя выпускать в открытый доступ – поэтому, мол, доступ предоставляется только “ограниченному кругу лиц” (куда, в том числе, входят корпорации, непосредственно участвующие в разгоне хайпа). Стенберг при этом пишет, что ему доступ к новой системе предоставить обещали, он подписал контракт, но доступ так и не предоставили, а, выждав время, предложили, что кто-то ещё, со стороны Mythos, проведёт сканирование за Стенберга и перешлёт уже готовые результаты – и это очень забавно само по себе, особенно, на фоне всех этих заявлений про “невиданный уровень в разработке программных систем”, который, якобы, демонстрируют ИИ-LLM.
Комментировать »
В 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 – не факт, что в этом была проблема.
Оказалось – в этом и была проблема. Что тут ещё сказать? Бывает, конечно: ведь с пониманием сложных процессов – сейчас трудности везде.
Комментировать »
В Англии NHS (система здравоохранения) собирается закрыть доступ к собственным репозиториям с открытым (ранее) исходным кодом информационных систем и с сопутствующими (публичными) данными, мотивируя это тем, что, мол, такой ход снизит риск обнаружения уязвимостей при помощи LLM (конечно же, ссылаются на “страшный и опасный” миф под названием Mythos). Очевидно, что решение – так себе, мягко говоря. Естественно, в ответ на такой “ловкий ход”, в сообществе уже подготовли открытое письмо, требующее не закрывать репозитории с исходными кодами (и данными), тем более, что они разработаны в интересах местных налогоплательщиков (казалось бы).
Понятно, что, во-первых, хайп – он и есть хайп, и никакого прорывного результата, без участия специалистов-людей, LLM-инструменты не дают, а технологии “фаззинга” и подобные им – были давно: но, конечно, с ростом вычислительной базы и на волне хайпа – эффективность увеличилась. Во-вторых, сокрытие исходных кодов, если преподносить его как инструмент “снижения рисков”, имеет сомнительную ценность. Особенно – в данном случае: исходные коды, которые пытаются скрыть, уже так или иначе есть в этой самой LLM – их скачали раньше, скачали из других репозиториев, из внутренних инструментов “ИИ-разработки” и т.д., и т.п. Это кроме того, что формат распространения кода программы – не особенно влияет на сокрытие уязвимостей, а исполняемый машинный код – может являться таким же “исходным”, если приложить к нему некоторые детерминированные и строгие инструменты, типа современного дизассемблера.
Кстати, по этой теме ещё модно говорить, что для LLM уровня Mythos (что бы это ни значило), типа, нет разницы, на каком языке подан код программы (а машинные коды – это тоже язык, не забывайте). Это, конечно, не так: подобные системы сами никаких уязвимостей не находят, но могут генерировать вывод, который совпадает с описанием уязвимости (или не совпадает). Это хорошо подтверждается тем, что уровень качества “исправлений”, сгенерированных той же LLM, ниже уровня “обнаружения” (должно быть наоборот, если уязвимость находит реальный интеллект). То же, кстати, видно и в “решении” математических задач LLM: генератор текста – он и есть генератор текста.
Поэтому, если основной базой обучения был код на Python, то именно эта база и не позволит непосредственно, без потерь, перейти на обработку машинного кода или выдачи дизассемблера. Так что некоторое минимальное зерно разумности в желании закрыть код от LLM найти можно, при желании. Другое дело, что, с одной стороны, кто сказал, что LLM не обучили и на ассемблерных распечаnках, и на машинном коде? Никто не сказал, да. И, с другой стороны, это минимальное “зерно разумности” – никак не может перевесить массы прочих вредных эффектов, типа того, что начнут надеяться на мнимую “безопасность”, связывая её с “секретностью” исходных кодов или недоступностью кодов исполняемых, которые вертятся во внутренних системах только (см. впрочем, про принцип Керкгоффса).
Хотя – хайп. Хайп не все хотят пропустить.
Комментировать »
Хроники разваливающихся интернетов и проблем с диагностикой разваливания. Понадобилось тут проверить один технологический артефакт в связке 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) »
Сейчас много околотехнических обсуждений по теме методов определения того, пришёл ли веб-клиент на некий крупный веб-сервис “c VPN или без VPN”. Оставим за скобками набравшую сейчас популярность трактовку того, что такое VPN – термин обобщили до невозможности. Но в технической стороне процесса “определения” сетевых настроек есть пара занятных моментов, которые как-то пропускают.
Момент первый: измерение параметров времени для TCP-соединения. Например, к некоторому веб-сервису подключается клиент, скажем, браузер. При помощи выполнения некоторых скриптов не очень трудно померить время “сетевой задержки” между средой веб-страниц этого браузера и серверной средой. То есть, это будет время доставки запроса, измеренное от контекста DOM в браузере до веб-сервера. Предположим, это 50 ms. Но это всё по HTTP, а HTTP-соединение использует TCP.
TCP-соединение устанавливается не с браузером, а с логически ближайшим к серверному сетевому стеку узлом. Это может быть клиентский компьютер, то есть, ОС на этом компьютере. Но может быть и выходной узел, выполняющий трансляцию адресов, например. Обычно – именно так и есть: клиентский компьютер редко стоит прямо за маршрутизируемым IP-адресом. Тогда, если измерять и задержку в браузере, и задержку на серверном TCP, то получится, скажем, что, в рамках одной логической HTTP-сессии, TCP-задержка – 10 ms, а браузерная задержка, до DOM в HTTP-клиенте, – 50 ms. Большая разница – 40 ms. Это означает, что от клиента транслированные запросы ещё где-то там внутри долго ходят, пока доберутся до выходного узла, который к нам по TCP подключился.
Если же выходной TCP-узел примерно совпадает с логическим узлом, где работает клиентский браузер, то разница между двумя задержками будет минимальной, например: 10 ms TCP и 11 ms – браузерная задержка, читай – Javascript в DOM-контексте. Здесь под “примерно совпадает” имеется в виду, что между клиентским компьютером и выходным узлом нет большого сетевого плеча: компьютер и выходной узел стоят технически рядом (простейший случай: локальный пограничный “роутер” с NAT и подключенный к этому “роутеру” по локальному порту компьютер в локальной IP-сети над Ethernet-ом).
Естественно, измерять задержки TCP-стека для веб-сервиса (не веб-сервера) – несколько сложнее, чем померить что-то внутри веб-логики. Для таких измерений нужно зацепить “щупы” прямо в сетевой стек, причём, на входном узле, а не на бэкенде, куда проксируются HTTP-запросы. Очевидно, что на “веб-уровне”, даже для сервера, TCP в таких деталях не виден. Но измерять всё равно можно – это не суперсложная задача, и решение вполне под силу специализированной компании, сохранившей инженерный подход среди своих разработчиков. Мы же тут, как раз, речь ведём о крупных профильных компаниях, где, вполне возможно, понимающие инженеры есть – верно?
Понятно, что сравнение задержек по времени на уровне браузерного движка с задержками на уровне TCP-стека не является каким-то волшебным зеркалом, которое всё показывает: большие задержки бывают при использовании радиоканалов, из-за перегруженного оборудования, из-за потерь пакетов на стороне клиента и т.д. Тем не менее – фактор это достаточно важный, чтобы о нём не забывать.
Момент второй: геометрия сетевых подключений. Если наш гипотетический веб-сервис имеет только одно подключение к общему Интернету, – которое называют “аплинк”, – то этот веб-сервис не может различить пути поступления сетевых пакетов извне в локальную сеть, в рамках какой-то веб-сессии. Ну, как не может – путь для таких пакетов тут один, потому что один “аплинк”. Соответственно, различать нечего. Однако в совсем крупных компаниях, связанных с веб-сервисами, есть несколько подключений, несколько “аплинков”, своя автономная система (или несколько) и свой центр управления сетью, населённый инженерами NOC.
Для опытного инженера NOC, IP-адрес – это сетевой номер, идентификатор, а не “интернет-узел”. С точки зрения физической организаци сети, IP-адрес может указывать куда угодно, а доставка IP-пакетов – просто происходит на другом уровне, чем работает сама вверенная сеть. Поэтому IP-пакеты можно различать по физическим портам коммутаторов или по логическим маршрутам, которые ниже IP и связаны с внутренним устройством сетей оператора (см. MPLS и пр.). Так что для IP-пакетов, с разными адресами источника, и разными правилами, могут использоваться разные порты подключения – эти пакеты, проще говоря, приходят “с разных сторон”, что создаёт внутренний различительный признак. Как ни странно, но этот признак зависит от внешних факторов (где какие фильтры, кто к кому подключен и пр.).
Сюда же попадает и повсеместная путаница, связанная с распределением блоков IP-адресов (префиксов). У всякого IP-префикса есть администратор – автономная система (AS). Это верно. Но ещё есть маршрутизация и BGP. И вот в рамках BGP, технически, быть источником (origin) для данного IP-префикса может любая (подчёркиваю: технически – любая, даже с тестовым номером) автономная система. То есть, административно, префикс принадлежит одной AS, но анонсирует его в Интернет – совсем другая. Или даже несколько других AS – в зависимости от того, какой оператор из какой точки сети смотрит на BGP. Да, для штатного анонсирования префикса должно быть разрешение от его администратора, сейчас это даже подтверждается в RPKI. Да, конкретная ситуация с приёмом IP-пакетов зависит от фильтров, настроенных оператором. Но это только подчёркивает то, что одно дело – административная принадлежность, другое – BGP и маршрутизация в реальности.
BGP – это хорошо, но при чём здесь сетевые задержки? Вот при чём: даже во внешнем BGP, например, не видны многие и многие внутренние каналы между операторами, более того, административная принадлежность префикса не позволяет судить о реальных характеристиках сетевой связности вообще никак; однако разные пути доставки тут всё равно образуются, и разное время доставки, наблюдаемое внутри, вполне себе может служить признаком для классификации.
Комментарии (11) »
На днях я писал о том, что сейчас нетрудно сделать веб-сайт без доменного имени, а прямо под IP-адресом (v4), но с доверенным HTTPS для коробочного браузера. В качестве примера – сделал точно такой веб-сайт, с сертификатом от Let’s Encrypt: https://185.39.19.199/ – можно зайти браузером и убедиться, что всё работает. Надо заметить, что TLS-сертификаты для IP-адресов можно было получать в доверенных, хорошо известных УЦ и раньше, это, конечно, не в Let’s Encrypt придумали – но вот только раньше выпуск такого сертификата был сопряжён с существенными дополнительными административными трудностями, а Let’s Encrypt позволяет этих трудностей избежать совсем.
Посмотрим подробнее на сам TLS-сертификат, который сейчас установлен на сервере под указанным выше IP-адресом. Исходный файл сертификата можно получить с сервера – он и так передаётся при каждом TLS-соединении, а здесь – будет текстовая распечатка, полученная при помощи OpenSSL. Так как полная распечатка довольно длинная, а разделю её на части, которые подробно прокомментирую, попутно рассказав, на что это всё влияет.
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
06:7e:8d:e7:b0:8a:13:8c:23:da:d4:f1:43:e6:de:24:02:f6
Signature Algorithm: ecdsa-with-SHA384
Issuer: C = US, O = Let's Encrypt, CN = YE1
Validity
Not Before: Apr 26 13:18:14 2026 GMT
Not After : May 3 05:18:13 2026 GMT
Subject:
Здесь указаны самые, наверное, очевидные поля: версия формата (3 – сейчас это типовой вариант); серийный номер; алгоритм подписи – ECDSA, см. ниже; название подписавшего сертификат УЦ (Issuer); период валидности.
Обратите внимание – в сертификате отсутствует поле Subject. Это весьма важный момент, довольно свежий. Сейчас в TLS-сертификатах (для веба) в качестве носителя имён и адресов TLS-узла выступает другое поле – SAN (Subject Alternative Name). Поле Subject может присутствовать в сертификате, но, например, браузеры имена из этого поля игнорируют, если нет соотвествующего имени в SAN. В случае же этого сертификата от Let’s Encrypt, как мы видим, нет самого содержимого поля Subject. Это, в частности, означает, что если в каких-то скриптах (скажем, для мониторинга) это поле используется для определения принадлежности сертификата, то с современными TLS-сертификатами (для веба) скрипт правильно работать не будет. Такие скрипты нужно обновлять – см. ниже.
Вот типичный пример вызова OpenSSL в shell-скрипте, который пытается проверить имя в сертификате по Subject:
openssl x509 -in 185-39-19-199.pem -subject -noout -nameopt multiline \
| awk -F' = ' '/commonName/ {print $2}'
Для старого формата сертификатов (например, как сейчас установлен на dxdt.blog) – этот вызов выведет имя из поля “commonName” в Subject, то есть, для dxdt.blog – напечатает dxdt.blog. Однако в случае с новыми сертификатами – фрагмент не напечатает ничего, но, при этом, обработанный сертификат будет валидным и вполне себе корректным. То есть, полагаться на Subject больше нельзя – нужно заменять вызовы утилит на обработку поля SAN. Это несколько сложнее, но вполне реализуемо.
Для извлечения имён из SAN при помощи OpenSSL (утилита x509) нужно указать опцию -ext subjectAltName. Выдача openssl x509 в этом случае состоит из списка, где тип элемента обозначен префиксом. DNS-имена OpenSSL выводит с префиксом “DNS”, а IP-адреса – “IP address” (это будет полезно для нашего сертификата). Пример:
openssl x509 -in 185-39-19-199.pem -noout -ext subjectAltName
Результат:
X509v3 Subject Alternative Name: critical
DNS:185.39.19.199.zone, IP Address:185.39.19.199
Скрипт, понятно, усложняется – нужно парсить префиксы полей. Пример скриптового вызова с awk, для извлечения DNS-имени:
openssl x509 -in 185-39-19-199.pem -noout -ext subjectAltName \
| awk 'NR>1{split($0,A,",");for(k in A){split(A[k],B,":"); \
if(B[1]~/DNS/){print B[2]}}}'
Результат:
185.39.19.199.zone
Обратите внимание: 185.39.19.199.zone – это хостнейм, доменное имя, пусть оно и похоже на IP-адрес. Да, в данном сертификате присутствует и DNS-имя, и IP-адрес – это делает сертификат хорошим примером. В принципе, сервер доступен и под доменным адресом 185.39.19.199.zone, но основным мы тут считаем IP-адрес. Для выпуска сертификата на IP-адрес не требуется указание доменного имени. Но если имя нужно включить в сертификат, то это нетрдуно сделать при помощи того же certbot – просто указываем при вызове и доменное имя, и IP-адрес:
certbot certonly --preferred-profile shortlived \ -d 185.39.19.199.zone \ --ip-address 185.39.19.199 \ --webroot --webroot-path /var/www/html/
Вернёмся к распечатке исходного сертификата. Предыдущий блок закончился на пустом Subject. Смотрим дальше:
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:ea:98:84:aa:0e:d5:2b:0f:5a:00:6b:bc:17:df:
33:91:86:e5:f8:b6:cb:e8:f0:7b:48:f0:5f:bf:8c:
04:57:9e:7f:ee:66:a8:09:7a:31:f3:11:d5:2f:90:
67:01:af:04:cc:45:52:56:5d:18:73:bf:1c:d5:6d:
f9:f7:44:6e:5d
ASN1 OID: prime256v1
NIST CURVE: P-256
Это открытый ключ. В сертификате указан открытый ключ для ECDSA на кривой P-256. Это, опять же, типовой сейчас вариант, ничего необычного.
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
BB:20:CA:47:0B:FE:D7:E5:9C:F9:8F:09:2A:A3:8C:37:45:B1:BC:D8
Authority Information Access:
CA Issuers - URI:http://ye1.i.lencr.org/
Далее идут так называемые “расширения” (extensions). Key Usage и Extended Key Usage – обозначают допустимое использование открытого ключа из сертификата. Сейчас, в случае TLS-сертификатов для веба, перечень флагов, указываемых в этих полях Удостоверяющим Центром (УЦ), сильно сократили: здесь есть только Digital Signature (цифровая подпись) в основном поле Key Usage и TLS Web Server Authentication (аутентификация TLS-сервера для веба) – в дополнительном Extended Key Usage. И всё – это, опять же, нововведение: тут нт ни клиентской аутентификации, ни “шифрования ключа” или “ключевого обмена”, ни чего-то ещё подобного.
CA:FALSE в Basic Constraints – ключ из сертификата не может быть использован в качестве доверенного для проверки подписи на других сертификатах (это если строго; простыми словами говорят, что “это не сертификат ключа УЦ”).
Authority Key Identifier – идентификатор ключа для проверки подписи; это, вообще говоря, историческое поле, которое предназначено для “быстрого поиска” ключа проверки подписи на сертификате, но, понятно, без самого ключа не имеет смысла.
Authority Information Access – указание на точки раздачи файлов с информацией об удостоверяющем центре. В данном случае, указана только точка раздачи по HTTP сертификата ключа УЦ – CA Issuers.
Далее идёт поле SAN, с именами и адресами, которое мы упоминали выше:
X509v3 Subject Alternative Name: critical
DNS:185.39.19.199.zone, IP Address:185.39.19.199
Указано одно доменное имя (DNS) и один IP-адрес (IP Address). Ещё раз напомню, что могли быть и только IP-адреса, причём, разных версий – v4, v6. Современные барузеры в процессе валидации сопоставляют имена или адреса из поля SAN, не из Subject. Например, при подключении по IP-адресу 185.39.19.199, браузер проверит, что в TLS-сертификате указан именно этот адрес в поле SAN.
Интересен вопрос контекста: что использует браузер – IP-адрес или доменное имя? В сертификате могут быть указаны оба этих артефакта, но браузер при валидации использует тот, который пользователь ввёл при вызове. То есть, если обращение по имени хоста, то сранивается имя хоста, если по IP-адресу напрямую, то сравнивается IP-адрес. Понятно, что почти всякое HTTP-обращение, в стетевом смысле, производится по IP-адресу. Я как-то (https://dxdt.blog/2025/04/15/15391/) писал о том, что, в теории, для случая хостнейма, тоже можно использовать и IP-адреса из сертификата, в качестве дополнительного фактора – совпал и домен, и IP-адрес. Но в современной практике веба это, скорее, излишняя перестарховка, сопряжённая с техническими сложностями, к тому же.
X509v3 Certificate Policies:
Policy: 2.23.140.1.2.1
X509v3 CRL Distribution Points:
Full Name:
URI:http://ye1.c.lencr.org/119.crl
Политики (Policies) – тут просто указан идентификатор политики УЦ, в рамках которой проводилась проверка права управления ресурсом (адресом, именем) и выпускался сертификат. Политики – это больше административный момент. Но, например, именно идентификатором политики определяются так называемые EV-сертификаты (Extended Validation), которые сейчас почти что утратили актуальность.
X509v3 CRL Distribution Points – точка раздачи CRL – списка отозванных сертификатов. В данном сертификате есть механизм проверки отзыва – это CRL. В принципе, для короткоживущих сертификатов от механизма отзыва собираются вообще отказаться, но тут адрес CRL все же указан (отчасти, потому что это сертификат для IP-адреса).
Хвост сертификата, с сокращениями:
CT Precertificate SCTs:
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : E3:23:8D:F2:8D:A2:88:E0:AA:E0:AC:F0:FA:90:C9:85:
F0:B6:BF:F5:D2:A5:27:B0:01:FC:1C:44:58:C4:B6:E8
Timestamp : Apr 26 14:16:45.523 2026 GMT
Extensions: 00:00:05:00:36:66:ED:17
Signature : ecdsa-with-SHA256
[...]
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : D1:6E:A9:A5:68:07:7E:66:35:A0:3F:37:A5:DD:BC:03:
A5:3C:41:12:14:D4:88:18:F5:E9:31:B3:23:CB:95:04
Timestamp : Apr 26 14:16:45.489 2026 GMT
Extensions: none
Signature : ecdsa-with-SHA256
[...]
Signature Algorithm: ecdsa-with-SHA384
Signature Value:
[...]
CT Precertificate SCTs – это подписанные метки времени, полученные для этого сертификата от операторов логов Certificate Transparency.
Далее – повторное указание на тип подписи в сертификате (ecdsa-with-SHA384). Это тип криптосистемы цифровой подписи, использованной УЦ. Тот же идентификатор уже встречался в начале сертификата – так сложилось исторически: идентификатор указывается в двух местах, хотя точно хватило бы и одного, в конце, где приводится сама подпись – Signature Value.
Комментировать »
Раньше самолёты (и не только самолёты, конечно) ориентировались по звёздам. Для автоматизации процесса использовались аналоговые вычислители, которые и сейчас-то иногда превосходят цифровые на некоторых задачах, а уж в 60-х годах прошлого века – только такие и могли бы вычислять координаты в режиме онлайн. Подробное и с картинками описание такой аналоговой системы астронавигации, использовавшейся на борту самолёта B-52, – по ссылке (англ. много букв).

На этой иллюстрации из статьи – аналоговый вычислитель, выполнявший преобразование углов.
(via)
Комментировать »
В продолжение предыдущей записки: можно ли вообще обойтись без доменного имени для веб-сайта? Можно, но это доставит некоторых дополнительных проблем, да и “игра” получается с другими правилами. В принципе, сейчас уже можно автоматом заказывать и выпускать TLS-сертификаты для IP-адресов от хорошо известного (доверенного в “коробочных” браузерах) УЦ – это сертификаты от Let’s Encrypt, на шесть дней валидности.
Наличие TLS-сертификата и выделенного IP-адреса позволяет поднять веб-сервер с доверенным TLS прямо по IP-адресу, без использования доменного имени. Вот, посмотрите, я сделал для примера – должно работать в любом распространённом веб-браузере:
Этот 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-файл), именно для того, чтобы система заработала при первоначальном запуске.
Комментировать »
Новый