Про технологию ESNI (и SNI) я не так давно написал несколько записок. Сейчас ESNI находится в процессе внедрения, интересно взглянуть на эффект, который данная технология будет иметь для систем инспекции трафика и блокирования доступа. Современные системы используют SNI (а также, в продвинутых вариантах, TLS-сертификаты) для обнаружения имён узлов, с которыми пытается установить соединение пользователь. ESNI скрывает эти имена из SNI (TLS-сертификаты скрыты в новой версии TLS 1.3), причём, текущая версия ESNI использует для этого ключи, опубликованные в DNS.

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

Провайдер хостинга может использовать ключи, опубликованные под одним DNS-именем, для обеспечения доступа к “скрытым серверам” под совсем другими именами, это означает, что открытый запрос в DNS не будет раскрывать имя “целевого узла”. Например, Cloudflare сейчас использует одни и те же ключи для самых разных веб-узлов. Более того, “скрытый узел” может находиться за некоторым “фронтэндом”, имеющим другое, универсальное, имя – фактически, это Domain Fronting.

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

В открытой DNS, системы анализа трафика, которые видят весь трафик клиента, могут сопоставить запрос в DNS для извлечения ключа ESNI и последующее TLS-соединение. DNS-ответ с ключами даже можно заблокировать, сделав использование ESNI невозможным (но только при условии, что ключи не были получены другим способом). Однако автоматическое корректное сопоставление имени из DNS-запроса и сессии TLS – представляют серьёзную дополнительную задачу, которая тем сложнее, чем больше объём трафика, анализируемого системой фильтрации. (Конечно, уже само наличие ESNI может являться признаком подозрительного соединения.)

То есть, ESNI, в случае массового внедрения, довольно заметно повлияет на ландшафт систем инспекции трафика. А кроме того, данная технология может подстегнуть рост распространённости DNSSEC и DNS-over-TLS. Впрочем, пока что ESNI не поддерживается распространёнными веб-серверами, да и соответствующий RFC не вышел из статуса черновика.

(Как работает ESNI – можно посмотреть на моём тестовом сервере TLS 1.3, там реализована поддержка.)



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

Внёс некоторые дополнения на сервер tls13.1d.pw. Во-первых, появилась поддержка “пересогласования” (renegotiation) параметров соединения. В TLS 1.3 есть отдельный механизм, который позволяет серверу запросить у клиента другие параметры протокола Диффи-Хеллмана, конечно, при условии, что клиент их поддерживает. Для этого сервер, в самом начале процесса установления соединения, отправляет сообщение HelloRetryRequest. (Технические подробности есть в описании TLS.) Я давно планировал дописать на сервер поддержку классического варианта протокола Диффи-Хеллмана (DH), который есть в Firefox. Так как по умолчанию браузеры используют эллиптический вариант, включение классического – как раз требует пересогласования параметров. То есть, чтобы заработал классический DH, нужно реализовать пересогласование.

Чуть ранее – я добавил поддержку ESNI. Так вот, в процессе отладки механизма пересогласования выяснилось, что в библиотеке NSS, которая используется Firefox, содержится ошибка в реализации механизма HelloRetryRequest, которая не позволяет использовать вместе с ним ESNI (про ошибку разработчикам я сообщил; вроде, планируют исправить). Так что теперь действие полезного механизма ESNI в Firefox можно наблюдать только в тех случаях, когда сервер не использует пересогласования: для этого нужно обновить страницу tls13.1d.pw несколько раз – группы DH на сервере выбираются псевдослучайным образом, так что, если выбор совпал с перечнем ключей браузера, присланных по умолчанию, то пересогласования не будет, а сработает ESNI.

