Перейти к содержанию

Hysteria Realms

Hysteria Realms — это P2P-режим, позволяющий запускать сервер Hysteria без публичного IP-адреса и проброса портов. Небольшой сервис рандеву (rendezvous) знакомит сервер и клиент друг с другом, после чего они выполняют пробивание UDP-отверстия (UDP hole punching), чтобы установить прямое QUIC-соединение. Когда отверстие открыто, рандеву выходит из игры — весь трафик идёт напрямую между клиентом и сервером.

Когда это полезно?

  • Хостинг из домашней сети за NAT.
  • Хостинг из кафе, отеля или мобильной точки доступа, где у вас нет контроля над маршрутизатором.
  • Быстрые эксперименты, когда выделять VPS с открытым портом — избыточно.
  • Любая среда за CGNAT, где входящий порт получить вообще невозможно.

Вам всё ещё нужен рабочий исходящий UDP-канал к рандеву и к сети вашего пира — что разрешает практически любой NAT.

Как это работает

  1. Сервер Hysteria регистрирует realm (имя на ваш выбор) в сервисе рандеву, сообщая UDP-адреса, обнаруженные через STUN.
  2. Клиент с тем же realm-адресом просит рандеву установить соединение. Рандеву возвращает клиенту адреса сервера и пушит серверу адреса клиента.
  3. Обе стороны одновременно отправляют UDP-пакеты друг другу, пробивая отверстия в своих NAT.
  4. Как только отверстие открыто, обычное QUIC-рукопожатие Hysteria продолжается по прямому соединению.

Рандеву только посредничает в знакомстве. Оно не передаёт никакого трафика.

Realm-адрес

Клиент и сервер идентифицируют realm одним URI:

realm://<token>@<rendezvous-host>[:port]/<realm-name>
  • realm:// — использует HTTPS для общения с рандеву (порт по умолчанию 443). Рекомендуется.
  • realm+http:// — использует обычный HTTP (порт по умолчанию 80). Только для разработки.
  • <token> — общий bearer-токен сервера рандеву.
  • <realm-name> — выбранное вами имя realm. Клиент и сервер должны использовать одинаковое.

Пример: realm://[email protected]/my-server

URL также поддерживает несколько необязательных параметров запроса:

  • stun=<host:port> — переопределяет используемые STUN-серверы. Повторите параметр для нескольких серверов (например, ?stun=stun1.example.com:3478&stun=stun2.example.com:3478). Если задан, имеет приоритет над realm.stunServers в YAML-конфигурации.
  • lport=<1-65535> — привязывает локальный UDP-сокет к указанному исходящему порту. Полезно для проброса через файрвол или получения более предсказуемого NAT-маппинга. По умолчанию используется эфемерный порт.

Выбор сервера рандеву

Вы можете использовать публичный рандеву или развернуть свой собственный.

Публичный рандеву (realm.hy2.io)

Проект Hysteria держит публичный рандеву по адресу realm.hy2.io с токеном public:

realm://[email protected]/<your-realm-name>

Без гарантий. Это бесплатный сервис «как получится». Он может упасть, изменить лимиты, оказаться заблокированным или исчезнуть без предупреждения. Не полагайтесь на него ни для чего важного.

Все realm’ы запускаются пользователями. Проект Hysteria не управляет, не одобряет и не проверяет ни один прокси-сервер, зарегистрированный на realm.hy2.io, и никогда не будет. Любой может зарегистрировать realm с любым именем. Подключайтесь только к realm’ам, оператору которых вы доверяете. Чужой realm может логировать ваш трафик, провести MITM-атаку или просто оказаться приманкой. Относитесь к любому realm-имени, которое вы не настраивали сами, с тем же скептицизмом, что и к случайному VPN-провайдеру.

Поскольку токен общий, любой, кто знает или угадает имя вашего realm, может узнать IP-адрес вашего сервера. Использовать ваш прокси они не смогут (собственная аутентификация Hysteria продолжит работать), но узнают, где вы. Чтобы угадать было нереально:

  • Выбирайте длинное случайное имя realm — относитесь к нему как к секрету. Что-то вроде my-cabin-1f3a8c2e9b гораздо труднее угадать, чем home.
  • Не используйте имена, которые могут вас идентифицировать (логин, имя хоста и т.п.).

Если что-то из этого важно — разверните собственный рандеву.

Текущие ограничения

Имя realm должно быть длиной от 6 до 64 символов, начинаться с буквы или цифры и содержать только буквы, цифры, - или _. С одного клиентского IP можно держать активными не более 2 realm одновременно. Эти ограничения могут меняться без уведомления; если вам нужны другие — поднимайте свой рандеву.

Самостоятельный хостинг

Сервер рандеву открыт и легко разворачивается: https://github.com/apernet/hysteria-realm-server

Для любого продакшена правильный выбор — собственный экземпляр со своим закрытым токеном:

  • Только клиенты и серверы, знающие токен, могут регистрироваться и подключаться.
  • Вы контролируете аптайм, лимиты и логирование.
  • Объём памяти небольшой (несколько КиБ на realm).

Описание установки и развёртывания см. в README проекта.

Конфигурация сервера

