Skip to content

Hysteria2 — sing-box ​

sing-box 的 Hysteria2 实现是三个内核中最简洁的:两端各一个扁平块、多态伪装、出站显式的端口跳变字段。

入站 ​

type: "hysteria2" 入站:

字段类型默认值允许值描述
up_mbpsint0<Mbps>估算的上行带宽(Mbps)。服务端把它作为拥塞控制的提示。
down_mbpsint0<Mbps>估算的下行带宽(Mbps)。
obfs*Hysteria2Obfs(disabled)Hysteria2Obfs混淆块(salamander 或 gecko)。设置后两端必须一致。
users[]Hysteria2User[][Hysteria2User]可接受的用户。
ignore_client_bandwidthboolfalsetrue | false丢弃客户端宣告的带宽,单方面使用服务端的带宽设置。
masquerade*Hysteria2Masquerade(disabled)Hysteria2Masquerade对未鉴权流量返回 HTTP 响应伪装。接受字符串 URL 或类型化对象。
bbr_profilestringstandardconservative | standard | aggressiveBBR 拥塞控制档位,凡选用 BBR 时生效。
brutal_debugboolfalsetrue | false记录 Brutal 拥塞控制的内部状态。
realm*Hysteria2InboundRealm(disabled)Hysteria2InboundRealm向 Hysteria Realm 会合服务登记本服务器以实现 NAT 穿透:通过 STUN 发现公网地址,以 realm_id 登记,并借助 UDP 打洞接受客户端 —— 无需可公开访问的监听地址。

源码: option/hysteria2.go:17-30 · 锚定版本 v1.14.2 (af6e64c)

该结构体内嵌 ListenOptions、InboundTLSOptionsContainer 以及 QUICOptions(见下文“QUIC 字段”)。必须 配置 TLS —— Hysteria2 跑在 QUIC 上,没有明文模式。

obfs ​

字段类型默认值允许值描述
typestring(required)salamander | gecko混淆类型。gecko 另外接受 min_packet_size / max_packet_size。
passwordstring(required)<string>混淆密码(与用户密码相互独立)。

源码: option/hysteria2.go:64-68 · 锚定版本 v1.14.2 (af6e64c)

当 type: "gecko" 时,同一对象还接受:

字段类型默认值允许值描述
min_packet_sizeint512<bytes>线上最小数据包大小(字节)。仅 gecko。
max_packet_sizeint1200<bytes>线上最大数据包大小(字节)。仅 gecko。

源码: option/hysteria2.go:59-62 · 锚定版本 v1.14.2 (af6e64c)

users[] ​

字段类型默认值允许值描述
namestring(unset)<string>统计与日志中使用的显示名。
passwordstring(required)<string>用户鉴权密码。

源码: option/hysteria2.go:116-119 · 锚定版本 v1.14.2 (af6e64c)

masquerade ​

masquerade 字段是多态的(option/hysteria2.go:121-181):

  • 一个纯 字符串 URL。可识别的 scheme:
    • file:///var/www —— 等价于 { "type": "file", "directory": "/var/www" }。
    • https://upstream.example.com —— 等价于 { "type": "proxy", "url": "..." }。
  • 一个 对象,由 type 字段选择三种形态之一:
字段类型默认值允许值描述
typestring(unset)file | proxy | string选择启用的子块。

源码: option/hysteria2.go:121-126 · 锚定版本 v1.14.2 (af6e64c)

type: "file" ​

字段类型默认值允许值描述
directorystring(required)<dir path>在伪装端点上托管的本地目录。

源码: option/hysteria2.go:195-197 · 锚定版本 v1.14.2 (af6e64c)

type: "proxy" ​

字段类型默认值允许值描述
urlstring(required)<URL>伪装端点反向代理到的上游 URL。
rewrite_hostboolfalsetrue | false改写 Host 头以匹配上游 URL。

源码: option/hysteria2.go:199-202 · 锚定版本 v1.14.2 (af6e64c)

type: "string" ​

字段类型默认值允许值描述
status_codeint200<int>返回的 HTTP 状态码。
headersbadoption.HTTPHeader{}{<header>: <value>}附加响应头。
contentstring(required)<text>响应体内容。