Соответственно, во-вторых, – это и есть реализация классического DH. Его ещё называют “мультипликативным” вариантом, DH “в конечном поле” и так далее, а если говорить не слишком научно, то это алгоритм в арифметике остатков. Chrome/Chromium поддерживают только эллиптический вариант, соответственно, там увидеть классический никак не удастся. А вот в Firefox – можно. На сервере я реализовал только одну группу, зато самую “большую”: FFDHE3072. В предыдущих версиях TLS – сервер мог выбрать произвольную группу для классического DH, в версии TLS 1.3 список зафиксировали. Я некоторое время назад писал про то, как выбираются параметры для этих групп. По сравнению с эллиптическими вариантами, запись ключа FFDHE3072 – весьма длинная, 384 байта. Вот так результат выглядит на скриншоте:

FFDHE screen

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

(Вообще, использование пересогласования может поломать какие-то другие библиотеки, поддерживающие TLS 1.3, но пока что я таких не обнаружил.)



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

При установлении TLS-соединения имя узла передаётся в открытом виде, внутри поля (или расширения) SNI – Server Name Indication. На стороне сервера имя узла требуется для того, чтобы выбрать правильный набор сертификатов и серверных ключей, в случае, если на одном IP-адресе отвечает несколько TLS-узлов.

С появлением новой версии TLS 1.3, в которой зашифрована существенная часть сообщений, передаваемых при установлении соединения, вновь обострились споры относительно того, что хорошо бы зашифровать и SNI – ведь через это поле происходит утечка информации о том, с каким именно узлом устанавливается соединение.

Предлагалось несколько вариантов защищённого SNI. Вероятно, будет выбран вариант, использующий ключи в DNS: для него уже есть поддержка в браузере Firefox (версии 64 и Nightly) и на веб-узлах Cloudflare, несмотря на то, что сама спецификация пока в состоянии черновика.

Защищённый вариант называется ESNI (Encrypted SNI) и доступен только для TLS 1.3 (и, в будущем, выше). Рассмотрим, как он работает.

Основная идея следующая. В DNS размещается специальная запись (сейчас это TXT-запись, но, возможно, скоро появится выделенный для ESNI тип), в которой публикуется открытый ключ сервера (для протокола Диффи-Хеллмана (DH), см. ниже) и другие криптографические параметры. А именно: шифронабор, используемый для защиты SNI; группа для DH; контрольная сумма; время действия ключа. Для адресации DNS-записи служит специальное имя, имеющее вид _esni.example.com (здесь важен символ подчёркивания в начале).

Например, для узла tls13.1d.pw имя записи будет таким: _esni.tls13.1d.pw. А значением является структура с криптографическими параметрами, закодированная в Base64. Вот действующее значение для _esni.tls13.1d.pw:

“/wGu7tnmACQAHQAgLukkHH6AiIAPYODmYK/6Nz3H7N58nYZyb/WG62h4TTgAAhMBAIAAAAAAXCPQTgAAAABcQ3ROAAA=”

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

Обычно, клиентом является браузер. Он действует по следующему алгоритму: извлекает из DNS запись, содержащую данные ESNI; используя эти данные, генерирует свою часть обмена по протоколу Диффи-Хеллмана, вычисляет общий секрет, на его основе генерирует симметричный ключ и зашифровывает SNI симметричным шифром. Получившийся шифротекст – передаётся в составе нового расширения сообщения TLS ClientHello ESNI. Вместе с зашифрованным SNI передаётся клиентский ключ DH, который необходим серверу для получения симметричного ключа. Таким образом, третья сторона, прослушивающая канал, не может прочитать значение SNI.

Конкретный пример используемых криптосистем: для (эллиптического) DH используется кривая Curve25519; в качестве шифра – AES в режиме GCM. Все эти параметры, как указано выше, записаны в DNS.

Сервер обнаруживает наличие ESNI по присутствию соответствующего расширения в сообщении ClientHello, отправленном браузером (с этого сообщения начинается процесс установления TLS-соединения). Так как сервер знает секретный ключ DH, он может вычислить общий секрет и симметричный ключ, а после этого – расшифровать имя сервера, полученное в ESNI. Также сервер, успешно обработавший ESNI, отвечает с подтверждением: возвращает клиенту уникальное значение, полученное в зашифрованной части ESNI; при этом значение передаётся в защищённом виде, то есть, получаем ещё один, дополнительный, канал подтверждения подлинности сервера (для клиента).

