Что такое VLESS Reality и чем он отличается от обычного TLS
Классический VLESS+TLS требует домен и валидный сертификат: вы поднимаете свой хост, цензор видит ваш SNI, и такой узел легко ловится активным зондированием (active probing) — прибор сам стучится на 443 и по нестандартному ответу или самоподписанному сертификату понимает, что за ним прокси.
Reality решает это иначе — у вас нет собственного TLS-сертификата вообще. Сервер настроен на реальный чужой сайт (dest), и дальше:
- посторонний визитёр или зонд получает прозрачный проксипас всего TLS-соединения на этот настоящий сайт — подлинный сертификат, реальный контент, всё как при прямом заходе;
- ваш клиент встраивает в ClientHello криптографическую метку (общий секрет на базе x25519), и сервер после рукопожатия поднимает VLESS-туннель, оставляя снаружи вид легитимного TLS 1.3.
Итог: vless reality не подделывает сертификат — он одалживает настоящее рукопожатие настоящего сайта. Отсюда стойкость к probing: ломиться на ваш IP руками бесполезно, ответ неотличим от честного ресурса.
Как работает маскировка под чужой SNI
Ключевой элемент — vless reality sni. В ClientHello клиент указывает SNI не вашего сервера, а выбранного реального ресурса (serverName). DPI/ТСПУ на потоке видит:
- TLS 1.3 ClientHello с SNI популярного зарубежного сайта и браузерным отпечатком (uTLS,
fingerprint: chrome); - корректный обмен ключами X25519, ServerHello и сертификат — от имени настоящего сайта;
- никаких подозрительных редиректов и самоподписанных сертификатов.
Внутри ClientHello ваш клиент прячет аутентификатор: key_share выведен так, что сервер по общему секрету (публичный ключ у клиента, приватный на сервере) отличает «своего» от чужого. Свой получает туннель, чужой уходит на реальный dest.
Честное ограничение. SNI в пакете указывает на сайт, но IP назначения — ваш VPS, а не адрес этого сайта. Теоретически цензор может ловить рассинхрон «SNI одного сайта на IP другого» (SNI/IP mismatch). Массово на потоке ТСПУ такую сверку пока не наблюдают, но в модель угроз закладывать стоит: маскировка идеальна на уровне рукопожатия, но не отменяет того, что вы стучитесь на дата-центровый IP.
Как выбрать SNI и dest — критерии и проверка
От выбора dest/SNI зависит и стойкость, и работоспособность. Критерии живого кандидата:
- TLS 1.3 + X25519 — обязательно, без этого Reality не поднимется;
- HTTP/2 на стороне сайта — желательно;
- чужой зарубежный ресурс, который вы не контролируете и который маловероятно заблокируют (крупные сайты на больших CDN);
- не отдаёт редирект на другой домен;
- низкий RTT от вашего сервера до
dest(в идеале <30–50 мс) — рукопожатие ходит туда на каждое чужое подключение, дальнийdestзамедляет старт сессии; - не заезженный дефолт. Хрестоматийные
www.microsoft.com/dl.google.comиз каждого гайда — плохой выбор: их массово прописывают, и такие SNI первыми попадают под наблюдение.
Проверка кандидата перед боем:
# TLS 1.3 и согласованный ключ X25519
openssl s_client -connect example.com:443 -tls1_3 -servername example.com </dev/null 2>/dev/null | grep -E 'Protocol|Cipher|Server Temp Key'
# встроенный тест в свежих версиях Xray-core
xray tls ping example.com
В выводе openssl нужны TLSv1.3 и Server Temp Key: X25519. И главное: dest и serverNames должны быть согласованы — домен из serverNames обязан реально обслуживаться на хосте dest.
Пошаговая настройка сервера (VLESS TCP Reality)
Канонический вариант — vless tcp reality: VLESS поверх чистого TCP с security: reality. Сначала генерируем ключи и shortId:
xray x25519 # выдаст Private key / Public key
openssl rand -hex 8 # shortId, напр. 0123456789abcdef (0–16 hex-символов)
Inbound в конфиге Xray:
{
"inbounds": [{
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [{ "id": "ВАШ-UUID", "flow": "xtls-rprx-vision" }],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "chosen-site.example:443",
"xver": 0,
"serverNames": ["chosen-site.example"],
"privateKey": "ПРИВАТНЫЙ_КЛЮЧ_x25519",
"shortIds": ["", "0123456789abcdef"]
}
}
}]
}
Пояснения: flow: xtls-rprx-vision снимает проблему TLS-in-TLS и даёт скорость; пустая строка в shortIds разрешает клиентов без shortId, но для контроля лучше держать явное значение. В панелях (Remnawave, Marzban, 3x-ui) этот inbound генерируется автоматически — но dest/SNI панель ставит дефолтные, и их разумно заменить под свои критерии из раздела выше. После правки конфига не забудьте systemctl restart xray и проверьте, что порт 443 слушается (ss -tlnp | grep 443).
Настройка клиента
На клиенте прописываем публичный ключ (не приватный!), тот же SNI и shortId:
{
"outbounds": [{
"protocol": "vless",
"settings": {
"vnext": [{
"address": "IP_ВАШЕГО_СЕРВЕРА",
"port": 443,
"users": [{
"id": "ВАШ-UUID",
"encryption": "none",
"flow": "xtls-rprx-vision"
}]
}]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "chosen-site.example",
"fingerprint": "chrome",
"publicKey": "ПУБЛИЧНЫЙ_КЛЮЧ_x25519",
"shortId": "0123456789abcdef",
"spiderX": "/"
}
}
}]
}
В мобильных клиентах (v2rayNG, Streisand, Happ, sing-box) те же поля называются Reality PBK (public key), SID (shortId), SNI, Fingerprint, Flow. Обычно всё зашивается в ссылку vless://...?security=reality&sni=...&pbk=...&sid=...&fp=chrome&flow=xtls-rprx-vision#....
Самые частые причины «не коннектится»: перепутаны приватный/публичный ключи, flow прописан только с одной стороны, разошёлся shortId, либо клиент не поддерживает Vision.
Reality против XHTTP под блокировками: плюсы, минусы, гибрид
Сильные стороны Reality: без домена и сертификата, поднимается за минуты; максимальная стойкость к активному зондированию; прямой TCP + Vision = низкая задержка и высокая скорость; чистый отпечаток TLS 1.3.
Слабое место — открытый IP. Reality маскирует протокол, но соединение идёт напрямую на IP вашего VPS. В режиме белых списков, когда ТСПУ пропускает трафик только на разрешённые диапазоны, дата-центровая подсеть блокируется целиком — и идеальная маскировка рукопожатия не спасает, потому что до сервера просто не доходит пакет. Reality защищает *как* вы выглядите, но не *куда* вы стучитесь.
XHTTP дороже в настройке (нужен домен и сертификат, выше накладные на request-based транспорт), зато его можно завести за обратным прокси/CDN — то есть спрятать реальную ноду за IP, который у оператора связи в белом списке. Отсюда ключевой тезис: под жёсткими белыми списками устойчивость даёт не сам протокол, а фронт через whitelisted-CDN — клиент коннектится на разрешённый CDN-IP, а тот уже тянет трафик на вашу заблокированную по IP ноду.
Практический вывод — гибрид, а не «или-или». Reality держите как быстрый прямой профиль там, где IP ноды ещё достижим; CDN-фронтированный XHTTP — как fallback для зон с белыми списками. Раздавайте оба профиля в одной подписке, и клиент сам переключится, когда прямой узел отвалится.
Частые ошибки и диагностика
serverNameне поддерживает TLS 1.3 / X25519 — рукопожатие Reality не состоится. Проверьтеdestчерезopenssl s_client -tls1_3, в выводе должны бытьTLSv1.3иServer Temp Key: X25519.- Рассогласование
destиserverNames— домен изserverNamesдолжен реально обслуживаться на хостеdest. - Перегенерировали ключи на сервере, но не обновили клиента —
publicKeyперестаёт совпадать, все клиенты отваливаются. Меняете ключи — перевыпускайте подписку. flowтолько с одной стороны — Vision должен быть и в inbound, и в outbound, иначе разрыв.- Разъехались
shortId— значение на клиенте должно входить в списокshortIdsсервера (либо быть пустым, если пустая строка там разрешена). - Заезженный публичный SNI попал под наблюдение — смените
dest/SNI на менее очевидный живой ресурс. - Рассинхрон времени на сервере — TLS 1.3 чувствителен к часам, включите NTP (
timedatectl→NTP service: active). - «В одном приложении работает, в другом нет» — почти всегда разный
fingerprintили поддержка Vision в клиентах; выставьтеfp=chromeи берите актуальные сборки (sing-box, свежий Xray-core в клиенте).
Для отладки на сервере временно поставьте "show": true в realitySettings и смотрите лог рукопожатий.