Reality — обман DPI без сертификата
Reality (RPRX, январь 2023) — самый революционный шаг в обходе блокировок за последние 5 лет. Главная идея: не маскироваться под HTTPS, а реально проводить HTTPS-handshake с настоящим чужим сайтом. Только в середине этого handshake клиент и сервер «перехватывают» канал. DPI видит идеальный TLS — потому что он идеальный.
- Что Reality «крадёт» у настоящего сайта и зачем
- Полный pipeline handshake: 8 шагов с участием третьего сервера
- Почему НЕ нужны: свой домен, свой сертификат, Let's Encrypt, CDN
- Как X25519 + ShortIDs защищают от active probing
- Какой «destination» (SNI-цель) выбирать и какой нельзя
- Полная Xray-конфигурация сервера и клиента
- Тонкости: SpiderX, server names, минимальный TLS-версия — всё что важно
- Слабости Reality и почему он всё ещё работает в РФ/Иране
Reality — прямой ответ на модель противника из урока 5: passive (настоящий JA3 и SNI чужого сайта), active probing (проба видит реальный apple.com), TLS-in-TLS (убран через Vision из урока 6). Он снимает главную зависимость Xray-стека — собственный домен и сертификат (урок 6). Держи это в голове: Reality не «ещё одна маскировка», а закрытие всех трёх эшелонов DPI разом.
1. Проблема, которую решает Reality
До Reality все «маскирующиеся» протоколы (Trojan, VLESS+TLS+WS) имели две слабости:
- Нужен настоящий домен и сертификат. Покупка домена, привязка к IP, Let's Encrypt, обновление каждые 90 дней. Каждый «свой» домен в blacklist DPI попадает быстро.
- Active probing. DPI может сам подключиться к подозрительному IP и проверить: «а есть ли тут реальный сайт?». Если нет — забанить.
Reality решает оба за раз: SNI указывает на чужой реальный сайт, и сервер Reality, увидев handshake без нужного «приветствия», проксирует handshake на тот самый чужой сайт. Active probe получит ответ настоящего сервера — не от твоего VPN.
2. Как работает Reality — высокоуровневая схема
3. Как сервер проверяет «свой/чужой» в первом байте
Это сердце Reality. Никакого пароля в plaintext, никакой явной аутентификации. Используется хитрая схема на X25519:
- На сервере сгенерирована пара
(server_priv, server_pub). server_pub кладётся в конфиг клиента. - Клиент при handshake генерирует свой ephemeral X25519
e_c. Считаетshared = X25519(e_c, server_pub). - Использует
sharedкак ключ для шифрования специального auth-tag, который кладётся в случайное место session_id поля ClientHello (32 байта random, как должно быть). Клиент пишет туда зашифрованный «правильный» магический cookie. - В Key Share extension клиент кладёт свой
e_c. Сервер видит его как обычный TLS Key Share — DPI не подозревает. - Сервер получает ClientHello, видит KeyShare, вычисляет
shared = X25519(server_priv, e_c), пытается расшифровать session_id. Если magic cookie сошёлся — клиент свой. - Если расшифровка не сошлась (это сторонний запрос, например, active probe DPI) — сервер
проксирует ClientHello на
dest = apple.com:443и отдаёт обратно настоящие ответы apple.com. Active probe видит реальный сайт.
Почему это математически невозможно отличить от настоящего TLS
В ClientHello session_id — это произвольные 32 байта, описанные стандартом TLS как «opaque». У реальных браузеров session_id — обычно случайные (или специфический формат). У клиента Reality session_id выглядит как случайный шум (потому что это шифротекст). DPI не может отличить «random» от «зашифрованного random» — это и есть фундамент Reality.
KeyShare X25519 — тоже выглядит как 32 байта random для DPI. Эфемерный pub-key всегда так выглядит. Никакой статистический классификатор не может опознать «не настоящий X25519 KeyShare».
4. ShortIDs — несколько клиентов на одном сервере
Если у тебя 10 пользователей, у каждого свой UUID — как сервер их различает? В Reality для этого есть ShortIDs — короткие (1-8 байт) hex-строки, которые тоже кладутся в зашифрованную часть session_id.
В конфиге сервера:
"shortIds": [ "", // ← пустой = «любой» (на отладке) "01ab", // пользователь 1 "02cd", // пользователь 2 "03ef", // пользователь 3 "0a0b0c0d0e0f1011" // VIP-пользователь, длиннее (8 байт) ]
У клиента в конфиге shortId: "01ab" — он его шифрует в session_id. Сервер
расшифровал — сравнил с whitelist'ом — пропустил.
5. Какой dest (SNI-цель) выбирать
Это самый важный конфигурационный параметр Reality. К чему предъявляются требования:
- TLS 1.3 only. Сервер должен поддерживать TLS 1.3 (Reality использует только её для KeyShare extension)
- X25519 supported. Должен поддерживать X25519 в KeyShare
- HTTP/2 enabled. Для правдоподобия (большинство современных сайтов)
- Иностранный сайт. Не российский (чтобы IP не «пингался» внутри РФ — это будет странно). Подходят: apple.com, microsoft.com, amazon.com, cloudflare.com
- Существующий сайт. ALPN-handshake должен реально отдавать контент, иначе active probe получит ошибку
- НЕ Cloudflare. CF использует тот же IP для тысяч сайтов — если SNI не совпадёт, ответ может прийти странным
- Стабильный IP. Не AnyCast-CDN с динамическими IP
В 2024-2025 популярные хорошие dest'ы:
www.microsoft.comwww.apple.comdl.google.comwww.lovelive-anime.jp— японские сайты часто хорошиwww.swift.comwww.icloud.com
github.com— Cloudflareyoutube.com— заблокирован в РФ, странно прикидываться- Локальные сайты страны, где сидит сервер
- Сайты, которые сами заблокированы в твоей стране
6. Полная конфигурация — сервер и клиент
Сервер (Xray-core)
{
"log": { "loglevel": "warning" },
"inbounds": [
{
"port": 443, // ← наружу 443, как у обычного HTTPS
"protocol": "vless",
"settings": {
"clients": [
{
"id": "12345678-1234-1234-1234-123456789012", // ← UUID пользователя
"flow": "xtls-rprx-vision", // ← Vision overlay
"email": "user1@vpn"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.microsoft.com:443", // ← маскируемся под MS
"xver": 0,
"serverNames": ["www.microsoft.com"], // ← валидные SNI
"privateKey": "SERVER_PRIVATE_KEY_BASE64", // ← xray x25519
"minClientVer": "",
"maxClientVer": "",
"maxTimeDiff": 0,
"shortIds": ["", "01ab", "02cd"]
}
}
}
],
"outbounds": [
{ "protocol": "freedom", "tag": "direct" },
{ "protocol": "blackhole", "tag": "block" }
],
"routing": {
"rules": [
{ "type": "field", "ip": ["geoip:private"], "outboundTag": "block" }
]
}
}
Генерация ключей: xray x25519 — выведет priv/pub keys.
Клиент (Xray / sing-box / NekoBox / v2rayN)
{
"inbounds": [
{ "port": 10808, "protocol": "socks", "listen": "127.0.0.1" }
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "VPS_IP", // ← IP твоего VPS
"port": 443,
"users": [
{
"id": "12345678-1234-1234-1234-123456789012",
"flow": "xtls-rprx-vision",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "www.microsoft.com", // ← маскировка под MS
"fingerprint": "chrome", // ← uTLS под Chrome
"publicKey": "SERVER_PUBLIC_KEY_BASE64",
"shortId": "01ab",
"spiderX": "/" // ← путь спайдеринга (см. ниже)
}
}
}
]
}
7. SpiderX — финальный штрих маскировки
Когда сервер Reality перехватил handshake, он отдал клиенту сертификат настоящего apple.com. После этого происходит обычный TLS application data. Но клиент НЕ открывает apple.com — он шлёт свой VPN-трафик через VLESS.
Чтобы DPI не заметил «странного поведения» (TLS-handshake с apple.com → дальше нет http-запросов к apple), Xray на стороне клиента эмулирует SpiderX: фоновые HTTP-запросы к настоящему apple.com по разным path. DPI видит: «клиент пошёл на apple.com и листает страницы» — нормально.
spiderX: "/" означает: при подключении делать GET / и эмулировать поведение
браузера. Можно настраивать паттерн обхода (что и как часто запрашивать).
8. Слабости Reality
Reality не магия. Несколько ограничений:
- IP сервера зачисляется в blacklist. Не по протоколу, а по объёму трафика. Если на твой IP идёт 100 ГБ/сутки — это уже подозрительно, ТСПУ может пометить «вероятно VPN». Reality не защищает от per-IP-блокировок по traffic volume.
- Тайминги. SpiderX делает запросы только на handshake. После — длинная сессия с маленькими/большими пакетами. Если у DPI хорошая ML-модель, она может задетектить «не настоящее браузерное поведение». Помогают uTLS + Vision + смешение реального трафика.
- Active probing на dest mismatch. Если активный probe из РФ подключится с
SNI=apple.com к твоему IP — он получит реальный ответ apple. Но если он подключится с другим
SNI к твоему IP (например, ничего не указав, или указав bing.com) — Reality его НЕ
обработает (сервер ждёт правильный SNI). Это потенциальный leak. В Xray есть параметр
serverNames— список допустимых SNI; всё что не в нём — отвергнуть. - Reality в РФ работает в 2025 потому, что ТСПУ не научилось это всё классифицировать. К 2026-2027 ML-классификация на bidirectional flow станет проблемой даже для Reality. Решения уже разрабатываются (см. урок 14).
9. Почему Reality всё ещё работает в 2026
- Снаружи неотличим от настоящего HTTPS. JA3 = настоящий Chrome. SNI = настоящий популярный сайт. Сертификат = настоящий чужой. Никакой статистики, которая могла бы выделить Reality среди «настоящих HTTPS-соединений».
- Active probing провален. Probe видит реальный apple.com.
- TLS-in-TLS нет. Vision splice убирает overhead и паттерн.
- Не нужен домен. Тысячи клиентов могут поднять Reality на любом VPS без domain registration — нечего вносить в blacklist.
- Open source, активно развивается. Каждый месяц патчи.
Reality — это текущий S-тир. Других протоколов такого уровня в 2026 нет.
Не поддельный паспорт, а вход через настоящую дверь
Trojan и обычный TLS-камуфляж — это качественная подделка документов: чем лучше подделка, тем дольше живёт, но эксперт (DPI) рано или поздно найдёт признак фальшивки (TLS-in-TLS, чужой JA3). Reality идёт иначе: он реально начинает входить в дверь настоящего здания — проводит подлинное TLS-рукопожатие с apple.com, с его настоящим сертификатом. Охранник (DPI) видит человека, честно входящего к Apple, — придраться не к чему, потому что это НЕ имитация, это Apple. И только в последний миг, уже внутри, «свой» клиент по секретному знаку (X25519-ключ + ShortID) сворачивает к твоему серверу, а чужой (probe) идёт дальше к настоящему Apple и ничего не замечает. Нельзя подделать то, что не подделываешь.
10. Мини-лаба: попробуй прямо сейчас
Ключи Reality и «кражу» чужого TLS можно рассмотреть без поднятия сервера:
# 1. Сгенерируй пару ключей Reality (X25519) — сервер отдаёт публичный клиентам
xray x25519
# Private key: ... / Public key: ... — та самая асимметрика из урока 2
# 2. Посмотри «жертву маскировки»: реальный TLS-сертификат сайта-донора.
# Именно ЭТОТ сертификат увидит DPI в твоём Reality-трафике.
openssl s_client -connect www.microsoft.com:443 -servername www.microsoft.com 2>/dev/null \
| openssl x509 -noout -issuer -subject -dates
# 3. Проверь пригодность донора: нужен TLS 1.3 + HTTP/2 (X25519) и НЕ за Cloudflare-CDN
openssl s_client -connect www.microsoft.com:443 -tls1_3 2>/dev/null | grep -E "Protocol|Cipher"
curl -sI https://www.microsoft.com | grep -iE "server|alt-svc"
# 4. Сгенерируй ShortID (несколько клиентов на одном сервере)
openssl rand -hex 8
Пункт 1 даст пару ключей — приватный остаётся на сервере, публичный прописывают клиенты (сравни с ролями ключей из урока 2). В пункте 2 ты увидишь ПОДЛИННЫЙ сертификат microsoft.com — это ровно то, что предъявит DPI твой Reality-сервер, поэтому придраться не к чему. Пункт 3 проверяет донора: нужен настоящий TLS 1.3 без чужого CDN впереди (иначе «кража» не сработает). Пункт 4 даёт ShortID — метку, по которой сервер отличает твоих клиентов от случайных проб, идущих к настоящему Microsoft.
11. Задачи самопроверки — реши, потом раскрой ответ
Задача 1. Объясни в двух предложениях, почему active probing, убивший Trojan, бессилен против Reality.
Probe от DPI не предъявляет секретный X25519-ключ и валидный ShortID, поэтому Reality-сервер прозрачно проксирует его на НАСТОЯЩИЙ сайт-донор (например, microsoft.com) — probe видит подлинный сайт с подлинным сертификатом и не находит ничего подозрительного. «Свой» клиент, знающий ключ, в нужный момент перехватывается сервером; отличить их снаружи невозможно, потому что до момента аутентификации всё — настоящий TLS к настоящему сайту.
Задача 2. Почему Reality не нужны ни собственный домен, ни сертификат Let's Encrypt, ни CDN — и какое практическое преимущество это даёт против блокировок?
Reality предъявляет чужой настоящий сертификат (донора), а не свой — регистрировать домен и выпускать сертификат незачем. Практический выигрыш: нечего вносить в чёрный список. Домен можно заблокировать по имени, а тут имени нет — есть только IP VPS и SNI чужого популярного сайта, который цензор блокировать не станет (себе дороже). Тысячи пользователей поднимают Reality на произвольных VPS без единой общей зацепки для блокировки.
Задача 3. Друг выбрал донором (dest/SNI) маленький персональный блог на shared-хостинге за Cloudflare. Назови две причины, почему это плохой выбор.
(1) За Cloudflare/CDN «кража» ломается: ты снимаешь TLS чужого CDN, а не самого сайта — параметры не совпадут, и маскировка станет заметной или неработающей. (2) Непопулярный редкий сайт сам по себе подозрителен: массовый поток «клиентов» к личному блогу — аномалия для статистического эшелона, и такой SNI легко занести в списки. Донор должен быть крупным, всегда живым, с TLS 1.3+X25519 и без чужого CDN впереди (apple.com, microsoft.com и т.п.).
Задача 4. Зачем в Reality нужны ShortID, если аутентификация и так идёт по X25519-ключу?
ShortID позволяет обслуживать нескольких клиентов/группы на одном сервере и различать их: короткая метка в рукопожатии сообщает серверу, что это «свой» и какой именно, до дорогой криптографии, и даёт возможность отзывать доступ выборочно (сменил ShortID — отключил группу), не меняя основную пару ключей. Это удобство эксплуатации и гранулярность, поверх базовой аутентификации ключом.
Задача 5. Reality сегодня — S-тир, но у него есть слабости. Назови хотя бы две и объясни, почему он всё равно работает.
Слабости: (1) статистический эшелон — если внутри туннеля идёт нехарактерный для веб-сёрфинга равномерный поток (большая закачка, стрим), профиль трафика может отличаться от реального визита на сайт-донор; (2) зависимость от «здоровья» донора — если выбранный сайт меняет TLS-параметры или ложится, маскировка деградирует; (3) TCP-природа — на плохих каналах хуже QUIC. Работает потому, что закрывает два самых дешёвых и массовых эшелона (passive и active probing) идеально, а статистику атаковать дорого и чревато ложными срабатываниями на настоящем трафике к популярным сайтам.
12. Словарик урока
13. Дальше
Reality — это TCP-стрим. Есть случаи (плохой UDP-канал, мобильник в роуминге, потери), где TCP-туннель страдает. Для этого случая существуют UDP-туннели на QUIC: Hysteria 2, TUIC. Они быстрее на плохих каналах и имеют другой набор противотрюков (port hopping, BBR Brutal). Это урок 08.