源码: option/hysteria2.go:204-208 · 锚定版本 v1.14.2 (af6e64c)

出站 ​

type: "hysteria2" 出站:

字段类型默认值允许值描述
server_portsbadoption.Listable[string][]<range>端口跳变列表。每个条目是端口(如 "20001")或带连字符的范围(如 "20001-20100")。
hop_intervalbadoption.Duration30s<duration>切换新端口的频率。接受 Go 风格时长。
hop_interval_maxbadoption.Duration(unset)<duration>随机化端口跳变的上限:每次跳变等待 hop_interval 与该值之间的随机时长。
up_mbpsint0<Mbps>估算的上行带宽(Mbps)。
down_mbpsint0<Mbps>估算的下行带宽(Mbps)。
obfs*Hysteria2Obfs(disabled)Hysteria2Obfs混淆(salamander 或 gecko);必须与服务端一致。
passwordstring(required)<string>用户鉴权密码。
networkNetworkList(tcp+udp)tcp | udp | 限定为仅 TCP 或仅 UDP。
bbr_profilestringstandardconservative | standard | aggressiveBBR 拥塞控制档位,凡选用 BBR 时生效。
brutal_debugboolfalsetrue | false在客户端侧记录 Brutal CC 内部状态。
disable_chrome_parrotboolfalsetrue | false关闭 Chrome QUIC 握手模仿(默认开启)。模仿会套用 Chrome 的 QUIC 参数(idle_timeout 固定为 30 秒;max_concurrent_streams 与 initial_packet_size 采用 Chrome 的值;接收窗口从 Chrome 的初始值起步),且无法与使用 Ed25519 证书的服务端完成握手。
realm*Hysteria2Realm(disabled)Hysteria2Realm经由 Hysteria Realm 连接服务端:向 realm 查询以 realm_id 登记的地址,打洞后再进行正常的 QUIC 握手。与 server、server_port、server_ports 冲突。

源码: option/hysteria2.go:210-227 · 锚定版本 v1.14.2 (af6e64c)

同时内嵌 DialerOptions、ServerOptions(server、server_port)、OutboundTLSOptionsContainer(tls —— 必填)与 QUICOptions。

Realm(NAT 穿透) ​

位于 NAT 之后的服务端在入站上设置 realm,向 Hysteria Realm 服务登记;客户端在出站上设置 realm(代替 server)来找到它。两端共用以下结构:

字段类型默认值允许值描述
server_urlstring(required)<URL>Realm 会合服务的 URL。
tokenstring(unset)<string>Bearer 令牌;必须与 realm 的某个 users[].token 一致。
realm_idstring(required)<id>槽位标识。服务端以此登记,客户端必须使用相同的值;1–64 个字符,匹配 ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$。
stun_serversbadoption.Listable[string](required)<host[:port]> | …用于发现公网地址的 STUN 服务器。在出站上,域名由拨号字段中的 domain_resolver 解析。
ip_versionint(both)4 | 6把 STUN、打洞以及最终的 QUIC 路径限制在单一 IP 版本。
port_mapping*Hysteria2RealmPortMapping(disabled)Hysteria2RealmPortMapping通过 UPnP 或 NAT-PMP 在本地网关上维持 UDP 端口映射;失败不致命。要求 IPv4。
http_client*HTTPClientOptions(default)<tag> | HTTPClientOptions与 realm 通信所用的 HTTP 客户端(内联对象,或 http_clients 条目的 tag)。

源码: option/hysteria2.go:32-40 · 锚定版本 v1.14.2 (af6e64c)

入站形式额外增加:

字段类型默认值允许值描述
stun_domain_resolver*DomainResolveOptions(default resolver)<dns server tag> | DomainResolveOptions仅入站:用于解析 STUN 服务器域名的解析器(格式同 domain_resolver)。

源码: option/hysteria2.go:54-57 · 锚定版本 v1.14.2 (af6e64c)

port_mapping:

字段类型默认值允许值描述
enabledboolfalsetrue | false启用端口映射。
timeoutbadoption.Duration10s<duration>网关发现与映射操作的超时。
lifetimebadoption.Duration10m<duration>映射的租期;在租期过半时续期。

源码: option/hysteria2.go:48-52 · 锚定版本 v1.14.2 (af6e64c)

