Skip to content

Hysteria2 — Xray-core ​

Xray-core 支持 Hysteria v2,但 把配置分到多个块:协议层的 settings(version、address/port、users)、传输层的 streamSettings.hysteriaSettings(鉴权、UDP 空闲超时、伪装),以及负责拥塞控制、带宽与端口跳变的 streamSettings.finalmask。settings 与 hysteriaSettings 都填好后出站才可用。

出站 —— 协议层 ​

"protocol": "hysteria" 出站的 settings:

字段类型默认值允许值描述
versionint32(required)2必须恰好等于 2。其他值会在启动时被拒绝(infra/conf/hysteria.go:19-21)。
address*Address(required)<host>服务器主机名或 IP。
portuint16(required)<port>服务器 UDP 端口。

源码: infra/conf/hysteria.go:13-17 · 锚定版本 v26.9.9 (52a412d)

不支持 Hysteria v1

version 字段 必须 等于 2。HysteriaClientConfig.Build(infra/conf/hysteria.go:19-21)对任何其他值返回 errors.New("version != 2")。

入站 —— 协议层 ​

"protocol": "hysteria" 入站的 settings:

字段类型默认值允许值描述
versionint32(required)2必须为 2。
users[]*HysteriaUserConfig[][HysteriaUserConfig]可接受的用户。users 与 clients 是可互换的键,形状相同。
clients[]*HysteriaUserConfig[][HysteriaUserConfig]可接受的用户(替代键;形状与 users 相同)。

源码: infra/conf/hysteria.go:39-43 · 锚定版本 v26.9.9 (52a412d)

clients[] ​

字段类型默认值允许值描述
authstring(required)<string>鉴权字符串。
leveluint320<uint32>该用户的策略等级。
emailstring(unset)<string>统计 / 日志中显示的标签。

源码: infra/conf/hysteria.go:33-37 · 锚定版本 v26.9.9 (52a412d)

传输层 —— hysteriaSettings ​

位于 streamSettings.hysteriaSettings 下。承载鉴权、UDP 空闲超时与入站伪装;拥塞控制、带宽与端口跳变位于 finalmask(见下文)。

字段类型默认值允许值描述
versionint32(required)2Hysteria 协议版本。必须与 settings 中的 version 一致。
authstring(required on outbound)<string>出站的鉴权字符串。入站会把该字段转发给校验器,但每用户的鉴权位于 settings.clients[].auth。
udpIdleTimeoutint6460<2..600 seconds>QUIC 流关闭前的 UDP 流空闲秒数。必须在 [2, 600] 之间(含端点)(infra/conf/transport_method.go:764-766)。
masqueradeMasquerade(unset)Masquerade仅入站:对未鉴权流量返回 HTTP 响应伪装。

源码: infra/conf/transport_method.go:752-757 · 锚定版本 v26.9.9 (52a412d)

masquerade ​

字段类型默认值允许值描述
typestring(required)file | proxy | string选择启用的子块。
dirstring(file only)<dir path>type: file 时托管的目录。
urlstring(proxy only)<URL>type: proxy 时使用的上游 URL。
rewriteHostboolfalsetrue | false代理时是否改写 Host 头(type: proxy)。
xForwardedboolfalsetrue | false为代理请求添加 X-Forwarded-For / X-Forwarded-Host / X-Forwarded-Proto 头(type: proxy)。
insecureboolfalsetrue | falsetype: proxy 时跳过对上游的 TLS 校验。
contentstring(string only)<text>type: string 时返回的响应体。
headersmap[string]string{}{<header>: <value>}type: string 时附加的响应头。
statusCodeint32200<int>type: string 时返回的状态码。

源码: infra/conf/transport_method.go:737-750 · 锚定版本 v26.9.9 (52a412d)

type 字段切换活动子块:file 使用 dir,proxy 使用 url / rewriteHost / xForwarded / insecure,string 使用 content / headers / statusCode。

拥塞控制与带宽 —— finalmask.quicParams ​

位于 streamSettings.finalmask.quicParams 下(与其他基于 QUIC 的传输层共用的 QUIC 参数块)。与 Hysteria 相关的字段:

字段类型默认值允许值描述
congestionstring(empty)brutal | force-brutal | bbr | renoHysteria 的拥塞控制。空值 / brutal:当 brutalUp 与对端通告的接收速率都已知时,以两者中的较小值运行 Brutal,否则使用 BBR。force-brutal:始终以 brutalUp 运行 Brutal(要求设置 brutalUp)。bbr:始终使用 BBR。reno:普通 Reno。
bbrProfilestringstandardconservative | standard | aggressiveBBR 调优档位,凡选用 BBR 时生效。未知值会在配置构建时报错。
brutalUpBandwidth(unset)<bandwidth>本端 Brutal 的发送速率,使用带单位的字符串(见“带宽语法”)。设置时必须至少为 65536 字节/秒(512 kbps)。
brutalDownBandwidth(unset)<bandwidth>本端在 Hysteria 握手中向对端通告的接收速率;对端会把自身的 Brutal 发送速率限制在该值以内。语法与下限同 brutalUp。
brutalDisableLossCompensationboolfalsetrue | false禁止 Brutal 为补偿测得的丢包而提高发送速率 —— 此时它严格按配置速率发送。

源码: infra/conf/transport_finalmask.go:993-1011 · 锚定版本 v26.9.9 (52a412d)

端口跳变 —— finalmask.udp 中的 udphop ​

