Some checks failed
Published content check / validate (push) Failing after 3s
Обновить правила репозитория и подписи исходников в 99 заметках, не затрагивая пользовательские незакоммиченные файлы. Сделать Forgejo Actions содержательным: проверять опубликованный commit, а не пустое рабочее дерево после checkout.
118 lines
14 KiB
Markdown
118 lines
14 KiB
Markdown
---
|
||
date: 2026-07-11
|
||
tags:
|
||
- hysteria
|
||
- realms
|
||
- nat
|
||
- p2p
|
||
- hole-punching
|
||
aliases:
|
||
- Hysteria Realms
|
||
- Hysteria за NAT
|
||
- Hysteria без белого IP
|
||
- Hysteria P2P
|
||
link: https://v2.hysteria.network/docs/advanced/Realms/
|
||
---
|
||
|
||
# 🦎 Hysteria 2 — Realms: сервер за NAT без белого IP
|
||
|
||
> [!info] О чём заметка
|
||
> Как поднять сервер Hysteria 2 **без публичного IP и проброса портов** — из дома, из-за CGNAT, с мобильного модема — с помощью режима Hysteria Realms (P2P через UDP hole punching). Базовые конфиги — в заметках [[Hysteria/config-server|сервер]] и [[Hysteria/config-client|клиент]]. Обзор протокола — [[Hysteria/00-overview|тут]].
|
||
|
||
## TL;DR
|
||
|
||
- **Realms** — P2P-режим: маленький сервис-посредник (rendezvous) «знакомит» сервер и клиент, после чего они пробивают NAT (UDP hole punching) и соединяются **напрямую**. Посредник трафик не передаёт — только сводит стороны.
|
||
- Нужен для хостинга **без белого IP**: из домашней сети за NAT, из-за CGNAT, с хотспота/модема, где нет входящего порта.
|
||
- И сервер, и клиент используют один URI вида `realm://<токен>@<rendezvous-host>/<имя-realm>`. На сервере он ставится в `listen`, на клиенте — в `server`.
|
||
- Есть публичный посредник `realm.hy2.io` с токеном `public` (без гарантий), но для чего-то серьёзного лучше **поднять свой** rendezvous.
|
||
- **Токен realm ≠ пароль Hysteria.** Аутентификация и TLS работают как обычно — токен лишь для знакомства через посредник.
|
||
- Работает не при любом NAT: если хотя бы с одной стороны **симметричный NAT со случайными портами** — hole punching обычно не удаётся, нужен обычный сервер с белым IP.
|
||
|
||
## Зачем это нужно и как работает
|
||
|
||
Обычный сервер Hysteria требует публичный IP и открытый порт — см. [[Hysteria/install-server|установку сервера]]. Но что если сервер хочется поднять дома, а провайдер не даёт белый IP (или вы за CGNAT — общим IP на много абонентов, где входящее соединение в принципе невозможно)? Тут помогает Realms.
|
||
|
||
Идея (UDP hole punching простыми словами): две машины за NAT не могут «дозвониться» друг другу напрямую, потому что NAT не пропускает входящие пакеты. Но если обе одновременно начнут слать пакеты навстречу, каждый NAT решит, что это ответ на исходящее соединение, и пропустит — «дырка» пробита. Проблема лишь в том, что стороны не знают адресов друг друга. Эту роль играет **rendezvous** — общедоступный посредник: сервер регистрирует у него «realm» (имя, которое вы придумали) со своими адресами (узнаёт их через STUN), а клиент запрашивает у посредника адреса сервера. Дальше — hole punching и обычное QUIC-рукопожатие Hysteria напрямую.
|
||
|
||
> [!important] Посредник не видит ваш трафик
|
||
> Rendezvous участвует только в момент знакомства — сводит адреса сервера и клиента. Как только «дырка» в NAT пробита, весь трафик идёт **напрямую** между клиентом и сервером, посредник в нём не участвует и ничего не ретранслирует.
|
||
|
||
## Адрес realm
|
||
|
||
Обе стороны используют один URI:
|
||
|
||
```
|
||
realm://<токен>@<rendezvous-host>[:port]/<имя-realm>
|
||
```
|
||
|
||
- `realm://` — общение с посредником по HTTPS (порт 443 по умолчанию). **Рекомендуется.**
|
||
- `realm+http://` — по обычному HTTP (порт 80). Только для разработки.
|
||
- `<токен>` — общий bearer-токен посредника.
|
||
- `<имя-realm>` — имя, которое вы выбрали. На сервере и клиенте оно **должно совпадать**.
|
||
|
||
Пример: `realm://mytoken@rendezvous.example.com/my-server`.
|
||
|
||
## Конфиг сервера
|
||
|
||
Чтобы запустить сервер в режиме realm, поставьте realm-URI в `listen`. Сервер сам сходит к посреднику по исходящему соединению, зарегистрирует realm и будет ждать подключений — входящий порт не нужен.
|
||
|
||
```yaml
|
||
listen: realm://public@realm.hy2.io/your-realm-name
|
||
```
|
||
|
||
Все прочие поля сервера (`auth`, `tls`, `obfs`, `bandwidth`) работают как обычно — см. [[Hysteria/config-server|серверный конфиг]].
|
||
|
||
> [!warning] В режиме realm включайте обфускацию против DPI
|
||
> В realm-режиме сервер слушает на **случайном UDP-порту**, а не на 443. HTTP/3-трафик на нестандартном порту сам по себе может быть сигналом для DPI. Если цензура — забота, включите [[Hysteria/obfs-port-hopping|обфускацию (obfs)]], чтобы спрятать почерк QUIC.
|
||
|
||
## Конфиг клиента
|
||
|
||
В [[Hysteria/config-client|клиентском конфиге]] в `server` укажите тот же realm-URI, что зарегистрировал сервер:
|
||
|
||
```yaml
|
||
server: realm://public@realm.hy2.io/your-realm-name
|
||
auth: your-hysteria-password
|
||
```
|
||
|
||
Клиент делает STUN-обнаружение, просит посредника свести его с сервером, пробивает NAT и дальше проходит обычное QUIC-рукопожатие Hysteria — с проверкой TLS и паролем.
|
||
|
||
> [!danger] Токен realm — это НЕ пароль сервера
|
||
> Токен в URI нужен только для доступа к посреднику, он не заменяет пароль Hysteria (`auth`). Более того, на публичном посреднике токен общий (`public`), поэтому **любой, кто знает или угадает имя вашего realm, сможет узнать IP-адрес вашего сервера** (прокси он не воспользуется — аутентификация Hysteria на месте, но местоположение раскроет). Поэтому имя realm выбирайте длинным и случайным, как секрет (`my-cabin-1f3a8c2e9b`, а не `home`), и не используйте в нём то, что вас идентифицирует. Если это важно — поднимайте свой посредник.
|
||
|
||
## Выбор посредника (rendezvous)
|
||
|
||
**Публичный `realm.hy2.io`** (токен `public`) — бесплатный best-effort сервис проекта Hysteria. Удобно попробовать, но без гарантий: может лечь, сменить лимиты, быть заблокированным. Проект Hysteria не управляет и не проверяет чужие realm'ы — относитесь к незнакомому realm-имени с той же осторожностью, что к случайному VPN-провайдеру (может логировать трафик, устроить MITM или быть honeypot). Текущие лимиты: имя realm 6–64 символа (буква/цифра в начале, дальше буквы, цифры, `-`, `_`), не более 2 активных realm на один IP.
|
||
|
||
**Свой rendezvous** — правильный выбор для чего-то серьёзного. Сервер-посредник открытый и лёгкий (несколько КиБ памяти на realm): [github.com/apernet/hysteria-realm-server](https://github.com/apernet/hysteria-realm-server). Со своим приватным токеном регистрироваться и подключаться смогут только те, кто его знает, а uptime и логи под вашим контролем.
|
||
|
||
## Совместимость с NAT — работает не всегда
|
||
|
||
Hole punching зависит от типа NAT с обеих сторон. Полная матрица — в [официальной документации Realms](https://v2.hysteria.network/docs/advanced/Realms/#nat-compatibility), но суть такая:
|
||
|
||
- Если хотя бы одна сторона имеет **белый IP или Full Cone NAT** — работает надёжно в любой паре.
|
||
- **Симметричный NAT со случайными портами** с любой стороны (кроме случая, когда вторая сторона с белым IP/Full Cone) — принципиально не решается. Это свойство UDP hole punching, а не ограничение Hysteria.
|
||
- Промежуточные случаи (restricted, симметричный с предсказуемыми портами) — работают через раз, зависит от того, сможет ли Hysteria предугадать следующий порт. Для эвристики нужны несколько STUN-серверов (по умолчанию их 3); с одним STUN предсказание не сработает.
|
||
|
||
> [!tip] Если Realms не подключается
|
||
> Самая частая причина — симметричный NAT хотя бы с одной стороны. Если у вас так, запасной путь — обычный сервер с белым IP (см. [[Hysteria/install-server|установку]]). Для диагностики запустите обе стороны с `HYSTERIA_LOG_LEVEL=debug` и смотрите логи: `HYSTERIA_LOG_LEVEL=debug ./hysteria server -c server.yaml` и то же для клиента.
|
||
|
||
## TLS в режиме realm
|
||
|
||
Тонкость: в realm-режиме у клиента нет доменного имени для проверки сертификата — он соединяется по IP, который вернул посредник. Без настройки клиент подставит как SNI имя посредника, и обычный сертификат не совпадёт. Три варианта:
|
||
|
||
- **Самоподписанный сертификат + `pinSHA256`** — самый простой. Команда `hysteria cert` на сервере генерирует ключ с сертификатом и печатает готовые блоки `tls` для сервера (`cert`/`key`) и клиента (`insecure: true` + `pinSHA256`). Пин гарантирует, что клиент примет ровно этот сертификат, так что SNI и CA-проверка не важны.
|
||
- **Настоящий сертификат через DNS-01 ACME** для вашего домена + `tls.sni` на клиенте с этим доменом (HTTP-01/TLS-ALPN-01 без белого IP не сработают).
|
||
- **Сертификат на имя посредника** — практично только если вы хостите и посредник, и сервер сами.
|
||
|
||
## 📚 См. также
|
||
|
||
- [[Hysteria/install-server|Установка сервера]] — обычный путь с белым IP; запасной вариант, если NAT не пробивается.
|
||
- [[Hysteria/config-server|Конфиг сервера]] — поля `auth`/`tls`/`obfs`, работающие и в realm-режиме.
|
||
- [[Hysteria/config-client|Конфиг клиента]] — `pinSHA256` и `tls.sni` для самоподписанного сертификата.
|
||
- [[Hysteria/obfs-port-hopping|Обфускация и port hopping]] — почему в realm-режиме важна обфускация.
|
||
- 🔗 [Hysteria Realms — официальная документация](https://v2.hysteria.network/docs/advanced/Realms/) · [rendezvous-сервер](https://github.com/apernet/hysteria-realm-server)
|
||
|
||
---
|
||
|
||
> [!quote] 🤖 Эти статьи открыты — можно обучать на них ИИ
|
||
> При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование и скачивание всего репозитория одним zip-архивом доступны в Forgejo: [исходник этой заметки](https://git.zapret.moe/zapretdiscordyoutube/todo/src/branch/main/Hysteria/realms-nat.md) · [весь репозиторий](https://git.zapret.moe/zapretdiscordyoutube/todo/src/branch/main).
|