Очевидно, что в данной схеме имя узла потенциально передаётся в открытом виде при запросе в DNS, поэтому необходимо использовать инструменты защиты DNS-трафика. В частности, в Firefox используют DNS-over-HTTPS (DoH), но данная технология защищает трафик только на “последней миле”, то есть, на пути от рекурсивного резолвера к клиенту. Кроме того, DoH никак не решает проблему подмены DNS-ответов. То есть, в полной мере ESNI заработает только при условии поддержки DNSSEC и внедрения TLS для защиты DNS-транзакций на всех этапах. Тем не менее, с чего-то нужно начать, поэтому внедрение ESNI в распространённый браузер – весьма хороший стимул, который может подтолкнуть и другие технологии.

В качестве теста, я реализовал ESNI, в только что описанной версии, на сервере tls13.1d.pw. Попробовать можно при помощи браузеров Firefox Nightly или Firefox 64. Поддержка ESNI включается в “about:config” (в 64-й версии уже должна быть включена “из коробки”); обязательно нужно также активировать DoH (DNS-over-HTTPS), указав URI сервера, который будет обслуживать DNS-запросы – в Firefox ESNI без DoH не работает.

Если вы зайдёте на tls13.1d.pw с поддержкой ESNI, то информацию об этом сервер выведет в начале страницы – как на скриншоте (update, 10/04/19: ошибку в Firefox исправили, начиная с версии 66.0.2 в основной линейке, так что поддержка ESNI теперь не зависит от пересогласования параметров;update, 05/02/19: из-за ошибки в библиотеке NSS, на которой базируется реализация TLS в Firefox, увидеть при помощи этого браузера ESNI на tls13.1d.pw можно только в том случае, если сервер не использовал пересогласование параметров – то есть, нужно несколько раз обновить страницу; подробнее – в отдельной записке).

Screenshot



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

Новая версия TLS 1.3 получила RFC, а именно – RFC 8446 (обратите внимание: TLS 1.0 – RFC 2246, TLS 1.1 – RFC 4346, 1.2 – RFC 5246). Я уже довольно подробно описывал этот новый протокол, который радикально отличается от всех предыдущих версий TLS/SSL. Вот ссылка на подробную статью про TLS 1.3. В блоге Cloudflare – опубликован хороший популярный обзор TLS 1.3 (но он на английском).



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

TLS 1.3 – это новая версия протокола, вот-вот должен появиться RFC (пока что актуален черновик – draft-28). По адресу https://tls13.1d.pw/ я разместил тестовый сервер, который позволяет попробовать TLS 1.3 на практике, при помощи браузера. Поддержка протокола пока есть далеко не везде. Для сервера я полностью написал стек TLS версии 1.3 на Go, то есть, реализовал всё, что “выше TCP”, так как в стандартной библиотеке поддержки 1.3 нет. (Ну, строго говоря, криптопримитивы использованы библиотечные, а именно – шифры и алгоритмы на эллиптических кривых для протокола Диффи-Хеллмана (DH) и электронной подписи ECDSA.) Это именно тестовый сервер, поэтому он поддерживает не все возможности TLS 1.3, но базовые – поддерживает. В частности, я реализовал две draft-версии: 28 и 23. Draft-28 – должен стать RFC, а 23-й поддерживается распространёнными клиентами. (Update: c 09.2018 поддерживается и RFC-версия – 0x0304.) Сервер умеет шифры AES (с GCM) и ChaCha20 (c Poly1305). DH для сеансовых ключей и подпись – только эллиптические (возможно, RSA и “мультипликативный” DH я добавлю позже; update: c 26/01/2019 – есть поддержка “мультипликативного” DH). Кроме TLS – есть кусочек, поддерживающий HTTP-запрос GET, он позволяет использовать обычный браузер и выводит в текстовом виде подробную информацию о TLS-соединении. Понятно, что для получения этой информации TLS-соединение нужно установить. Версий TLS ниже 1.3 – тестовый сервер не поддерживает (совсем не поддерживает: всё же, это специальный сервер, я просто не стал их реализовывать, так как от 1.3 они отличаются весьма существенно).

