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 и почему он всё ещё работает в РФ/Иране
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 нет.
10. Дальше
Reality — это TCP-стрим. Есть случаи (плохой UDP-канал, мобильник в роуминге, потери), где TCP-туннель страдает. Для этого случая существуют UDP-туннели на QUIC: Hysteria 2, TUIC. Они быстрее на плохих каналах и имеют другой набор противотрюков (port hopping, BBR Brutal). Это урок 08.