端口跳变是一个客户端 UDP 掩码:在 streamSettings.finalmask.udp 中添加一个 "type": "udphop" 条目,并在其 settings 下填写以下选项。它必须是 finalmask.udp 的第一个条目,且仅用于出站 —— 入站会以 udphop: client only 拒绝。服务端仍只监听一个端口,需要把跳变范围转发到该端口(例如使用 iptables 的 DNAT / REDIRECT 规则)。

字段类型默认值允许值描述
sockopt*SocketConfig(unset)SocketConfigintervalLocal 每次跳变新打开的本地套接字所使用的套接字选项。
modestring(required)intervalLocal | intervalRemote | perConnRemote | <comma-separated combination>每次跳变时改变什么(不区分大小写,逗号分隔)。intervalLocal 每个间隔打开一个新的本地 UDP 套接字(新的源端口);intervalRemote 每个间隔从 remotePorts / remoteIPs 中挑选新的目标端口 / IP;perConnRemote 每个连接只随机挑选一次目标。空值或未知值会在配置构建时报错。只有 intervalLocal 跳变打开的套接字才会读取回包,因此请包含它(例如 "intervalLocal,intervalRemote")。
intervalInt32Range(required)<seconds> | "<min>-<max>"两次跳变之间的秒数;给出范围时每次随机取值。两端都必须至少为 5 —— 否则连接会在拨号时以 invalid interval 失败。
remotePortsPortList(keep original port)<port / range list>用于跳变的目标端口,例如 "20000-50000" 或 [443, "8000-9000"]。供 intervalRemote / perConnRemote 使用。
remoteIPs[]string(keep original IP)<IP or CIDR> | …用于跳变的目标地址。CIDR 会在前缀内随机挑选地址。供 intervalRemote / perConnRemote 使用。

源码: infra/conf/transport_finalmask.go:911-917 · 锚定版本 v26.9.9 (52a412d)

带宽语法 ​

brutalUp 与 brutalDown 由 infra/conf/transport_method.go:696-735 中的辅助函数解析。可接受的后缀:

后缀倍数
(空)、b、bps1
k、kb、kbps1024
m、mb、mbps1 048 576
g、gb、gbps1 073 741 824
t、tb、tbps1 099 511 627 776

数值部分按 float64 解析,结果除以 8(protobuf 中承载的是 bytes-per-second,但来源单位名是 bps)。

示例 ​

出站:

json
{
  "outbounds": [
    {
      "tag": "hy2-out",
      "protocol": "hysteria",
      "settings": {
        "version": 2,
        "address": "example.com",
        "port": 443
      },
      "streamSettings": {
        "network": "hysteria",
        "security": "tls",
        "tlsSettings": { "serverName": "example.com" },
        "hysteriaSettings": {
          "version": 2,
          "auth": "<password>",
          "udpIdleTimeout": 120
        },
        "finalmask": {
          "quicParams": {
            "brutalUp": "100mbps",
            "brutalDown": "300mbps"
          },
          "udp": [
            {
              "type": "udphop",
              "settings": {
                "mode": "intervalLocal,intervalRemote",
                "remotePorts": "20000-50000",
                "interval": "5-30"
              }
            }
          ]
        }
      }
    }
  ]
}

带两个用户与 HTTP-file 伪装的入站:

json
{
  "inbounds": [
    {
      "tag": "hy2-in",
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "hysteria",
      "settings": {
        "version": 2,
        "clients": [
          { "auth": "<alice>", "email": "alice" },
          { "auth": "<bob>",   "email": "bob"   }
        ]
      },
      "streamSettings": {
        "network": "hysteria",
        "security": "tls",
        "tlsSettings": { "certificates": [{ "certificateFile": "/etc/ssl/cert.pem", "keyFile": "/etc/ssl/key.pem" }] },
        "hysteriaSettings": {
          "version": 2,
          "masquerade": {
            "type": "file",
            "dir": "/var/www"
          }
        }
      }
    }
  ]
}

说明 ​

  • 常见坑:仅在 settings 中设置 auth(误以为它是用户名 / 密码字段)。Xray 从 streamSettings.hysteriaSettings.auth 读取出站鉴权;入站用户使用 settings.clients[].auth(每用户),匹配时忽略传输层 auth。
  • congestion、up、down 与 udphop 不是 hysteriaSettings 的字段。Xray 不拒绝未知键,因此写在此处的值会被静默忽略。请通过 finalmask.quicParams.congestion / brutalUp / brutalDown 以及 finalmask.udp 中的 udphop 条目来设置。
  • Xray-core 只实现 Hysteria 2:version 必须为 2,其他任何值都是硬错误。
  • udpIdleTimeout < 2 或 > 600 会触发启动错误(infra/conf/transport_method.go:764-766)。

跨内核说明 ​

  • sing-box 采用单一、扁平得多的块 —— 没有传输层拆分。带宽以整数 Mbps 表达(不带单位字符串),伪装支持多态形态(字符串 URL 或类型化对象)。参见 Hysteria2 — sing-box。
  • mihomo 同样是单块形态,端口跳变由 ports(范围语法)加 hop-interval 驱动。mihomo 接受带单位后缀的 up / down 字符串,与 Xray 的 brutalUp / brutalDown 相同。参见 Hysteria2 — mihomo。

源码: infra/conf/hysteria.go:13-43 · v26.9.9 (52a412d)

由 Argsment 出品的 Core Tutorial