Skip to content

Hysteria realm — sing-box ​

hysteria-realm — сервис-рандеву для обхода NAT в Hysteria2. Сервер Hysteria2 за NAT узнаёт свои публичные адреса через STUN и регистрирует их в этом сервисе под идентификатором realm; клиенты запрашивают эти адреса у realm, обе стороны пробивают UDP-дыру, и затем QUIC-соединение устанавливается напрямую. Realm передаёт только сигнализацию плоскости управления — проксируемый трафик через него никогда не идёт.

Параметры ​

type: "hysteria-realm" в services[]:

ПолеТипПо умолчаниюДопустимые значенияОписание
users[]HysteriaRealmUser(required)[HysteriaRealmUser]Учётные записи, которым разрешено пользоваться realm. Нужна хотя бы одна, иначе запуск завершается ошибкой.

Исходный код: option/hysteria2.go:235-240 · зафиксировано на v1.14.2 (af6e64c)

Сервис также встраивает ListenOptions (см. Входящие), входящий блок tls (см. TLS) и поля HTTP/2 ниже. С tls он работает по HTTP/2 поверх TLS (h2 автоматически добавляется в список ALPN); без него — по обычному HTTP: HTTP/1.1, причём HTTP/2 без шифрования тоже принимается.

users[] ​

ПолеТипПо умолчаниюДопустимые значенияОписание
namestring(required)<string>Имя учётной записи; используется в журналах и как ключ квоты realm на пользователя.
tokenstring(required)<string>Bearer-токен, который входящие и исходящие Hysteria2 предъявляют как Authorization: Bearer <token> (их realm.token).
max_realmsint0<int>Сколько слотов realm эта учётная запись может занимать одновременно. 0 — без ограничений; сверх лимита регистрация отклоняется с HTTP 429.

Исходный код: option/hysteria2.go:229-233 · зафиксировано на v1.14.2 (af6e64c)

Поля HTTP/2 ​

Эти поля настраивают HTTP/2-сервер сервиса и важны только тогда, когда клиенты используют HTTP/2.

ПолеТипПо умолчаниюДопустимые значенияОписание
idle_timeoutbadoption.Duration(Go default)<duration>Закрывать соединения HTTP/2, простаивающие дольше этого времени.
keep_alive_periodbadoption.Duration(disabled)<duration>Отправлять HTTP/2 PING, если за это время ничего не прочитано, чтобы обнаруживать мёртвые соединения.
stream_receive_window*byteformats.MemoryBytes(Go default)<size>Буфер загрузки на поток (окно управления потоком) в виде размера памяти.
connection_receive_window*byteformats.MemoryBytes(Go default)<size>Буфер загрузки на соединение в виде размера памяти.
max_concurrent_streamsint(Go default)<int>Максимум одновременных потоков HTTP/2 на соединение.

Исходный код: option/http.go:14-20 · зафиксировано на v1.14.2 (af6e64c)

Как Hysteria2 использует realm ​

  • Сервер: задайте realm на входящем Hysteria2 с server_url, указывающим на этот сервис, token из users[], realm_id и stun_servers. Входящий регистрирует найденные через STUN адреса под этим идентификатором и поддерживает регистрацию heartbeat-запросами.
  • Клиент: задайте realm на исходящем Hysteria2 (вместо server) с тем же server_url, действительным token и тем же realm_id. Исходящий запрашивает адреса, пробивает NAT и затем выполняет обычное QUIC-рукопожатие.
  • Подробности полей (ip_version, port_mapping, http_client, stun_domain_resolver) — на странице Hysteria2.

Минимальный пример ​

Сервис realm на хосте со стабильным публичным адресом:

json
{
  "services": [
    {
      "type": "hysteria-realm",
      "tag": "realm",
      "listen": "::",
      "listen_port": 8443,
      "tls": {
        "enabled": true,
        "certificate_path": "/etc/ssl/realm.pem",
        "key_path": "/etc/ssl/realm.key"
      },
      "users": [
        { "name": "home", "token": "<token>", "max_realms": 2 }
      ]
    }
  ]
}

Соответствующий блок realm на входящем Hysteria2 за NAT (исходящий использует те же server_url, token и realm_id):

json
"realm": {
  "server_url": "https://realm.example.com:8443",
  "token": "<token>",
  "realm_id": "home-server",
  "stun_servers": ["stun.l.google.com:19302"]
}

Примечания ​

  • Требуется тег сборки with_quic; без него тип существует, но запуск завершается ошибкой.
  • users не может быть пустым, и в каждой записи нужны и name, и token.
  • Идентификатор realm одновременно может занимать только одна регистрация: второй сервер, регистрирующий тот же идентификатор, получает HTTP 409 (realm_taken).
  • API расположен под /v1/<realm_id> — сохраните этот путь, если ставите перед сервисом обратный прокси.
  • Публично доступным должен быть только realm; серверу Hysteria2 за NAT проброс портов не нужен.

Сравнение с другими ядрами ​

  • У mihomo есть эквивалентный слушатель-рандеву Hysteria2 realm с одним общим token и ограничениями max-realms / max-realms-per-ip вместо токенов на пользователя.
  • У Xray-core нет realm-сервера; его UDP-маска finalmask realm — аналог на стороне конечной точки. См. Hysteria2 — Xray-core.

Исходный код: option/hysteria2.go:229-240 · v1.14.2 (af6e64c)

Core Tutorial от Argsment