Чтобы запустить сервер Hysteria в realm-режиме, укажите в listen realm-URI. Сервер подключится к рандеву по исходящему TCP, зарегистрирует realm и будет ждать подключений — входящий порт не нужен.

listen: realm://[email protected]/your-realm-name

Все остальные поля сервера (auth, tls, obfs, bandwidth и т.п.) остаются прежними. Параметры тонкой настройки STUN, пробивания и пинга описаны в Полной конфигурации сервера.

Если вас беспокоит DPI-цензура, включите obfs. В realm-режиме сервер слушает на случайном UDP-порте, а не на 443, и сам по себе HTTP/3-трафик на нестандартном порте может быть сигналом для детекторов.

Конфигурация клиента

Установите в server тот же realm-URI, который зарегистрировал сервер:

server: realm://[email protected]/your-realm-name
auth: your-hysteria-password

Все остальные поля клиента работают как обычно. Параметры тонкой настройки STUN и пробивания описаны в Полной конфигурации клиента.

Клиент выполняет STUN-обнаружение, просит рандеву представить его серверу, пробивает соединение и затем продолжает обычное QUIC-рукопожатие Hysteria — включая проверку TLS и пароль. Realm-токен не заменяет пароль вашего сервера Hysteria.

TLS

В realm-режиме у клиента нет DNS-имени, по которому он мог бы проверить сертификат сервера — он соединяется с тем IP, который вернул рандеву. Без настройки клиент использует имя хоста рандеву как SNI, что обычно не совпадает с обычным сертификатом. Есть три варианта:

1. Самоподписанный сертификат с pinSHA256. Запустите hysteria cert на сервере — она сгенерирует ключ и сертификат и распечатает готовые блоки tls для server.yaml (cert/key) и client.yaml (insecure: true + pinSHA256). Pin гарантирует, что клиент примет только этот конкретный сертификат, поэтому SNI и проверка CA уже не важны.

2. Реальный CA-сертификат + переопределение tls.sni. Получите сертификат через DNS-01 ACME для домена, которым вы владеете (HTTP-01 / TLS-ALPN-01 без публичного IP не сработают), используйте его на сервере и установите tls.sni на клиенте равным этому домену.

3. Сертификат на имя хоста рандеву. Применимо, только если вы поднимаете и рандеву, и сервер сами — выпустите сертификат сервера Hysteria на то же имя хоста, что у рандеву. Тогда клиентский SNI по умолчанию совпадёт без каких-либо переопределений.

Совместимость с NAT

UDP-пробивание работает на большинстве домашних и мобильных сетей, но не на всех.

Тип NAT с любой стороны Работает?
Публичный IP, без NAT (типичный VPS с открытым портом) Да
Full cone / endpoint-independent («открытый») Да
Restricted cone, port-restricted cone («умеренный») Да
Симметричный («строгий») Иногда

Для симметричных NAT мы применяем несколько приёмов, которые во многих реальных случаях помогают пробиться, но гарантий нет. Если симметричный NAT с обеих сторон, шансы падают ещё сильнее.

Некоторые реализации carrier-grade NAT (CGNAT) ведут себя как симметричный NAT и работают нестабильно. Если Realms у вас не работает, наиболее вероятная причина — симметричный NAT хотя бы с одной стороны. В этом случае возвращайтесь к серверу с публичным IP.

STUN-серверы

И серверу, и клиенту нужен STUN, чтобы обнаружить свои публичные UDP-адреса прежде, чем рандеву сможет познакомить их друг с другом. Если вы ничего не настраиваете, Hysteria использует небольшой встроенный список публичных STUN-серверов:

  • stun.nextcloud.com:3478
  • stun.sip.us:3478
  • global.stun.twilio.com:3478

Эти серверы держат третьи стороны и предоставляют их как любезность. Они могут упасть, ограничивать частоту запросов или оказаться заблокированными в вашей сети. Для чего-то большего, чем разовые эксперименты, укажите Hysteria собственные (или доверенные) STUN-серверы через realm.stunServers на сервере и realm.stunServers на клиенте.

Сообщения о проблемах с подключением

В Realms задействовано несколько подсистем (STUN, рандеву, UDP-пробивание, TLS, QUIC-рукопожатие), поэтому отчёт «не подключается» без трассировки практически нечем обработать. Если вы оформляете issue, запустите и клиент, и сервер с HYSTERIA_LOG_LEVEL=debug и приложите полный вывод с обеих сторон:

HYSTERIA_LOG_LEVEL=debug ./hysteria server -c server.yaml
HYSTERIA_LOG_LEVEL=debug ./hysteria client -c client.yaml

Для других протоколов

По сути Realms — это универсальный фреймворк UDP-пробивания: протокол рандеву, STUN-обнаружение и логика пробивания не зависят от Hysteria. Hysteria — просто его первый пользователь.

И сервер рандеву, и клиентская/серверная библиотека пробивания выпущены под свободными лицензиями. Авторов других UDP-инструментов и протоколов мы приглашаем интегрировать тот же протокол, чтобы любой совместимый клиент мог достучаться до любого совместимого сервера через любой совместимый рандеву — мы хотели бы, чтобы это стало небольшим де-факто стандартом. PR, issue и вопросы по интеграции приветствуются на GitHub.