ESNI – зашифрованное поле SNI

При установлении 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

Адрес записки: https://dxdt.ru/2018/12/28/8645/

Похожие записки:



Далее - мнения и дискуссии

(Сообщения ниже добавляются читателями сайта, через форму, расположенную в конце страницы.)

1 комментарий от читателей

  • 1. 3rd April 2019, 00:06 // Читатель jeudesprits написал:

    Работает так же и в Safari 12.1 на macOS

Написать комментарий

Ваш комментарий:

Введите ключевое слово "Q96FR" латиницей СПРАВА НАЛЕВО (<--) без кавычек: (это необходимо для защиты от спама).

Если видите "капчу", то решите её. Это необходимо для отправки комментария ("капча" не применяется для зарегистрированных пользователей). Обычно, комментарии поступают на премодерацию, которая нередко занимает продолжительное время.