Блокировки VLESS Reality в 2026 году и переход на self-steal
Классическая схема VLESS Reality, где сервер притворяется чужим сайтом вроде www.google.com или www.microsoft.com, в России перестала работать надёжно. ТСПУ научились находить такие серверы, а вслед за сервером блокируют и всю подсеть хостера. Рабочая замена: self-steal, когда Reality маскируется под ваш собственный сайт на вашем домене.
Что происходит
Роскомнадзор атакует VLESS волнами:
| Когда | Что изменилось |
|---|---|
| Ноябрь 2025 | Первые блокировки VLESS по сигнатуре TLS-хендшейка на порту 443 |
| 17 февраля 2026 | Переход на косвенные признаки: SNI не соответствует сети, из которой отвечает сервер, нетипичный для браузера характер соединений |
| Май 2026 | Повторные тесты блокировок в Сибири, на Дальнем Востоке и в Москве |
| Август и сентябрь 2026 | Блокировки целых подсетей и автономных систем хостеров, массовые сбои у VPN-сервисов |
Сам протокол Reality не взломан: трафик по-прежнему зашифрован, а хендшейк неотличим от обычного TLS 1.3. Проблема в том, подо что маскируется сервер.
Почему чужой SNI выдаёт сервер
В обычной настройке Reality клиент отправляет в ClientHello имя чужого сайта, например www.microsoft.com. Сервер, получив запрос без ключа, проксирует его на настоящий microsoft.com и отдаёт его настоящий сертификат. Для внешнего наблюдателя это выглядит как поход на сайт Microsoft.
ТСПУ видит открытые части хендшейка и сопоставляет их:
- SNI и IP не сходятся. Домен Microsoft должен отвечать с адресов Microsoft или её CDN. Если тот же SNI приходит на IP из диапазона VPS-хостинга, это аномалия, которую легко проверить по ASN.
- Активная проверка. ТСПУ может сам подключиться к подозрительному IP. Reality честно отдаст ему сайт Microsoft, и это только подтверждает расхождение: на дешёвом VPS не живёт microsoft.com.
- Поведение клиента. По наблюдениям пользователей, учитывается и отпечаток TLS (uTLS fingerprint), и частота: много параллельных TLS-сессий к одному SNI за короткое время нетипичны для браузера.
Поскольку признаки проверяются автоматически, после нескольких таких серверов в одной подсети под ограничения попадает вся подсеть. Страдают и соседи, у которых VPN нет вовсе. Поэтому хостеры начали прямо запрещать маскировку под сторонние ресурсы и проверять серверы на чужие сертификаты.
Не маскируйтесь под чужие сайты
Не используйте в serverNames, target (dest) или сертификате домены, которые вам не принадлежат: google.com, microsoft.com, apple.com, yahoo.com и подобные. Такая настройка быстрее всего приводит к блокировке IP, причём не только вашего.
Что такое self-steal
Self-steal (steal oneself, «украсть у себя») это та же схема Reality, но целью маскировки служит ваш собственный сайт:
- у вас есть свой домен, и его A-запись указывает на IP вашего VPS;
- на этом же VPS работает настоящий веб-сервер (nginx) с сайтом и сертификатом Let's Encrypt;
- Xray слушает порт 443, а все запросы без ключа Reality отдаёт локальному nginx.
В итоге всё сходится. SNI это ваш домен, DNS этого домена ведёт на этот IP, сертификат выпущен именно для него, а ТСПУ при проверке видит обычный сайт. Расхождения, по которому срабатывает блокировка, просто нет.
Что понадобится
- VPS с Ubuntu 22.04, 24.04 или Debian 12. Хватит младшего тарифа, см. тарифы VPS.
- Свой домен или поддомен. Подойдёт любой регистратор.
- Доступ по SSH к серверу.
Дальше в командах и конфигах везде, где написано ВАШ_ДОМЕН, подставьте свой домен. Копировать команды как есть нельзя, без замены ничего не заработает.
Домен не должен выдавать VPN
Ни в домене, ни в поддомене не должно быть слов, которые намекают на прокси: vpn, proxy, node, server, tunnel, marzban, xray, vless, reality, remnawave, 3x-ui и похожих. Плохо: vpn.ваш-домен.ru, node1.ваш-домен.ru, marzban.ваш-домен.ru. Хорошо: blog.ваш-домен.ru, photos.ваш-домен.ru или просто ваш-домен.ru. SNI передаётся открытым текстом, и такие имена легко отловить простым списком слов.
Шаг 1. Направьте домен на сервер
У регистратора или в DNS-хостинге создайте A-запись ВАШ_ДОМЕН с IP вашего VPS. Проксирование через CDN (оранжевое облако в Cloudflare) не включайте: Reality должен принимать соединения напрямую.
Проверьте, что запись применилась:
dig +short ВАШ_ДОМЕНШаг 2. Поднимите сайт и получите сертификат
Установите nginx и certbot:
apt update && apt upgrade -y
apt install -y nginx certbotПоложите на сайт любую осмысленную страницу. Это может быть визитка, блог или заглушка проекта:
mkdir -p /var/www/site
echo '<!doctype html><html lang="ru"><meta charset="utf-8"><title>Мой сайт</title><h1>Мой сайт</h1></html>' > /var/www/site/index.htmlПолучите сертификат. Стандартный сайт nginx уже отвечает на порту 80 из /var/www/html:
certbot certonly --webroot -w /var/www/html -d ВАШ_ДОМЕН --deploy-hook "systemctl reload nginx"Шаг 3. Настройте nginx на локальный порт
Nginx больше не должен слушать порт 443 снаружи: этот порт займёт Xray. Сайт с TLS переезжает на 127.0.0.1:8443, а порт 80 остаётся для продления сертификата и редиректа.
Удалите стандартный сайт и создайте /etc/nginx/sites-available/site:
rm /etc/nginx/sites-enabled/defaultПодсвеченные строки содержат ваш домен, остальное копируйте как есть:
server {
listen 80;
server_name ВАШ_ДОМЕН;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 127.0.0.1:8443 ssl http2;
server_name ВАШ_ДОМЕН;
ssl_certificate /etc/letsencrypt/live/ВАШ_ДОМЕН/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ВАШ_ДОМЕН/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
root /var/www/site;
index index.html;
}Включите сайт и перезапустите nginx:
ln -s /etc/nginx/sites-available/site /etc/nginx/sites-enabled/site
nginx -t && systemctl reload nginxНа nginx 1.25.1 и новее nginx -t предупредит, что запись listen ... http2 устарела. Это не ошибка, конфиг работает. Новую директиву http2 on; здесь не используем, потому что nginx из репозиториев Ubuntu 22.04, 24.04 и Debian 12 её не знает и не запустится.
Шаг 4. Установите Xray
Официальный установщик ставит Xray как systemd-сервис:
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ installСгенерируйте UUID клиента, ключи Reality и короткий идентификатор:
xray uuid
xray x25519
openssl rand -hex 8Команда xray x25519 выводит приватный ключ (PrivateKey) и публичный. В актуальных версиях Xray публичный ключ подписан как Password (PublicKey), в старых как Public key. Приватный остаётся на сервере, публичный нужен клиенту.
Шаг 5. Настройте Reality на свой сайт
Установщик создаёт файл /usr/local/etc/xray/config.json, в котором только {}. Откройте его (nano /usr/local/etc/xray/config.json), удалите {} и вставьте конфиг ниже целиком. В подсвеченных строках замените значения на свои из шага 4.
Xray уже был настроен?
Тогда не перезаписывайте файл целиком: пропадут ваши пользователи и ключи, и все старые подключения перестанут работать. Переходите к разделу Если Xray уже установлен, там показано, какие строки поменять.
{
"log": { "loglevel": "warning" },
"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": {
"target": "127.0.0.1:8443",
"serverNames": ["ВАШ_ДОМЕН"],
"privateKey": "ВАШ_PRIVATE_KEY",
"shortIds": ["ВАШ_SHORT_ID"]
}
},
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] }
}
],
"outbounds": [
{ "protocol": "freedom", "tag": "direct" },
{ "protocol": "blackhole", "tag": "block" }
]
}Главное отличие от классической схемы: target указывает на локальный nginx, а не на чужой сайт, и в serverNames стоит ваш домен. В старых версиях Xray поле target называется dest.
Перезапустите Xray и откройте порты, если включён UFW:
systemctl restart xray
systemctl status xray --no-pager
ufw allow 80/tcp
ufw allow 443/tcpШаг 6. Проверьте маскировку
Откройте https://ВАШ_ДОМЕН в браузере. Должен открыться ваш сайт с валидным сертификатом без предупреждений. Именно это увидит любой, кто подключится к серверу без ключа.
Из терминала то же самое:
curl -sI https://ВАШ_ДОМЕНШаг 7. Подключите клиента
Соберите ссылку и импортируйте её в клиент: v2rayN, Hiddify, NekoBox, v2RayTun, Streisand, Happ или любой другой с поддержкой Reality.
vless://ВАШ_UUID@ВАШ_ДОМЕН:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=ВАШ_ДОМЕН&fp=chrome&pbk=ВАШ_PUBLIC_KEY&sid=ВАШ_SHORT_ID&type=tcp#oblakosniсовпадает с вашим доменом и сserverNamesна сервере.pbkэто публичный ключ из шага 4.fpэто отпечаток TLS. Если соединение подвисает у конкретного провайдера, попробуйтеfirefox.
Если Xray уже установлен
Ставить всё заново не нужно. UUID, ключи Reality и shortIds остаются прежними, меняются только домен и то, куда Xray отправляет запросы без ключа. Перед правками сохраните копию конфига:
cp /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.bakПуть /usr/local/etc/xray/config.json относится к официальному установщику. Если Xray ставили через панель, смотрите раздел про панели ниже.
Как читать примеры правок
Конфиг целиком не перезаписывайте. В примерах ниже красные строки показывают, что у вас сейчас, а зелёные то, на что их заменить. Строки без подсветки и всё остальное в файле оставьте как есть, вместо ... у вас будут свои значения.
Reality с чужим доменом
Это случай, когда в конфиге стоит www.microsoft.com, www.google.com или другой чужой сайт.
- Выполните шаг 1, шаг 2 и шаг 3 этой инструкции. Nginx займёт только порт 80 и локальный
127.0.0.1:8443, работающему Xray на порту 443 он не помешает. - Откройте конфиг (
nano /usr/local/etc/xray/config.json), найдите блокrealitySettingsи замените в нём две строки. Чужой домен у вас может быть другим, напримерwww.google.com:
"realitySettings": {
"dest": "www.microsoft.com:443",
"serverNames": ["www.microsoft.com"],
"target": "127.0.0.1:8443",
"serverNames": ["ВАШ_ДОМЕН"],
"privateKey": "...",
"shortIds": ["..."]
}Поля dest и target это одно и то же, у вас может быть любое из них. Важно, чтобы в конфиге осталось только одно. Если в realitySettings есть "xver" больше нуля, поставьте 0: иначе Xray будет отправлять nginx заголовок PROXY protocol, которого nginx из этой инструкции не ждёт.
- Проверьте конфиг и перезапустите Xray:
xray run -test -c /usr/local/etc/xray/config.json
systemctl restart xray- Выполните шаг 6: по
https://ВАШ_ДОМЕНдолжен открываться ваш сайт. - Обновите ссылки у всех клиентов: в
sniтеперьВАШ_ДОМЕН, адрес сервера тоже лучше заменить на домен.pbk,sidи UUID не меняются. Старые ссылки со старым SNI работать перестанут.
Reality, установленный через AmneziaVPN
Если сервер настраивали через приложение AmneziaVPN, протокол XRay там это тоже VLESS Reality. Xray работает в Docker-контейнере amnezia-xray, конфиг лежит внутри контейнера в /opt/amnezia/xray/server.json. Посмотреть его можно так:
docker exec amnezia-xray cat /opt/amnezia/xray/server.jsonПо умолчанию приложение маскирует сервер под www.googletagmanager.com. Это сайт Google, то есть ровно та схема, которую сейчас блокируют. Полностью перейти на self-steal из приложения нельзя. В настройках XRay есть только поле Server Name (SNI), отдельного поля для адреса маскировки нет. Приложение всегда записывает dest в виде домен:443, а для self-steal нужен адрес локального nginx на другом порту. Если же dest станет ВАШ_ДОМЕН:443, Xray будет пересылать запросы сам себе. Поэтому dest придётся поменять на сервере вручную.
Есть две особенности, которые надо учесть:
- Контейнер работает в своей сети Docker.
127.0.0.1внутри него указывает на сам контейнер, поэтому nginx нужно повесить на адрес шлюза Docker, а не на localhost. - Приложение заново записывает
server.jsonпри каждом открытии и сохранении настроек XRay и при этом может сменить ключи. После ручной правки не открывайте настройки XRay в приложении, иначе изменения пропадут.
Порядок действий:
- Выполните шаг 1 и шаг 2. Порт 80 контейнер Amnezia не занимает, certbot отработает как обычно.
- Узнайте адрес шлюза Docker. Обычно это
172.17.0.1:
docker network inspect bridge -f '{{(index .IPAM.Config 0).Gateway}}'- Выполните шаг 3, но в конфиге nginx во втором блоке
serverзамените одну строку, адрес шлюза возьмите из пункта 2:
server {
listen 127.0.0.1:8443 ssl http2;
listen 172.17.0.1:8443 ssl http2;
server_name ВАШ_ДОМЕН;Чтобы nginx не падал при загрузке сервера, когда Docker ещё не создал этот адрес, разрешите привязку к нему заранее:
echo 'net.ipv4.ip_nonlocal_bind=1' > /etc/sysctl.d/99-nonlocal-bind.conf
sysctl --system
nginx -t && systemctl reload nginxЕсли включён UFW, разрешите контейнерам доступ к этому порту:
ufw allow from 172.17.0.0/16 to any port 8443 proto tcp- В приложении AmneziaVPN откройте настройки протокола XRay на сервере, в разделе Security впишите в поле Server Name (SNI)
ВАШ_ДОМЕНи сохраните. Приложение обновитserverNamesна сервере и SNI в подключении. - Теперь замените
destна сервере. Внутри контейнера нет удобного редактора, поэтому скопируйте конфиг наружу, поправьте и верните обратно:
docker cp amnezia-xray:/opt/amnezia/xray/server.json /root/server.json
cp /root/server.json /root/server.json.bak
nano /root/server.jsonФайл целиком не перезаписывайте. В блоке realitySettings замените одну строку dest, адрес шлюза возьмите из пункта 2. Подсвеченная строка serverNames уже должна содержать ваш домен после пункта 4, проверьте это. Остальные строки не трогайте:
"realitySettings": {
"dest": "www.googletagmanager.com:443",
"dest": "172.17.0.1:8443",
"fingerprint": "...",
"privateKey": "...",
"serverNames": ["ВАШ_ДОМЕН"],
"shortIds": ["..."]
}docker cp /root/server.json amnezia-xray:/opt/amnezia/xray/server.json
docker exec amnezia-xray xray run -test -config /opt/amnezia/xray/server.json
docker restart amnezia-xray- Выполните шаг 6: по
https://ВАШ_ДОМЕНдолжен открываться ваш сайт. - Поделитесь подключением на остальные устройства заново из приложения, старые подключения со SNI googletagmanager работать перестанут.
Надёжнее уйти с Amnezia на обычный Xray
Из-за того что приложение перезаписывает конфиг, ручная правка держится до первого открытия настроек XRay. Если вы готовы работать в терминале, проще удалить протокол XRay в приложении (это освободит порт 443) и поставить Xray по этой инструкции с начала.
VLESS с TLS и неудачным доменом
Это схема без Reality, где Xray сам держит сертификат Let's Encrypt, а домен содержит vpn, node или другое «говорящее» слово. Нужен новый домен и новый сертификат.
- Создайте A-запись нового домена на IP сервера, как в шаге 1.
- Выпустите сертификат на новый домен. Если на порту 80 работает nginx, используйте webroot, как в шаге 2. Если порт 80 свободен, хватит встроенного сервера certbot:
certbot certonly --standalone -d ВАШ_ДОМЕН- Откройте конфиг (
nano /usr/local/etc/xray/config.json) и в блокеtlsSettingsзамените строки со старым доменом. Старый домен и пути у вас свои, меняйте именно те строки, где он встречается:
"tlsSettings": {
"serverName": "vpn.старый-домен.ru",
"serverName": "ВАШ_ДОМЕН",
"certificates": [
{
"certificateFile": "/etc/letsencrypt/live/vpn.старый-домен.ru/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/vpn.старый-домен.ru/privkey.pem"
"certificateFile": "/etc/letsencrypt/live/ВАШ_ДОМЕН/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/ВАШ_ДОМЕН/privkey.pem"
}
]
}- Если в
fallbacksзапросы уходят на nginx, замените старый домен и вserver_nameего конфига, затем выполнитеnginx -t && systemctl reload nginx. - Проверьте конфиг и перезапустите Xray:
xray run -test -c /usr/local/etc/xray/config.json
systemctl restart xray- Обновите у клиентов адрес сервера и
sniна новый домен. Когда все переключатся, удалите старую DNS-запись.
Ошибка доступа к ключу
Официальный установщик запускает Xray от пользователя nobody, а ключи Let's Encrypt может читать только root. Если раньше вы копировали сертификаты в отдельную папку, скопируйте туда новые так же. Если в journalctl -u xray появилась ошибка permission denied, переустановите Xray с запуском от root:
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install -u rootПерезапускать Xray после продления сертификата не нужно: он сам перечитывает файлы сертификатов раз в час.
Xray в панели
Значения те же, что и в конфиге выше, меняется только место, где их вводить.
- 3x-ui. Откройте Inbounds (в русском интерфейсе Входящие) и откройте нужный инбаунд на редактирование. Для Reality впишите в Target (в русском интерфейсе Цель)
127.0.0.1:8443, в SNIВАШ_ДОМЕН, Xver оставьте0. Ключи заново генерировать не нужно. Сохраните и раздайте клиентам новые ссылки из панели. - Marzban. Конфиг Xray редактируется в разделе Core Settings: замените
target(илиdest) иserverNamesвrealitySettings. Если в настройках хостов прописан старый SNI, замените и его. - Remnawave. Откройте Config Profiles, выберите профиль ноды и замените
targetиserverNamesвrealitySettings. Старый SNI в настройках хостов тоже замените.
Nginx в этом случае ставится на ту же машину, где работает Xray (для Marzban и Remnawave это нода). Если Xray запущен в Docker без network_mode: host, адрес 127.0.0.1 указывает внутрь контейнера, и до nginx на хосте он не достучится.
Если не подключается
| Симптом | Что проверить |
|---|---|
| Сайт по домену не открывается | A-запись, nginx -t, слушает ли nginx 127.0.0.1:8443: ss -tlnp |
| Xray не стартует | journalctl -u xray -n 50, синтаксис JSON, не занят ли порт 443 nginx |
| Сайт открывается, VPN нет | Совпадают ли UUID, sni, pbk и sid с конфигом сервера |
| Сертификат не продлевается | Доступен ли порт 80 снаружи, certbot renew --dry-run |
| Работало и перестало у одного провайдера | Смените fp, проверьте с другой сети, нет ли блокировки IP целиком |
Что ещё помогает
- Не раздавайте конфиг широко. Чем больше устройств и пользователей, тем заметнее профиль трафика. Держите VPN личным.
- Сайт должен выглядеть живым. Пустая страница по умолчанию nginx хуже, чем простая, но настоящая страница.
- Регулярно обновляйте Xray, той же командой установщика. Разработчики быстро реагируют на новые методы детектирования.
Только для личного использования
Правила OBLAKO разрешают личный VPN для себя, семьи или небольшой команды. Публичный VPN и перепродажа доступа запрещены, подробнее в статье Личный VPN на VPS.