QUIC 字段 ​

两端都内嵌与 Hysteria、TUIC 以及 HTTP/3 客户端共用的 QUIC 参数(QUICOptions,其中又内嵌 HTTP2Options)。启用 Chrome 模仿时(客户端默认),idle_timeout 固定为 30 秒,max_concurrent_streams / initial_packet_size 由 Chrome 的值取代。

字段类型默认值允许值描述
initial_packet_sizeint(QUIC default)<bytes>QUIC 初始数据包大小。
disable_path_mtu_discoveryboolfalsetrue | false禁用 QUIC 路径 MTU 发现。

源码: option/http.go:22-26 · 锚定版本 v1.14.2 (af6e64c)

字段类型默认值允许值描述
idle_timeoutbadoption.Duration(default)<duration>空闲连接超时。
keep_alive_periodbadoption.Duration(default)<duration>保活周期。
stream_receive_window*byteformats.MemoryBytes(default)<size>每个流的流控接收窗口,内存大小格式(如 64 MB)。
connection_receive_window*byteformats.MemoryBytes(default)<size>每个连接的流控接收窗口,内存大小格式。
max_concurrent_streamsint(default)<int>每个连接的最大并发流数。

源码: option/http.go:14-20 · 锚定版本 v1.14.2 (af6e64c)

示例 ​

不暴露端口跳变(服务端只监听单端口)、带 Salamander 混淆与 file 伪装的入站:

json
{
  "inbounds": [
    {
      "type": "hysteria2",
      "tag": "hy2-in",
      "listen": "::",
      "listen_port": 443,
      "users": [
        { "name": "alice", "password": "<password>" }
      ],
      "obfs": { "type": "salamander", "password": "<obfs>" },
      "tls": {
        "enabled": true,
        "alpn": ["h3"],
        "certificate_path": "/etc/ssl/cert.pem",
        "key_path": "/etc/ssl/key.pem"
      },
      "masquerade": "file:///var/www"
    }
  ]
}

带端口跳变(20000-20100,每 30 秒切换)的出站:

json
{
  "outbounds": [
    {
      "type": "hysteria2",
      "tag": "hy2-out",
      "server": "example.com",
      "server_port": 443,
      "server_ports": ["20000-20100"],
      "hop_interval": "30s",
      "password": "<password>",
      "obfs": { "type": "salamander", "password": "<obfs>" },
      "up_mbps": 100,
      "down_mbps": 300,
      "tls": { "enabled": true, "server_name": "example.com" }
    }
  ]
}

说明 ​

  • 带宽这里是 纯整数 Mbps —— 不带单位字符串。Xray 与 mihomo 接受带后缀的字符串("100mbps"),sing-box 不支持。
  • obfs.type 可为 salamander 或 gecko。省略 obfs 的配置走未混淆路径。
  • 客户端默认模仿 Chrome 的 QUIC 握手。Chrome 不声明支持 Ed25519,因此使用 Ed25519 证书的服务端会握手失败 —— 请改用 ECDSA 或 RSA 证书,或在客户端设置 disable_chrome_parrot: true。
  • 在出站上不设置 up_mbps / down_mbps 时使用 BBR(可用 bbr_profile 调整),而非 Brutal。
  • masquerade 同时接受多态类型化对象与纯字符串 URL —— 两者都会解组到相同的内部表示(option/hysteria2.go:145-164)。
  • 管理员已知真实带宽时,推荐设置 ignore_client_bandwidth: true —— 可防止恶意客户端通过低报自身带宽从服务端榨取更多资源。

跨内核说明 ​

  • Xray-core 支持 Hysteria2,但把配置拆到 settings 与 streamSettings.hysteriaSettings,带宽、拥塞控制与端口跳变则位于 streamSettings.finalmask。参见 Hysteria2 — Xray-core。
  • mihomo 使用单块出站,up / down 是带单位后缀的字符串(与 Xray 一样)。端口跳变由 ports + hop-interval 表达。入站的用户是 map[string]string(用户名 → 密码)而非对象列表。参见 Hysteria2 — mihomo。

源码: option/hysteria2.go:17-227 · v1.14.2 (af6e64c)

由 Argsment 出品的 Core Tutorial