Hysteria realm — sing-box
hysteria-realm 是用于 Hysteria2 NAT 穿透的会合服务。位于 NAT 之后的 Hysteria2 服务端通过 STUN 探测自己的公网地址,并以某个 realm ID 注册到该服务;客户端向 realm 查询这些地址,双方进行 UDP 打洞,随后直接建立 QUIC 连接。realm 只承载控制面信令 —— 代理流量从不经过它。
选项
services[] 下的 type: "hysteria-realm":
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
users | []HysteriaRealmUser | (required) | [HysteriaRealmUser] | 允许使用该 realm 的账户。至少需要一个,否则启动失败。 |
源码: option/hysteria2.go:235-240 · 锚定版本 v1.14.2 (af6e64c)
该服务还嵌入了 ListenOptions(见入站)、入站 tls 块(见 TLS)以及下方的 HTTP/2 字段。配置 tls 时提供基于 TLS 的 HTTP/2(会自动把 h2 加入 ALPN 列表);否则提供明文 HTTP —— HTTP/1.1,同时也接受明文 HTTP/2。
users[]
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
name | string | (required) | <string> | 账户名,用于日志,也是按用户计算 realm 配额的键。 |
token | string | (required) | <string> | Hysteria2 入站和出站以 Authorization: Bearer <token> 出示的 Bearer 令牌(即它们的 realm.token)。 |
max_realms | int | 0 | <int> | 该账户可同时持有的 realm 槽位数量。0 表示不限;超出上限时注册会以 HTTP 429 被拒绝。 |
源码: option/hysteria2.go:229-233 · 锚定版本 v1.14.2 (af6e64c)
HTTP/2 字段
这些字段调节服务的 HTTP/2 服务器,仅在客户端使用 HTTP/2 时有意义。
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
idle_timeout | badoption.Duration | (Go default) | <duration> | 关闭空闲达到该时长的 HTTP/2 连接。 |
keep_alive_period | badoption.Duration | (disabled) | <duration> | 在该时长内未读到任何数据时发送 HTTP/2 PING,以检测失效连接。 |
stream_receive_window | *byteformats.MemoryBytes | (Go default) | <size> | 每个流的上传缓冲区(流量控制窗口),以内存大小表示。 |
connection_receive_window | *byteformats.MemoryBytes | (Go default) | <size> | 每个连接的上传缓冲区,以内存大小表示。 |
max_concurrent_streams | int | (Go default) | <int> | 每个连接允许的最大并发 HTTP/2 流数。 |
源码: option/http.go:14-20 · 锚定版本 v1.14.2 (af6e64c)
Hysteria2 如何使用 realm
- 服务端:在 Hysteria2 入站上设置
realm,其中server_url指向本服务,token取自users[],并给出realm_id与stun_servers。入站会把 STUN 探测到的地址注册到该 ID 下,并通过心跳保持注册有效。 - 客户端:在 Hysteria2 出站上设置
realm(代替server),使用相同的server_url、有效的token和相同的realm_id。出站查询地址、打洞,然后进行正常的 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 }
]
}
]
}位于 NAT 之后的 Hysteria2 入站上对应的 realm 块(出站使用相同的 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 ID 同一时间只能被一次注册持有:第二个服务端注册相同 ID 会得到 HTTP 409(
realm_taken)。 - API 位于
/v1/<realm_id>之下 —— 若在前面放置反向代理,请保持该路径不变。 - 只有 realm 需要能被公网访问;位于 NAT 之后的 Hysteria2 服务端无需端口转发。
跨内核说明
- mihomo 有等价的会合监听器 Hysteria2 realm,使用一个共享
token加max-realms/max-realms-per-ip上限,而非按用户的令牌。 - Xray-core 没有 realm 服务器;其
realmfinalmask UDP 掩码是端点一侧的对应物。参见 Hysteria2 — Xray-core。
源码: option/hysteria2.go:229-240 · v1.14.2 (af6e64c)