Два самых распространённых браузера – Chrome и Firefox – уже умеют TLS 1.3 в своих самых свежих версиях. Я проверил Chrome 68 (версия draft-23 TLS) под Debian и Android 8, FireFox Quantum 62.0b14 (это бета) под Debian, а также Firefox 61 под Android 8: все эти браузеры соединяются с тестовым сервером, а FF 62 даже поддерживает draft-28 (самый свежий вариант). То есть, вы можете попробовать подключиться к тестовому серверу, если у вас актуальная версия браузера. Кроме того, 1.3 умеет утилита s_client из пакета OpenSSL версии 1.1.1-pre8, но это тоже бета-версия, которую нужно самостоятельно собирать. Все прочие типичные инструменты (wget, curl и т.д.) – скорее всего TLS 1.3 пока что не умеют (но планируют быстро добавить поддержку).

Если браузер сумел договориться с сервером, то вы увидите простую текстовую страницу (англ.) с параметрами TLS, в частности, там отображаются сеансовые ключи. Сервер использует полноценный TLS-сертификат от Comodo (с ECDSA), поэтому предупреждений о безопасности барузер показывать не должен. Если соединиться не удалось, то, скорее всего, браузер выведет ту или иную ошибку SSL/TLS. Возможны варианты, когда соединение просто сбрасывается на уровне TCP (например потому, что мой сервер не присылает фиктивное сообщение ChangeCipherSpec, и такие соединения разрывает DPI, но это технические детали, которые, впрочем, очень интересно отследить). Попробуйте: https://tls13.1d.pw.

(Сервер специально использует статический ключ DH и “не слишком случайное” значение поля Random.)

Update: кстати, если вы хорошо знакомы с TLS и интересуетесь всякими занимательными “гиковскими” штуками, то рекомендую внимательно взглянуть на открытый ключ ECDSA сервера tls13.1d.pw – этот ключ входит в состав TLS-сертификата (смотреть нужно в шестнадцатеричной записи).

Update 13/08/2018: добавил передачу сообщения ChangeCipherSpec сервером; в случае TLS 1.3 – это фиктивное сообщение, которое нужно только для того, чтобы “замаскировать” TLS-соединение под предыдущие версии, обеспечивая прохождение через промежуточные узлы с DPI и прочей фильтрацией трафика.

Update: c 28/12/2018 добавил поддержку ESNI.

English note: there is a test implementation of TLS 1.3 server (RFC 8846, draft-28,-17) with HTTPS support.



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

SNI – это Server Name Indication, поле, которое передаёт клиент на начальном этапе установления TLS-соединения. В данном поле указано имя сервера (на уровне приложений), с которым клиент планирует установить соединение. Например, при обращении к dxdt.ru по HTTPS, ваш браузер указывает в SNI строку dxdt.ru. Указание SNI нужно для того, чтобы на стороне сервера по имени различать “виртуальные хосты” (узлы), которые разделяют общий IP-адрес. Например, если у сервера есть несколько наборов TLS-сертификатов и серверных ключей для разных имён, то на основании SNI он может определить, какие сертификаты передавать в данном TLS-соединении. Сейчас, во всех версиях TLS, включая новейшую 1.3, поле SNI передаётся в открытом виде. Это означает, что прослушивающая канал связи третья сторона может определить имя узла, с которым устанавливается соединение, несмотря на то что TLS использует шифрование для защиты от прослушивания.

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

