Hysteria2 — Xray-core
Xray-core 支持 Hysteria v2,但 把配置分到多个块:协议层的 settings(version、address/port、users)、传输层的 streamSettings.hysteriaSettings(鉴权、UDP 空闲超时、伪装),以及负责拥塞控制、带宽与端口跳变的 streamSettings.finalmask。settings 与 hysteriaSettings 都填好后出站才可用。
出站 —— 协议层
"protocol": "hysteria" 出站的 settings:
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
version | int32 | (required) | 2 | 必须恰好等于 2。其他值会在启动时被拒绝(infra/conf/hysteria.go:19-21)。 |
address | *Address | (required) | <host> | 服务器主机名或 IP。 |
port | uint16 | (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:
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
version | int32 | (required) | 2 | 必须为 2。 |
users | []*HysteriaUserConfig | [] | [HysteriaUserConfig] | 可接受的用户。users 与 clients 是可互换的键,形状相同。 |
clients | []*HysteriaUserConfig | [] | [HysteriaUserConfig] | 可接受的用户(替代键;形状与 users 相同)。 |
源码: infra/conf/hysteria.go:39-43 · 锚定版本 v26.9.9 (52a412d)
clients[]
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
auth | string | (required) | <string> | 鉴权字符串。 |
level | uint32 | 0 | <uint32> | 该用户的策略等级。 |
email | string | (unset) | <string> | 统计 / 日志中显示的标签。 |
源码: infra/conf/hysteria.go:33-37 · 锚定版本 v26.9.9 (52a412d)
传输层 —— hysteriaSettings
位于 streamSettings.hysteriaSettings 下。承载鉴权、UDP 空闲超时与入站伪装;拥塞控制、带宽与端口跳变位于 finalmask(见下文)。
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
version | int32 | (required) | 2 | Hysteria 协议版本。必须与 settings 中的 version 一致。 |
auth | string | (required on outbound) | <string> | 出站的鉴权字符串。入站会把该字段转发给校验器,但每用户的鉴权位于 settings.clients[].auth。 |
udpIdleTimeout | int64 | 60 | <2..600 seconds> | QUIC 流关闭前的 UDP 流空闲秒数。必须在 [2, 600] 之间(含端点)(infra/conf/transport_method.go:764-766)。 |
masquerade | Masquerade | (unset) | Masquerade | 仅入站:对未鉴权流量返回 HTTP 响应伪装。 |
源码: infra/conf/transport_method.go:752-757 · 锚定版本 v26.9.9 (52a412d)
masquerade
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
type | string | (required) | file | proxy | string | 选择启用的子块。 |
dir | string | (file only) | <dir path> | type: file 时托管的目录。 |
url | string | (proxy only) | <URL> | type: proxy 时使用的上游 URL。 |
rewriteHost | bool | false | true | false | 代理时是否改写 Host 头(type: proxy)。 |
xForwarded | bool | false | true | false | 为代理请求添加 X-Forwarded-For / X-Forwarded-Host / X-Forwarded-Proto 头(type: proxy)。 |
insecure | bool | false | true | false | type: proxy 时跳过对上游的 TLS 校验。 |
content | string | (string only) | <text> | type: string 时返回的响应体。 |
headers | map[string]string | {} | {<header>: <value>} | type: string 时附加的响应头。 |
statusCode | int32 | 200 | <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 相关的字段:
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
congestion | string | (empty) | brutal | force-brutal | bbr | reno | Hysteria 的拥塞控制。空值 / brutal:当 brutalUp 与对端通告的接收速率都已知时,以两者中的较小值运行 Brutal,否则使用 BBR。force-brutal:始终以 brutalUp 运行 Brutal(要求设置 brutalUp)。bbr:始终使用 BBR。reno:普通 Reno。 |
bbrProfile | string | standard | conservative | standard | aggressive | BBR 调优档位,凡选用 BBR 时生效。未知值会在配置构建时报错。 |
brutalUp | Bandwidth | (unset) | <bandwidth> | 本端 Brutal 的发送速率,使用带单位的字符串(见“带宽语法”)。设置时必须至少为 65536 字节/秒(512 kbps)。 |
brutalDown | Bandwidth | (unset) | <bandwidth> | 本端在 Hysteria 握手中向对端通告的接收速率;对端会把自身的 Brutal 发送速率限制在该值以内。语法与下限同 brutalUp。 |
brutalDisableLossCompensation | bool | false | true | 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) | SocketConfig | intervalLocal 每次跳变新打开的本地套接字所使用的套接字选项。 |
mode | string | (required) | intervalLocal | intervalRemote | perConnRemote | <comma-separated combination> | 每次跳变时改变什么(不区分大小写,逗号分隔)。intervalLocal 每个间隔打开一个新的本地 UDP 套接字(新的源端口);intervalRemote 每个间隔从 remotePorts / remoteIPs 中挑选新的目标端口 / IP;perConnRemote 每个连接只随机挑选一次目标。空值或未知值会在配置构建时报错。只有 intervalLocal 跳变打开的套接字才会读取回包,因此请包含它(例如 "intervalLocal,intervalRemote")。 |
interval | Int32Range | (required) | <seconds> | "<min>-<max>" | 两次跳变之间的秒数;给出范围时每次随机取值。两端都必须至少为 5 —— 否则连接会在拨号时以 invalid interval 失败。 |
remotePorts | PortList | (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、bps | 1 |
k、kb、kbps | 1024 |
m、mb、mbps | 1 048 576 |
g、gb、gbps | 1 073 741 824 |
t、tb、tbps | 1 099 511 627 776 |
数值部分按 float64 解析,结果除以 8(protobuf 中承载的是 bytes-per-second,但来源单位名是 bps)。
示例
出站:
{
"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 伪装的入站:
{
"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)
