ESNI – зашифрованное поле SNI
https://dxdt.ru/2018/12/28/8645/
28. December 2018, 20:29 Безопасность, Интернет
При установлении 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, 05/02/19:
из-за ошибки в библиотеке NSS, на которой базируется реализация TLS в
Firefox, увидеть при помощи этого браузера ESNI на
tls13.1d.pw можно
только в том случае, если сервер не использовал пересогласование
параметров – то есть, нужно несколько раз обновить страницу; подробнее –
в отдельной записке).
https://dxdt.ru/2018/12/28/8645/