Тем не менее, решения предлагаются. Скорее всего, значение SNI всё же спрячут. Свежий черновик (draft) RFC предлагает использовать для шифрования SNI записи DNS. Точнее, в DNS предполагается публикация открытого серверного ключа, с помощью которого клиент может зашифровать значение SNI. Такая схема позволяет клиенту сгенерировать нужный ключ заранее, сделав запрос в DNS (сопутствующие параметры публикуются там же, в одной TXT-записи), а сервер сможет расшифровать SNI непосредственно на первой итерации установления соединения (сервер знает секретный ключ). Решение весьма логичное, не требует обмена дополнительными сообщениями, кроме запроса-ответа DNS, который может быть выполнен асинхронно. Предполагается, что публикуемый в DNS ключ относится не к одному конкретному ресурсу, а к сервису, обеспечивающему размещение множества ресурсов.

Фактически, представленная в черновике схема стандартизует Domain Fronting: массовые провайдеры хостинга смогут опубликовать свои ключи для шифрования SNI в DNS, клиенты станут использовать эти ключи для доступа ко всем ресурсам, размещённым у провайдера. Удостоверение подлинности ключей – может быть выполнено в рамках DNSSEC. Ну и следует отметить, что ключи для шифрования SNI могут быть переданы не только через DNS.



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

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

А вот DNS авторам удаётся подменить полностью, несмотря на то, что LTE считается существенно более защищённой технологией, по сравнению с предыдущими поколениями 2G/3G. Суть атаки состоит в подмене части данных внутри UDP-пакетов, представляющих запрос и ответ DNS. Для этого требуется провести активную атаку типа “человек посередине” (MiTM), то есть, абонентское устройство должно подключиться к подменному узлу, который транслирует пакеты между ним и “подлинной” LTE-сетью. Казалось бы, LTE – современный протокол. Тем не менее, для основной части пользовательских данных в нём не используется аутентификация сообщений, хотя данные и передаются в зашифрованном виде. Данные зашифровываются AES в режиме счётчика (CTR), но, так как целостность не проверяется, пакеты могут быть прозрачно изменены.

Как это происходит. DNS использует в качестве штатного транспорта UDP. Структура пакета заранее известна (она определяется спецификациями IP и UDP). Более того, обычно известен и IP-адрес DNS-сервера, которому предназначен исходный запрос: это сервер, предоставляемый оператором связи, а определить его адрес можно из настроек IP-транспорта. Задача атакующего состоит в том, чтобы перехватить пакеты, содержащие DNS-запросы, и подменить в них IP-адрес DNS-сервера провайдера на IP-адрес подменного DNS-сервера, находящегося под контролем атакующего. Если такая подмена будет успешно осуществлена на пути от абонентского устройства до “легитимной сети” LTE, то пакет будет доставлен по адресу, заданному атакующим, соответственно, ответить на запрос сможет подменный DNS-сервер (и ответ, понятно, может содержать адрес произвольного узла). Также нужно модифицировать ответный пакет, чтобы он содержал нужный адрес отправителя. Почему нельзя заменить ответы сразу на перехватывающем узле, без отправки дальше? Потому что всё же имеется некоторая защита трафика, а секретный симметричный ключ атакующему неизвестен.

В режиме шифрования CTR, блочный шифр используется для зашифрования некоторого значения, изменяющегося для каждого следующего блока – это даёт ключевую последовательность (или гамму). Далее вычисляется XOR от блоков открытого текста и соответствующих блоков ключевой последовательности: это прямое побайтовое суммирование. Так как атакующий перехватывает все сообщения, ему известно значение блока шифротекста. Также, из структуры пакетов, известны смещения байтов, содержащих запись IP-адреса и значения этих байтов. Соответственно, атакующий может легко вычислить такую маску, которая при последующем суммировании с ключевым потоком на стороне настоящей сети LTE даст в результате нужные значения байтов записи адреса. Эту маску атакующий записывает в нужный фрагмент зашифрованного пакета. Это типовая атака, очень давно известная для режимов CTR (это, конечно, только подчёркивает странность того факта, что в LTE здесь нет контроля целостности). Единственную небольшую проблему создают контрольные суммы, которые есть и в IP-пакете, и в части, относящейся к UDP. Авторы работы справляются с этой проблемой при помощи модификации значений дополнительных полей пакетов, которые также известны заранее (в частности, поле TTL IP).

