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 можно только в том случае, если сервер не использовал пересогласование параметров – то есть, нужно несколько раз обновить страницу; подробнее – в отдельной записке).
Адрес записки: https://dxdt.ru/2018/12/28/8645/
Похожие записки:
- Экспериментальный сервер TLS 1.3 - отключение
- Реплика: преодоление air gap
- Домены верхнего уровня, реестры и администраторы
- Gofetch как уязвимость
- Браузеры и перехват TLS без участия УЦ
- Симметричные ключи, аутентификация и стойкость в TLS
- Техническое: добавление ключей в dnssec.pw
- Реестр параметров TLS IANA и именование индексов
- Ссылка: bluetooth-атака на iOS
- Новые корневые сертификаты на audit.statdom.ru
- "Постквантовый" компьютер
1 комментарий от читателей
1. 3rd April 2019, 00:06 // Читатель jeudesprits написал:
Работает так же и в Safari 12.1 на macOS
Написать комментарий