DevOps

Ошибка TLS рукопожатия в Remnawave VLESS Reality: как исправить

Подробное руководство по диагностике и устранению ошибки TLS рукопожатия в Remnawave при подключении внешней ноды с VLESS + Reality. Проверяем конфигурацию Xray, Nginx, логи и типовые правки для стабильного соединения.

Как исправить ошибку TLS рукопожатия в Remnawave при подключении к хосту через внешнюю ноду?

Описание:

  • Установил панель с локальной нодой и установил внешнюю ноду через скрипт eGames.
  • При подключении к хосту с внешней ноды появляется ошибка TLS рукопожатия.
  • Панель подключается к ноде и отдает ей команды.

Конфигурация ядра:

json
{
  "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"
      }
    ]
  }
}

Вопросы:

  1. Какие наиболее вероятные причины ошибки TLS рукопожатия в этой конфигурации (vless + reality, использование сокета /dev/shm/nginx.sock, параметры realitySettings)?
  2. Какие логи и команды проверить на панели, на ноде и в nginx для диагностики?
  3. Какие настройки reality/streamSettings или nginx чаще всего нужно менять для устранения TLS-ошибок?
  4. Какие дополнительные данные логов/конфигов нужно предоставить для точной диагностики?

Ошибка 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 нода

Ниже — наиболее правдоподобные причины в порядке частоты и простоты проверки, что каждая значит и как быстро проверить/починить.

  1. Неправильный 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
  2. Неправильное использование 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
  3. Несовпадение 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.
  4. Несовпадение privateKey / shortIds между клиентом и сервером

    • Симптомы: в логах Xray — ошибки Reality handshake / rejected proxy/vless/encoding.
    • Почему: Reality требует точного соответствия privateKey и shortIds для успешного рукопожатия.
    • Проверка: сверьте значения в конфиге ноды и в конфиге, который генерирует панель/клиент. См. обсуждение XTLS: https://github.com/XTLS/Xray-core/discussions/3518
  5. /dev/shm не смонтирован в контейнер ноды или права сокета неверные

  6. Nginx не собран/не настроен с модулем stream или неверный upstream

    • Симптомы: nginx не может проксировать unix socket или ошибки в nginx -T.
    • Проверка: nginx -V (есть ли stream/ssl_preread), nginx -T и лог ошибок.
  7. Несовместимые 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
  8. Неправильный 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 (удобно для воспроизведения):
    1. открыть локальный TCP порт, пробросив unix -> tcp:
      socat TCP-LISTEN:8444,reuseaddr,fork UNIX-CONNECT:/dev/shm/nginx.sock &
    2. подключиться openssl:
      openssl s_client -connect 127.0.0.1:8444 -servername nld-x8.plugvpn.ru -tls1_3
    • Результат покажет цепочку сертификатов и ошибку рукопожатия, если есть.
  • Проба напрямую к 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

Ниже — практические изменения, которые чаще всего решают проблему в конфигурации, похожей на вашу.

  1. Быстрая замена 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. Если заработало — проблема была в сокете/праве/монтировании.
  1. Если хотите оставить 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 для отладки)
  1. Уберите proxy_protocol, если upstream (Xray) не отправляет PROXY header
  1. Проверьте serverNames и сертификат
  • В realitySettings.serverNames должен быть домен, который клиент использует в SNI и который покрыт сертификатом на nginx. Если не совпадает — рукопожатие может не пройти. Протестируйте:
    openssl s_client -connect <NODE_IP>:443 -servername nld-x8.plugvpn.ru -tls1_3
  • Если вы маскируете под сайт, используйте корректный cert (Let’s Encrypt или selfsigned с доверенным цепочками для теста).
  1. Синхронизируйте privateKey и shortIds; проверьте xver
  • Если панель генерирует ключи, убедитесь, что нода получила те же значения (в конфиге ноды). При сомнении — пересоздайте/пересинхронизируйте их через панель. См. обсуждение Xray: https://github.com/XTLS/Xray-core/discussions/3518
  1. TLS‑параметры (TLS1.3, ALPN, ciphers, fingerprint)
  • Убедитесь, что nginx поддерживает TLS1.3 и набор шифров, ожидаемых клиентом. В некоторых случаях полезно подстроить fingerprint/ALPN в клиенте/сервере (примеры настроек встречаются в обсуждениях и примерах конфигов). Xray/XTLS‑доки по транспорту: https://xtls.github.io/ru/config/transport.html
  1. Временно увеличить уровень логирования Xray для диагностики
  • В config.json: "log": {"loglevel": "debug"} → перезагрузить и воспроизвести ошибку, собрать логи. Не забудьте вернуть loglevel в warning/info после диагностики.
  1. Если мобильные сети/провайдеры блокируют — временный обход через туннель (Cloudflare Tunnel)

Пример безопасной правки realitySettings (используйте свои значения):

json
"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 (олига для идеи; адаптируйте под вашу сборку):

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)

Шаги для быстрого воспроизведения и локализации:

  1. Получите отметку времени ошибки на клиенте (время попытки подключения).
  2. На ноде соберите Xray‑логи в период ошибки:
    journalctl -u xray --since "YYYY-MM-DD HH:MM:SS" --until "YYYY-MM-DD HH:MM:SS" > /tmp/xray.log
  3. Проверка сокета и прав:
    ls -l /dev/shm/nginx.sock
    ss -xl | grep nginx.sock
  4. Если сокет есть — пробросите его на 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.
  5. Если сокета нет, попробуйте временно сменить dest на 127.0.0.1:8443 и сконфигурировать nginx слушать этот порт; затем:
    openssl s_client -connect 127.0.0.1:8443 -servername nld-x8.plugvpn.ru -tls1_3
  6. Сопоставьте метки времени: если openssl успешно, но Xray пишет handshake failed — вероятно privateKey/shortIds/SNI mismatch.
  7. Снимки логов nginx в момент ошибки: tail -n 200 /var/log/nginx/error.log — ищите SSL/PROXY errors.
  8. Если проблема воспроизводится только из одной сети (например, мобильной), выполните тесты из другой сети или через Cloudflare Tunnel.

Какие данные и логи приложить для точной диагностики

Чтобы быстро получить корректный совет, приложите (обязательно — с редактированием секретных ключей: privateKey/UUID/ части shortIds можно замаскировать, но укажите структуру):

  1. Вырезка inbound блока конфигурации ноды (config.json) — особенно streamSettings.realitySettings (замаскируйте privateKey и первую/последнюю части UUID при публикации).
  2. Вывод nginx -T (или файл stream конфигурации), где показан upstream/перенаправление на /dev/shm/nginx.sock или 127.0.0.1:8443.
  3. Логи Xray вокруг времени ошибки: journalctl -u xray --since "..." --no-pager | tail -n 200 или docker logs -t <node_container> --since ....
  4. Логи nginx: tail -n 200 /var/log/nginx/error.log с тем же временным окном.
  5. Результат теста openssl/socat: вывод команды openssl s_client -connect 127.0.0.1:8444 -servername nld-x8.plugvpn.ru -tls1_3.
  6. Вывод ss -xl и ls -l /dev/shm/nginx.sock и, если Docker, docker inspect <container> --format '{{json .Mounts}}'.
  7. Укажите, работает ли подключение из других сетей (Wi‑Fi/другая сеть) — это указывает на DPI/провайдера.
  8. Если публикуете конфиги — замените реальные 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: точная строка/скриншот журнала

Источники

Заключение

Коротко: при вашей конфигурации 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. После этих данных можно дать точечный фикс.

Авторы
Проверено модерацией
Модерация