Модифицированный пакет с DNS-запросом будет успешно обработан подставным сервером, после чего абонентский смартфон получит подставной ответ, тем самым можно переадресовать HTTP-запросы и запросы других протоколов, при условии, что реализация использует DNS. Это, в частности, актуально для распространённых мессенджеров.



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

Сейчас сайт снова должен быть доступен из сетей российских провайдеров в штатном режиме. Так как некоторое время назад многочисленные сети (миллионы IP-адресов) попали под блокировку, в том числе, и подсеть с адресами dxdt.ru, пришлось добавить IP-адресов сайту. Это делается при помощи внесения дополнительных A-записей в DNS. Я добавил ещё три адреса, сделав на соответствующих узлах TCP-туннели к основному серверу (сейчас уже вернул единственный адрес, так как блокировки пошли на спад).

Почему это работало. В случае наличия нескольких адресов, браузер, обнаружив недоступность какого-то из них (из-за блокировок у провайдера), должен попробовать установить соединение с другим адресом. В принципе, всё примерно так и выходило, но только не в случае HTTP: потому что для HTTP некоторые провайдеры показывали “заглушку”, сообщающую о том, что сайт заблокирован. Соответственно, браузер полагал, что эта заглушка и есть сайт, и не делал попыток обратиться по другим адресам. Тут нужно учитывать следующий момент: первый GET-запрос, для извлечения основного тела документа, браузер всегда делает только по одному из адресов; это обусловлено тем, что отправлять два одинаковых запроса на разные IP-адреса в ситуации нормальной работы Сети особого смысла нет, это лишь создаст дополнительный трафик и нагрузку. Уже после того, как получен основной код страницы, браузер обращается ко всем доступным IP-адресам веб-узла параллельно, за сопутствующими ресурсами, а именно – за картинками, таблицами стилей и так далее. Но когда провайдер перехватывает запрос и подменяет узел dxdt.ru на свой собственный, браузер получает код этой провайдерской страницы. В итоге, если пользователю с HTTP не повезло, и его браузер обратился именно к заблокированному IP-адресу из имеющихся, то и на сайт браузер уже не попадёт, до повторной попытки загрузки.

А вот с HTTPS ситуация гораздо лучше: пока что не все провайдеры пытаются подменять TLS-узлы, поэтому соответствующие TCP-соединения просто разрываются, а браузер сразу видит, что этот адрес нерабочий и прозрачно переходит к следующему. Вмешательство же провайдера в TLS-соединение при помощи подмены узла – будет приводить к появлению предупреждения браузера. Так как dxdt.ru использует HPKP, это предупреждение во многих браузерах нельзя “подавить”, кликнув что-нибудь вроде кнопки “Всё равно продолжить”. Таким образом, HPKP тоже очень хорошо помогает в подобных случаях. Кстати, Google собирается убрать поддержку HPKP из Chrome, под совершенно надуманным предлогом. Это, в принципе, понятно: корпорация, с некоторых пор, не желает давать в руки пользователям распределённый, независимый от некоторого центра инструмент проверки подлинности сайтов. Впрочем, это другая история.

Итак, сайт dxdt.ru должен быть опять доступен.



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

Очередная новость “про блокировки” сообщает, что, якобы, Amazon запретил “использовать свои сети в качестве прокси” (варианты: использовать для “обхода блокировок” и др.). Сообщения сопровождаются ссылкой на публикацию AWS (Amazon Web Services), где, впрочем, рассказывается о другом.

