Skip to content
RUEN

Блокировки 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 должен принимать соединения напрямую.

Проверьте, что запись применилась:

bash
dig +short ВАШ_ДОМЕН

Шаг 2. Поднимите сайт и получите сертификат ​

Установите nginx и certbot:

bash
apt update && apt upgrade -y
apt install -y nginx certbot

Положите на сайт любую осмысленную страницу. Это может быть визитка, блог или заглушка проекта:

bash
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:

bash
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:

bash
rm /etc/nginx/sites-enabled/default

Подсвеченные строки содержат ваш домен, остальное копируйте как есть:

nginx
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:

bash
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
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

Сгенерируйте UUID клиента, ключи Reality и короткий идентификатор:

bash
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 уже установлен, там показано, какие строки поменять.

json
{
  "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:

bash
systemctl restart xray
systemctl status xray --no-pager
ufw allow 80/tcp
ufw allow 443/tcp

Шаг 6. Проверьте маскировку ​

Откройте https://ВАШ_ДОМЕН в браузере. Должен открыться ваш сайт с валидным сертификатом без предупреждений. Именно это увидит любой, кто подключится к серверу без ключа.

Из терминала то же самое:

bash
curl -sI https://ВАШ_ДОМЕН

Шаг 7. Подключите клиента ​

Соберите ссылку и импортируйте её в клиент: v2rayN, Hiddify, NekoBox, v2RayTun, Streisand, Happ или любой другой с поддержкой Reality.

text
vless://ВАШ_UUID@ВАШ_ДОМЕН:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=ВАШ_ДОМЕН&fp=chrome&pbk=ВАШ_PUBLIC_KEY&sid=ВАШ_SHORT_ID&type=tcp#oblako
  • sni совпадает с вашим доменом и с serverNames на сервере.
  • pbk это публичный ключ из шага 4.
  • fp это отпечаток TLS. Если соединение подвисает у конкретного провайдера, попробуйте firefox.

Если Xray уже установлен ​

Ставить всё заново не нужно. UUID, ключи Reality и shortIds остаются прежними, меняются только домен и то, куда Xray отправляет запросы без ключа. Перед правками сохраните копию конфига:

bash
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. Выполните шаг 1, шаг 2 и шаг 3 этой инструкции. Nginx займёт только порт 80 и локальный 127.0.0.1:8443, работающему Xray на порту 443 он не помешает.
  2. Откройте конфиг (nano /usr/local/etc/xray/config.json), найдите блок realitySettings и замените в нём две строки. Чужой домен у вас может быть другим, например www.google.com:
json
"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 из этой инструкции не ждёт.

  1. Проверьте конфиг и перезапустите Xray:
bash
xray run -test -c /usr/local/etc/xray/config.json
systemctl restart xray
  1. Выполните шаг 6: по https://ВАШ_ДОМЕН должен открываться ваш сайт.
  2. Обновите ссылки у всех клиентов: в sni теперь ВАШ_ДОМЕН, адрес сервера тоже лучше заменить на домен. pbk, sid и UUID не меняются. Старые ссылки со старым SNI работать перестанут.

Reality, установленный через AmneziaVPN ​

Если сервер настраивали через приложение AmneziaVPN, протокол XRay там это тоже VLESS Reality. Xray работает в Docker-контейнере amnezia-xray, конфиг лежит внутри контейнера в /opt/amnezia/xray/server.json. Посмотреть его можно так:

bash
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. Выполните шаг 1 и шаг 2. Порт 80 контейнер Amnezia не занимает, certbot отработает как обычно.
  2. Узнайте адрес шлюза Docker. Обычно это 172.17.0.1:
bash
docker network inspect bridge -f '{{(index .IPAM.Config 0).Gateway}}'
  1. Выполните шаг 3, но в конфиге nginx во втором блоке server замените одну строку, адрес шлюза возьмите из пункта 2:
nginx
server {
    listen 127.0.0.1:8443 ssl http2; 
    listen 172.17.0.1:8443 ssl http2; 
    server_name ВАШ_ДОМЕН;

Чтобы nginx не падал при загрузке сервера, когда Docker ещё не создал этот адрес, разрешите привязку к нему заранее:

bash
echo 'net.ipv4.ip_nonlocal_bind=1' > /etc/sysctl.d/99-nonlocal-bind.conf
sysctl --system
nginx -t && systemctl reload nginx

Если включён UFW, разрешите контейнерам доступ к этому порту:

bash
ufw allow from 172.17.0.0/16 to any port 8443 proto tcp
  1. В приложении AmneziaVPN откройте настройки протокола XRay на сервере, в разделе Security впишите в поле Server Name (SNI) ВАШ_ДОМЕН и сохраните. Приложение обновит serverNames на сервере и SNI в подключении.
  2. Теперь замените dest на сервере. Внутри контейнера нет удобного редактора, поэтому скопируйте конфиг наружу, поправьте и верните обратно:
bash
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, проверьте это. Остальные строки не трогайте:

json
"realitySettings": {
  "dest": "www.googletagmanager.com:443", 
  "dest": "172.17.0.1:8443", 
  "fingerprint": "...",
  "privateKey": "...",
  "serverNames": ["ВАШ_ДОМЕН"], 
  "shortIds": ["..."]
}
bash
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
  1. Выполните шаг 6: по https://ВАШ_ДОМЕН должен открываться ваш сайт.
  2. Поделитесь подключением на остальные устройства заново из приложения, старые подключения со SNI googletagmanager работать перестанут.

Надёжнее уйти с Amnezia на обычный Xray

Из-за того что приложение перезаписывает конфиг, ручная правка держится до первого открытия настроек XRay. Если вы готовы работать в терминале, проще удалить протокол XRay в приложении (это освободит порт 443) и поставить Xray по этой инструкции с начала.

VLESS с TLS и неудачным доменом ​

Это схема без Reality, где Xray сам держит сертификат Let's Encrypt, а домен содержит vpn, node или другое «говорящее» слово. Нужен новый домен и новый сертификат.

  1. Создайте A-запись нового домена на IP сервера, как в шаге 1.
  2. Выпустите сертификат на новый домен. Если на порту 80 работает nginx, используйте webroot, как в шаге 2. Если порт 80 свободен, хватит встроенного сервера certbot:
bash
certbot certonly --standalone -d ВАШ_ДОМЕН
  1. Откройте конфиг (nano /usr/local/etc/xray/config.json) и в блоке tlsSettings замените строки со старым доменом. Старый домен и пути у вас свои, меняйте именно те строки, где он встречается:
json
"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"
    }
  ]
}
  1. Если в fallbacks запросы уходят на nginx, замените старый домен и в server_name его конфига, затем выполните nginx -t && systemctl reload nginx.
  2. Проверьте конфиг и перезапустите Xray:
bash
xray run -test -c /usr/local/etc/xray/config.json
systemctl restart xray
  1. Обновите у клиентов адрес сервера и sni на новый домен. Когда все переключатся, удалите старую DNS-запись.

Ошибка доступа к ключу

Официальный установщик запускает Xray от пользователя nobody, а ключи Let's Encrypt может читать только root. Если раньше вы копировали сертификаты в отдельную папку, скопируйте туда новые так же. Если в journalctl -u xray появилась ошибка permission denied, переустановите Xray с запуском от root:

bash
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.