Dev.to Security 🔐 Cybersecurity 👁 0

Как устроен обмен ключами в Reality: x25519, shortId и зачем серверу «чужой» сертификат

#реклама. Я Вадим, разработчик сервиса Unlimited VPN, и в конце статьи расскажу о нём. Основная часть — концептуальный разбор протокола REALITY по открытой документации и исходникам проекта Xray-core. Это не описание вну

#реклама. Я Вадим, разработчик сервиса Unlimited VPN, и в конце статьи расскажу о нём. Основная часть — концептуальный разбор протокола REALITY по открытой документации и исходникам проекта Xray-core. Это не описание внутренней кухни нашего сервиса, а объяснение того, как механизм задуман авторами.

Проблема, которую решает Reality

Классический VLESS поверх TLS требует собственного домена и настоящего сертификата. Сторонний наблюдатель видит рукопожатие с малоизвестным сайтом, и если зайти на этот адрес браузером, часто обнаруживается заглушка. Такой сервер легко отличить от обычного веб-ресурса.

Reality подходит с другой стороны: сервер не притворяется сайтом, он буквально перенаправляет «посторонних» на настоящий популярный сайт. Для внешнего проверяющего соединение выглядит как обращение к реальному ресурсу с его подлинным сертификатом.

Что такое x25519 и откуда берутся ключи

x25519 — функция согласования ключей Диффи — Хеллмана на эллиптической кривой Curve25519. У каждой стороны есть закрытый ключ и вычисленный из него открытый. Если клиент знает открытый ключ сервера, а сервер — открытый ключ клиента, обе стороны независимо вычисляют один и тот же общий секрет, ни разу не передав его по сети.

В Xray пара ключей сервера генерируется командой xray x25519. Закрытый ключ остаётся в конфигурации сервера, открытый (в клиентах он часто называется publicKey или pbk) попадает в ссылку подключения. Важно понимать: открытый ключ не секретен, но без него клиент не сможет доказать серверу, что он «свой».

Как клиент подаёт сигнал внутри обычного TLS

Рукопожатие TLS 1.3 начинается с сообщения ClientHello. В нём уже есть поле key_share с эфемерным открытым ключом x25519 — так устроен сам TLS, это не изобретение Reality. Клиент Reality использует этот же эфемерный ключ и открытый ключ сервера, чтобы вычислить общий секрет.

Дальше, согласно описанию в репозитории, из этого секрета выводится ключ, которым шифруется небольшой фрагмент данных, помещаемый в поле session_id ClientHello. Туда входят версия клиента, отметка времени и shortId. Для постороннего глаза session_id — просто 32 случайных байта, как и в любом другом браузерном рукопожатии.

Сервер, получив ClientHello, повторяет вычисление со своей стороны своим закрытым ключом. Если расшифровка удалась, время укладывается в допустимое окно, а shortId есть в списке разрешённых — значит, пришёл легитимный клиент.

Зачем нужен shortId

shortId — короткая шестнадцатеричная строка, которую администратор задаёт в конфиге сервера (список shortIds). По сути это дополнительный идентификатор: можно выдать разным группам клиентов разные значения и при необходимости отключать их по отдельности, не меняя пару ключей. Пустая строка тоже допустима, но тогда эта дополнительная граница исчезает. Если в ссылке опечатка в sid, сервер просто не признает клиента — один из типичных случаев, когда «всё настроено, но не работает».

«Чужой» сертификат: роль dest и serverNames

Самая необычная часть Reality — параметры dest и serverNames. В dest указывается адрес реального стороннего сайта с поддержкой TLS 1.3 и HTTP/2, а в serverNames — допустимые имена (SNI), которые клиент может указать.

Если ClientHello не прошёл проверку, сервер не рвёт соединение и не показывает ошибку. Он прозрачно проксирует трафик на dest, и проверяющий получает настоящий сертификат настоящего сайта. Никакой заглушки, никакого самоподписанного сертификата — именно поэтому активное зондирование мало что даёт.

Если же клиент опознан, сервер завершает рукопожатие сам. Документация описывает это так: сервер выдаёт «временный» сертификат, подпись которого клиент проверяет с помощью того же общего секрета. Это защищает клиента от подмены посредником: человек посередине не знает закрытого ключа сервера и не сможет корректно подписать ответ.

Отпечаток клиента: параметр fingerprint

Ещё одна деталь — fingerprint (fp), например chrome или firefox. Клиент Xray использует библиотеку uTLS, чтобы ClientHello по набору расширений и их порядку был похож на ClientHello популярного браузера. Иначе сам факт нестандартного рукопожатия выдавал бы Go-приложение.

Что из этого следует на практике

  • Ошибка в pbk или sid выглядит как «нет соединения», хотя сервер жив.
  • Неправильные системные часы ломают проверку отметки времени.
  • SNI в ссылке должен совпадать с одним из serverNames на сервере.
  • Выбор dest — ответственность администратора: сайт должен поддерживать TLS 1.3 и быть доступен с сервера.

Именно поэтому большинство клиентов принимают готовую ссылку vless:// или подписку: все эти параметры приходят одним пакетом и вручную ничего вбивать не нужно.

О сервисе (реклама)

Unlimited VPN — мой проект, работающий на VLESS Reality. Серверы расположены в Чехии. Подключение через приложения Happ или v2RayTun на iOS, Android, Windows, macOS и Android TV. Есть пробный период на 3 дня без привязки карты.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.