О чём идет речь? Действительно, существует схема маскировки имени сервиса, под названием Domain Fronting. Схема построена на архитектурной особенности HTTPS: данный протокол использует TLS в качестве транспорта, соответственно, появляются два уровня – TLS и HTTP. С каждым из этих уровней связано некоторое имя сервера (имя хоста). В TLS это имя передаётся в поле SNI (Server Name Indication), в открытом виде, то есть, в виде, доступном для просмотра системой DPI. На уровне HTTP есть ещё одно имя сервера, оно входит в состав адреса документа (URI), который запрашивает клиент. Этот адрес, а следовательно и имя, входящее в его состав, передаётся уже в зашифрованном виде, поэтому недоступен для DPI.

Пример: пусть клиент, являющийся браузером, использует веб-сервер под именем “example.com” и пытается с помощью HTTPS извлечь документ по адресу “https://example.com/document.html”. Тогда при установлении TLS-соединения, которое происходит до отправки HTTP-запроса, браузером в поле SNI (TLS) будет передано имя “example.com” (обратите внимание: без полного адреса документа, только имя узла, домен). После того, как TLS-соединение установлено, браузер отправит GET-запрос HTTP, указав, согласно спецификации протокола HTTP, адрес документа “/document.html” и имя узла (в специальном поле заголовка HTTP-запроса, под названием Host) “example.com”. Это имя совпадает с именем на уровне TLS, в поле SNI, но вообще имена могут различаться, так как находятся на разных уровнях абстракции. Приложение, работающее по HTTP, вообще обычно не видит не только имени в SNI, но и самого протокола TLS.

Domain Fronting строится на подмене имён SNI и HTTP. В SNI указывается имя одного сервера, но после того, как TLS-соединение установлено, HTTP запросы отправляются с указанием другого имени. Поясню в терминах примера из предыдущего абзаца: в TLS SNI указывается имя “example.com”, однако GET-запрос уже отправляется с указанием “test.ru” в качестве имени хоста. Теперь на уровне HTTP указано совсем другое имя, но так как TLS и HTTP используют разный контекст, сервис, где размещён исходный узел (адресуемый example.com в нашем примере), может выполнять и HTTP-запросы к test.ru. Это будет являться побочным эффектом реализации HTTPS на стороне сервиса.

Теперь предположим, что из некоторого сегмента Глобальной сети доступ к test.ru по каким-то причинам невозможен. Используя Domain Fronting можно замаскировать запросы к test.ru под HTTPS-сессию с узлом example.com: так как HTTP-запросы передаются в зашифрованном виде, анализирующая трафик сторона видит только имя example.com в поле SNI TLS. Конечно, могут заблокировать и доступ к example.com, в том числе, по IP-адресу, но тут в игру вступает административная часть: представьте, что вместо example.com используется google.com (или какой-то другой массовый сервис) – мало кто готов блокировать условный Google. Конечно, чтобы всё сработало, требуется поддержка описанной схемы со стороны сервиса, используемого как прикрытие. Именно на этом этапе и возникает сервис “Амазон” CloudFront, который позволяет (или позволял, см. ниже) использовать такую схему для ресурсов, которые размещаются за CloudFront. При этом “заехать” за чей-то домен можно без ведома того клиента CloudFront, который этот домен использует штатно, что, конечно, не самая привлекательная особенность сервиса.

Метод маскировки с использованием Domain Fronting известен много лет. Наличие такой особенности объясняется тем, что для массового сервиса удобнее жёстко разделить TLS и HTTP – одни логические узлы обрабатывают TLS-соединение (выполняют “терминирование TLS”), а другие – работают с HTTP, уже в открытом виде. Поводом для новостей про “запрет обхода блокировок” как раз послужило то, что “Амазон” недавно обновил платформу CloudFront, исправив обработку контекстов и, тем самым, удалив возможность использования Domain Fronting. Думаю, понятно, что к “обходу блокировок” это если и имеет какое-то отношение, то весьма и весьма косвенное, и только со стороны тех нестандартных клиентов, которые данную особенность использовали. К ним, например, относится мессенджер Signal, который, впрочем, уже получил предупреждение о нарушении правил использования сервиса от Amazon.



Comments Off on Domain Fronting, AWS и блокировки с обходом
Навигация по запискам: « Позже Раньше »