Ошибка TLS рукопожатия в Remnawave VLESS Reality: как исправить
Подробное руководство по диагностике и устранению ошибки TLS рукопожатия в Remnawave при подключении внешней ноды с VLESS + Reality. Проверяем конфигурацию Xray, Nginx, логи и типовые правки для стабильного соединения.
Как исправить ошибку TLS рукопожатия в Remnawave при подключении к хосту через внешнюю ноду?
Описание:
- Установил панель с локальной нодой и установил внешнюю ноду через скрипт eGames.
- При подключении к хосту с внешней ноды появляется ошибка TLS рукопожатия.
- Панель подключается к ноде и отдает ей команды.
Конфигурация ядра:
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
{
"address": "https://dns.google/dns-query",
"skipFallback": false
}
],
"queryStrategy": "UseIPv4"
},
"inbounds": [
{
"tag": "NLD-X8",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [],
"decryption": "none"
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls",
"quic"
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"dest": "/dev/shm/nginx.sock",
"show": false,
"xver": 1,
"spiderX": "",
"shortIds": [
"771f08d36893f672"
],
"privateKey": "OlGPEQCucgCOhFO26T-owAK1BLSrF-NEwq8PwFS8j1Y",
"serverNames": [
"nld-x8.plugvpn.ru"
]
}
}
}
],
"outbounds": [
{
"tag": "DIRECT",
"protocol": "freedom"
},
{
"tag": "BLOCK",
"protocol": "blackhole"
}
],
"routing": {
"rules": [
{
"ip": [
"geoip:private"
],
"type": "field",
"outboundTag": "BLOCK"
},
{
"type": "field",
"protocol": [
"bittorrent"
],
"outboundTag": "BLOCK"
}
]
}
}
Вопросы:
- Какие наиболее вероятные причины ошибки TLS рукопожатия в этой конфигурации (vless + reality, использование сокета /dev/shm/nginx.sock, параметры realitySettings)?
- Какие логи и команды проверить на панели, на ноде и в nginx для диагностики?
- Какие настройки reality/streamSettings или nginx чаще всего нужно менять для устранения TLS-ошибок?
- Какие дополнительные данные логов/конфигов нужно предоставить для точной диагностики?
Ошибка TLS рукопожатия в Remnawave при подключении через внешнюю ноду чаще всего вызвана рассинхроном параметров vless + reality: неверным dest (unix‑сокет vs host:port), несовпадением shortIds/privateKey или ошибками SNI/сертификата в nginx. Для remnawave ноды проверьте доступность и права /dev/shm/nginx.sock, уберите лишний proxy_protocol в конфиге nginx и временно включите детальный лог Xray — это даст ключ к решению. Ниже — пошаговый чек‑лист причин, команд для диагностики, типовые правки конфигураций и список логов, которые приложить для точной диагностики.
Содержание
- Причины ошибки TLS рукопожатия в vless reality и Remnawave нода
- Что проверить: логи и команды (панель, нода, nginx)
- Типовые правки reality/streamSettings и nginx для устранения ошибки TLS
- Пошаговые тесты и команды (socat / openssl / curl)
- Какие данные и логи приложить для точной диагностики
- Источники
- Заключение
Причины ошибки TLS рукопожатия в vless reality и Remnawave нода
Ниже — наиболее правдоподобные причины в порядке частоты и простоты проверки, что каждая значит и как быстро проверить/починить.
-
Неправильный dest (unix‑сокет указан, но nginx не слушает там или путь недоступен)
- Симптомы: в логах ноды — строки типа “dial: неизвестная сеть” / “connection refused” / “failed to connect to dest”.
- Почему: если Xray пытается переслать не‑VLESS трафик на /dev/shm/nginx.sock, а nginx не создал этот сокет или контейнер ноды его не видит — TLS рукопожатие сорвётся.
- Быстрая проверка:
ss -xl | grep nginx.sockиls -l /dev/shm/nginx.sock. - Подсказка и примеры в обсуждении Xray: https://github.com/XTLS/Xray-core/discussions/3518
-
Неправильное использование proxy_protocol в nginx (ожидание PROXY header)
- Симптомы: nginx сразу падает/логирует ошибки SSL или видит мусор вместо PROXY header; соединение разрывается в момент ClientHello.
- Почему:
listen ... proxy_protocol;заставляет nginx ждать PROXY header. Xray в режиме fallback обычно не посылает PROXY header, поэтому nginx примет первые байты TLS как некорректный PROXY. - Что проверить: конфиг nginx (строка
listen 7443 ssl proxy_protocol;) и связанныеreal_ip_header proxy_protocol. Пример и разбор: https://mmote.ru/xray-website-one-port/ и руководство по туннелю Nginx/Haproxy: https://xtls.github.io/ru/document/level-2/nginx_or_haproxy_tls_tunnel.html
-
Несовпадение serverNames (SNI) и/или сертификата на nginx
- Симптомы: openssl выводит другое имя в cert / “certificate verify failed” или быстро закрыто соединение.
- Почему: в realitySettings.serverNames должен быть домен, который клиент использует в SNI и который покрыт сертификатом nginx; иначе рукопожатие может отвергаться.
- Проверка:
openssl s_client -connect <IP>:443 -servername nld-x8.plugvpn.ru -tls1_3и просмотр SAN в cert.
-
Несовпадение privateKey / shortIds между клиентом и сервером
- Симптомы: в логах Xray — ошибки Reality handshake / rejected proxy/vless/encoding.
- Почему: Reality требует точного соответствия privateKey и shortIds для успешного рукопожатия.
- Проверка: сверьте значения в конфиге ноды и в конфиге, который генерирует панель/клиент. См. обсуждение XTLS: https://github.com/XTLS/Xray-core/discussions/3518
-
/dev/shm не смонтирован в контейнер ноды или права сокета неверные
- Симптомы: socket отсутствует в контейнере, permission denied, connection refused.
- Проверка в Docker:
docker inspect <node_container> --format '{{json .Mounts}}'иls -l /dev/shm/nginx.sockвнутри контейнера. Репозитории и сборки Remnawave указывают на необходимость монтирования /dev/shm: https://github.com/legiz-ru/my-remnawave и скрипт eGames: https://github.com/eGamesAPI/remnawave-reverse-proxy/blob/main/README-RU.md
-
Nginx не собран/не настроен с модулем stream или неверный upstream
- Симптомы: nginx не может проксировать unix socket или ошибки в
nginx -T. - Проверка:
nginx -V(есть ли stream/ssl_preread),nginx -Tи лог ошибок.
- Симптомы: nginx не может проксировать unix socket или ошибки в
-
Несовместимые TLS версии / наборы шифров / fingerprint (uTLS) / блокировки DPI
- Симптомы: рукопожатие зависает на mobile networks, но работает из других сетей; в логах — тайм-ауты или abrupt resets.
- Что делать: проверить TLS 1.3 поддержка в nginx и настройки клиента; попробовать fingerprint “chrome” / ALPN h2, либо использовать Cloudflare Tunnel как workaround. Сообщества обсуждали проблемы с мобильными DPI: https://www.reddit.com/r/VPN/comments/1ogn5cs/vlessreality_works_on_wifi_stalls_on_russian/?tl=ru и подбор обходных путей: https://ntc.party/t/.../16061
-
Неправильный xver / устаревший формат Reality
- Симптомы: handshake завершается на этапе версии при чтении запроса.
- Проверка: сверить
xverмежду клиентом и сервером (0/1) и при необходимости привести в соответствие; Xray fallback docs: https://xtls.github.io/ru/config/features/fallback.html
Что проверить: логи и команды (панель, нода, nginx)
Разделю по местам — что смотреть и какие команды дать для вывода подробностей.
Панель (Remnawave)
- Список контейнеров / сервисов:
docker ps --format "{{.Names}}\t{{.Image}}\t{{.Status}}" - Логи панели (если в Docker):
docker logs -f <remnawave_panel_container> - Убедитесь, что панель отдала ноде актуальный конфиг (в UI/экспорте). Репозиторий панели: https://github.com/remnawave/panel
Нода (Xray в ноде)
- Если systemd:
systemctl status xrayиjournalctl -u xray -f --no-pager - Для поиска ошибок:
journalctl -u xray --since "10 minutes ago" | grep -Ei "handshake|reality|rejected|failed|dial|proxy"- Или, если контейнер:
docker logs -f <remnawave_node_container>
- Проверить валидность конфига:
xray -test -c /etc/xray/config.json(в контейнере —docker exec -it <container> xray -test -c /etc/xray/config.json) - Включите временно debug‑лог: в config.json поставить
"log": {"loglevel": "debug"}и перезагрузить сервис, собрать логи при попытке подключения.
Nginx (stream / ssl)
- Тест конфигурации:
nginx -t - Полный дамп конфига:
nginx -T(скопируйте блок stream) - Логи ошибок/доступа:
tail -n 200 /var/log/nginx/error.logиtail -n 200 /var/log/nginx/access.log - Проверить, слушает ли unix socket:
ss -xl | grep nginx.sockилиlsof -U | grep nginx.sock - Проверить, используется ли proxy_protocol: ищите
proxy_protocolв выводеnginx -T - Если nginx слушает на unix‑сокете — вывести права:
ls -l /dev/shm/nginx.sockиstat /dev/shm/nginx.sock
Сетевые/пакетные тесты и проверка TLS
- Кто слушает 443 на ноде:
ss -ltnp | grep :443 - Проверка TLS к nginx через unix socket (удобно для воспроизведения):
- открыть локальный TCP порт, пробросив unix -> tcp:
socat TCP-LISTEN:8444,reuseaddr,fork UNIX-CONNECT:/dev/shm/nginx.sock & - подключиться openssl:
openssl s_client -connect 127.0.0.1:8444 -servername nld-x8.plugvpn.ru -tls1_3
- Результат покажет цепочку сертификатов и ошибку рукопожатия, если есть.
- открыть локальный TCP порт, пробросив unix -> tcp:
- Проба напрямую к Xray (если он слушает 443):
openssl s_client -connect 127.0.0.1:443 -servername nld-x8.plugvpn.ru -tls1_3 -msg - Проверка сертификата:
openssl x509 -in /path/to/fullchain.pem -noout -textилиcurl -vk --resolve nld-x8.plugvpn.ru:443:<NODE_IP> https://nld-x8.plugvpn.ru/
Утилиты для контейнеров
- Проверить, что /dev/shm примонтирован:
docker inspect <node_container> --format '{{json .Mounts}}' - Если контейнер запускается с
network_mode: host, это упрощает проверку сокета/портов.
Какие фразы в логах важны
- “rejected proxy/vless/encoding: failed to read request version” — указывает на проблему с dest/proxy_protocol.
- “reality: handshake failed” / “failed to read request version” — совпадение privateKey/shortIds, SNI или TLS mismatch.
- “dial: unknown network” — dest указан неверно (например, указали unix socket в месте, где ожидается host:port).
Полезные ссылки с примерами nginx/Xray конфигураций: https://xtls.github.io/ru/config/features/fallback.html и разбор режимов Nginx+Xray: https://henrywithu.com/coexisting-xray-vless-tcp-xtls-vision-and-vless-xhttp-reality-on-a-single-port/
Типовые правки reality/streamSettings и nginx для устранения ошибки TLS
Ниже — практические изменения, которые чаще всего решают проблему в конфигурации, похожей на вашу.
- Быстрая замена unix‑сокета на loopback TCP (самая простая отладка)
- Почему: легче тестировать — openssl/curl могут подключаться напрямую.
- В Xray (realitySettings): замените
“dest”: “/dev/shm/nginx.sock”
на
“dest”: “127.0.0.1:8443” - В nginx — слушайте 127.0.0.1:8443 для того сайта. После этого:
nginx -t && nginx -s reloadи тест черезopenssl s_client -connect 127.0.0.1:8443 -servername nld-x8.plugvpn.ru -tls1_3. Если заработало — проблема была в сокете/праве/монтировании.
- Если хотите оставить unix socket — убедитесь в двух вещах: nginx действительно создаёт сокет по этому пути, и контейнер ноды видит этот путь.
- В Docker‑Compose:
volumes: - /dev/shm:/dev/shmи/илиnetwork_mode: host(если допустимо). Пример: https://github.com/legiz-ru/my-remnawave - Проверьте права:
chown nginx:nginx /dev/shm/nginx.sock/chmod 660 /dev/shm/nginx.sock(или 666 для отладки)
- Уберите proxy_protocol, если upstream (Xray) не отправляет PROXY header
- В
nginx -Tнайдитеlisten ... proxy_protocol;и временно уберитеproxy_protocol. Если вы используете HAProxy/Cloudflare, только тогда нужен proxy_protocol и соответствующая настройка передачи — иначе nginx будет ломать TLS. Сравнение и примеры: https://mmote.ru/xray-website-one-port/ и https://xtls.github.io/ru/document/level-2/nginx_or_haproxy_tls_tunnel.html
- Проверьте serverNames и сертификат
- В realitySettings.serverNames должен быть домен, который клиент использует в SNI и который покрыт сертификатом на nginx. Если не совпадает — рукопожатие может не пройти. Протестируйте:
openssl s_client -connect <NODE_IP>:443 -servername nld-x8.plugvpn.ru -tls1_3 - Если вы маскируете под сайт, используйте корректный cert (Let’s Encrypt или selfsigned с доверенным цепочками для теста).
- Синхронизируйте privateKey и shortIds; проверьте xver
- Если панель генерирует ключи, убедитесь, что нода получила те же значения (в конфиге ноды). При сомнении — пересоздайте/пересинхронизируйте их через панель. См. обсуждение Xray: https://github.com/XTLS/Xray-core/discussions/3518
- TLS‑параметры (TLS1.3, ALPN, ciphers, fingerprint)
- Убедитесь, что nginx поддерживает TLS1.3 и набор шифров, ожидаемых клиентом. В некоторых случаях полезно подстроить fingerprint/ALPN в клиенте/сервере (примеры настроек встречаются в обсуждениях и примерах конфигов). Xray/XTLS‑доки по транспорту: https://xtls.github.io/ru/config/transport.html
- Временно увеличить уровень логирования Xray для диагностики
- В config.json:
"log": {"loglevel": "debug"}→ перезагрузить и воспроизвести ошибку, собрать логи. Не забудьте вернуть loglevel в warning/info после диагностики.
- Если мобильные сети/провайдеры блокируют — временный обход через туннель (Cloudflare Tunnel)
- Это частое решение при DPI‑проблемах; инструкция по Cloudflare Tunnel в контексте Remnawave: https://neonode.cc/ru/blog/remnawave-cloudflare-tunnel-docker-compose-guide/
Пример безопасной правки realitySettings (используйте свои значения):
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"dest": "127.0.0.1:8443",
"show": false,
"xver": 1,
"shortIds": ["771f08d36893f672"],
"privateKey": "OlGPEQCucgCOhFO26T-owAK1BLSrF-NEwq8PwFS8j1Y",
"serverNames": ["nld-x8.plugvpn.ru"]
}
}
Пример минимального streaming‑блока nginx (олига для идеи; адаптируйте под вашу сборку):
stream {
map $ssl_preread_server_name $backend {
nld-x8.plugvpn.ru web_backend;
default xray_backend;
}
upstream web_backend {
server 127.0.0.1:8443;
}
server {
listen 127.0.0.1:8443;
proxy_pass web_backend;
ssl_preread on;
}
}
(если используете unix socket — замените server 127.0.0.1:8443; на server unix:/dev/shm/nginx.sock;, но проверьте поддержку в вашей сборке nginx)
Пошаговые тесты и команды (socat / openssl / curl)
Шаги для быстрого воспроизведения и локализации:
- Получите отметку времени ошибки на клиенте (время попытки подключения).
- На ноде соберите Xray‑логи в период ошибки:
journalctl -u xray --since "YYYY-MM-DD HH:MM:SS" --until "YYYY-MM-DD HH:MM:SS" > /tmp/xray.log - Проверка сокета и прав:
ls -l /dev/shm/nginx.sock
ss -xl | grep nginx.sock - Если сокет есть — пробросите его на TCP и запустите openssl:
socat TCP-LISTEN:8444,reuseaddr,fork UNIX-CONNECT:/dev/shm/nginx.sock &
openssl s_client -connect 127.0.0.1:8444 -servername nld-x8.plugvpn.ru -tls1_3- Смотрите: рукопожатие, цепочку сертификатов, ошибки VERIFY/handshake.
- Если сокета нет, попробуйте временно сменить dest на 127.0.0.1:8443 и сконфигурировать nginx слушать этот порт; затем:
openssl s_client -connect 127.0.0.1:8443 -servername nld-x8.plugvpn.ru -tls1_3 - Сопоставьте метки времени: если openssl успешно, но Xray пишет handshake failed — вероятно privateKey/shortIds/SNI mismatch.
- Снимки логов nginx в момент ошибки:
tail -n 200 /var/log/nginx/error.log— ищите SSL/PROXY errors. - Если проблема воспроизводится только из одной сети (например, мобильной), выполните тесты из другой сети или через Cloudflare Tunnel.
Какие данные и логи приложить для точной диагностики
Чтобы быстро получить корректный совет, приложите (обязательно — с редактированием секретных ключей: privateKey/UUID/ части shortIds можно замаскировать, но укажите структуру):
- Вырезка inbound блока конфигурации ноды (config.json) — особенно
streamSettings.realitySettings(замаскируйте privateKey и первую/последнюю части UUID при публикации). - Вывод
nginx -T(или файл stream конфигурации), где показан upstream/перенаправление на /dev/shm/nginx.sock или 127.0.0.1:8443. - Логи Xray вокруг времени ошибки:
journalctl -u xray --since "..." --no-pager | tail -n 200илиdocker logs -t <node_container> --since .... - Логи nginx:
tail -n 200 /var/log/nginx/error.logс тем же временным окном. - Результат теста openssl/socat: вывод команды
openssl s_client -connect 127.0.0.1:8444 -servername nld-x8.plugvpn.ru -tls1_3. - Вывод
ss -xlиls -l /dev/shm/nginx.sockи, если Docker,docker inspect <container> --format '{{json .Mounts}}'. - Укажите, работает ли подключение из других сетей (Wi‑Fi/другая сеть) — это указывает на DPI/провайдера.
- Если публикуете конфиги — замените реальные privateKey/shortIds/UUID на
<REDACTED>и укажите их длину/формат.
Пример тела запроса техподдержке (что вставить):
- Время (UTC) попытки: 2025-12-27 12:02:34
- Входящий блок config.json (realitySettings) — privateKey:
<REDACTED>shortIds:["771f...672"] - Вывод
openssl s_client— прикреплённый файл/логи - nginx -T — прикреплённый фрагмент stream{}
- Ошибка из Xray: точная строка/скриншот журнала
Источники
- https://github.com/XTLS/Xray-core/discussions/3518
- https://xtls.github.io/ru/document/level-2/nginx_or_haproxy_tls_tunnel.html
- https://mmote.ru/xray-website-one-port/
- https://xtls.github.io/ru/config/features/fallback.html
- https://henrywithu.com/coexisting-xray-vless-tcp-xtls-vision-and-vless-xhttp-reality-on-a-single-port/
- https://github.com/legiz-ru/my-remnawave
- https://github.com/eGamesAPI/remnawave-reverse-proxy/blob/main/README-RU.md
- https://docs.rw/docs/learn/server-routing/
- https://www.reddit.com/r/VPN/comments/1ogn5cs/vlessreality_works_on_wifi_stalls_on_russian/?tl=ru
- https://ntc.party/t/блокировка-vless-xtls-rprx-vision-reality-в-россии-нет-частичная-блокировка-tls/16061?page=20
- https://neonode.cc/ru/blog/remnawave-cloudflare-tunnel-docker-compose-guide/
Заключение
Коротко: при вашей конфигурации vless + reality чаще всего виноваты путь dest (unix‑сокет vs tcp), proxy_protocol в nginx и рассинхрон ключей/SNI. Первые шаги — проверить наличие и права /dev/shm/nginx.sock, убрать/проверить proxy_protocol, временно переключить dest на 127.0.0.1:8443 и запустить openssl/socat‑тесты; если проблема остаётся — включите debug‑лог Xray и пришлите выдержки из журналов и блок stream{} из nginx. После этих данных можно дать точечный фикс.