diff --git a/.vitepress/menus/sidebar.en.mts b/.vitepress/menus/sidebar.en.mts index e1cbbe6479..25375c4fa6 100644 --- a/.vitepress/menus/sidebar.en.mts +++ b/.vitepress/menus/sidebar.en.mts @@ -68,6 +68,7 @@ export const sidebar: DefaultTheme.Config["sidebar"] = { }, { text: "VMess", link: "/en/config/inbounds/vmess.md" }, { text: "Wireguard", link: "/en/config/inbounds/wireguard.md" }, + { text: "Hysteria", link: "/en/config/inbounds/hysteria.md" }, { text: "TUN", link: "/en/config/inbounds/tun.md" } ] }, diff --git a/.vitepress/menus/sidebar.mts b/.vitepress/menus/sidebar.mts index a1503b11d7..728c72e5bc 100644 --- a/.vitepress/menus/sidebar.mts +++ b/.vitepress/menus/sidebar.mts @@ -59,6 +59,7 @@ export const sidebar: DefaultTheme.Config["sidebar"] = { }, { text: "VMess", link: "/config/inbounds/vmess.md" }, { text: "Wireguard", link: "/config/inbounds/wireguard.md" }, + { text: "Hysteria", link: "/config/inbounds/hysteria.md" }, { text: "TUN", link: "/config/inbounds/tun.md" } ] }, diff --git a/.vitepress/menus/sidebar.ru.mts b/.vitepress/menus/sidebar.ru.mts index 51f2a696a0..e28f42b086 100644 --- a/.vitepress/menus/sidebar.ru.mts +++ b/.vitepress/menus/sidebar.ru.mts @@ -80,6 +80,7 @@ export const sidebar: DefaultTheme.Config["sidebar"] = { }, { text: "VMess", link: "/ru/config/inbounds/vmess.md" }, { text: "Wireguard", link: "/ru/config/inbounds/wireguard.md" }, + { text: "Hysteria", link: "/ru/config/inbounds/hysteria.md" }, { text: "TUN", link: "/ru/config/inbounds/tun.md" } ] }, @@ -115,7 +116,7 @@ export const sidebar: DefaultTheme.Config["sidebar"] = { link: "/ru/config/outbounds/wireguard.md" }, { - text: "Hysteria 2", + text: "Hysteria", link: "/ru/config/outbounds/hysteria.md" } ] diff --git a/docs/config/inbound.md b/docs/config/inbound.md index 84660bb6d0..2f53baa584 100644 --- a/docs/config/inbound.md +++ b/docs/config/inbound.md @@ -54,7 +54,7 @@ 注意,监听一个端口是相当昂贵的操作,监听端口范围太大可能造成占用显著提高甚至导致 Xray 无法正常工作,一般来说监听数量接近四位数时可能就会开始出现问题,要使用一个很大的范围请考虑使用 iptables 进行重定向而不是在这里设置。 -> `protocol`: "dokodemo-door" | "http" | "shadowsocks" | "socks" | "vless" | "vmess" | "trojan" | "wireguard" +> `protocol`: "dokodemo-door" | "http" | "shadowsocks" | "socks" | "vless" | "vmess" | "trojan" | "wireguard" | "hysteria" 连接协议名称,可选的协议列表见左侧 [入站协议](./inbounds/)。 diff --git a/docs/config/inbounds/hysteria.md b/docs/config/inbounds/hysteria.md new file mode 100644 index 0000000000..71e39b6325 --- /dev/null +++ b/docs/config/inbounds/hysteria.md @@ -0,0 +1,52 @@ +# Hysteria + +::: tip +`hysteria protocol` 本身无认证,`clients` 仅在搭配 `hysteria` 传输层时生效 +::: + +## InboundConfigurationObject + +```json +{ + "version": 2, + "clients": [ + { + "auth": "5783a3e7-e373-51cd-8642-c83782b807c5", + "level": 0, + "email": "love@xray.com" + } + ] +} +``` + +> `version`: number + +Hysteria 版本,必须为 2。 + +> `clients`: \[ [ClientObject](#clientobject) \] + +一个数组,代表一组服务端认可的用户。 + +### ClientObject + +```json +{ + "auth": "5783a3e7-e373-51cd-8642-c83782b807c5", + "level": 0, + "email": "love@xray.com" +} +``` + +> `auth`: string + +任意长度字符串。 + +> `level`: number + +用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。 + +level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。 + +> `email`: string + +用户邮箱,用于区分不同用户的流量(会体现在日志、统计中)。 diff --git a/docs/config/inbounds/index.md b/docs/config/inbounds/index.md index 5eecddc2ec..d7d26cd904 100644 --- a/docs/config/inbounds/index.md +++ b/docs/config/inbounds/index.md @@ -10,4 +10,5 @@ Xray 支持以下入站协议: - [VLESS (XTLS Vision Seed)](vless.md) - [VMess](vmess.md) - [WireGuard](wireguard.md) +- [Hysteria](hysteria.md) - [TUN](tun.md) diff --git a/docs/config/outbounds/hysteria.md b/docs/config/outbounds/hysteria.md index 5fca88b700..fafcbff8e0 100644 --- a/docs/config/outbounds/hysteria.md +++ b/docs/config/outbounds/hysteria.md @@ -2,7 +2,11 @@ Hysteria 协议的客户端实现。 -这个页面非常简单,因为 hysteria 协议实际上分为一个简单的代理控制协议和经过调优的 QUIC 底层传输,在 Xray 中代理协议和底层传输被拆分,更多内容(如 brutal)详见底层传输的 [hysteriaSettings](../transports/hysteria.md) +这个页面非常简单,因为 hysteria 协议实际上分为一个简单的代理控制协议和经过调优的 QUIC 底层传输,在 Xray 中代理协议和底层传输被拆分,更多内容(如 brutal)详见底层传输的 [hysteriaSettings](../transports/hysteria.md) [finalmask.quicParams](../transport.md#quicParams) + +::: tip +`hysteria protocol` 本身无认证,搭配非 `hysteria` 传输层将无法代理 `udp`,也不推荐搭配其他传输层 +::: ## OutboundConfigurationObject diff --git a/docs/config/transport.md b/docs/config/transport.md index d3c3f9dfe1..0082d7b512 100644 --- a/docs/config/transport.md +++ b/docs/config/transport.md @@ -21,7 +21,9 @@ "wsSettings": {}, "httpupgradeSettings": {}, "finalmask": { - "udp": [] + "tcp": [], + "udp": [], + "quicParams": {} }, "sockopt": { "mark": 0, @@ -917,105 +919,368 @@ RFC-8305 中的 "First Address Family count", 默认值为 1. 它定义了对不 FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对流量进行最后一层伪装。 -目前仅有 UDP 支持。 - ```json { + "tcp": [ + { + "type": "", + "settings": {} + } + ], "udp": [ { - "type": "header-dns", - "settings": { - "domain": "www.baidu.com" - } + "type": "", + "settings": {} } + ], + "quicParams": { + "congestion": "force-brutal", + "debug": false, + "brutalUp": "60 mbps", + "brutalDown": 0, + "udpHop": { + "ports": "20000-50000", + "interval": "5-10" + }, + "initStreamReceiveWindow": 8388608, + "maxStreamReceiveWindow": 8388608, + "initConnectionReceiveWindow": 20971520, + "maxConnectionReceiveWindow": 20971520, + "maxIdleTimeout": 30, + "keepAlivePeriod": 0, + "disablePathMTUDiscovery": false, + "maxIncomingStreams": 1024 + } +} +``` + +> `tcp[n].type`: header-custom | fragment | sudoku + +数组第一个为最外层伪装。 + +用于搭配 raw | httpupgarde | websocket | grpc | xhttp 传输层。 + +`header-custom`: + +`fragment`: + +`sudoku`: + +> `tcp[n].settings`: header-custom | fragment | sudoku + +#### header-custom + +```json +{ + "clients": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] + ], + "servers": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] + ], + "errors": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] ] } ``` -> `udp`: \[ list \] +`clients[n][m].delay`: 单位毫秒,为 0 则于前面的粘包发送。 -一个数组,表示应用于 UDP 流量的伪装列表。多个伪装会按顺序一层层应用。 +`clients[n][m].rand`: 添加指定长度随机字节,与 `packet` 冲突。 -settings 根据伪装类型不同,见下。 +`clients[n][m].randRange`: 随机字节范围,默认 0-255。 -> `mkcp-original` +`clients[n][m].type`: `packet` 类型,`array | str | hex | base64`,默认为 array。 -mKCP 曾经默认应用的简单混淆,你可能需要配置它来连接以前的 mKCP 服务器。无额外配置。 +`clients[n][m].packet`: 添加固定数据,与 `rand` 冲突。 -> `mkcp-aes128gcm` +#### fragment -对应原 mKCP 的 `seed` 功能。使用 AES-128-GCM 进行混淆。 +```json +{ + "packets": "tlshello", + "length": "100-200", + "delay": "10-20", + "maxSplit": "3-6" +} +``` -- `settings`: - ```json - { - "password": "your-password" - } - ``` +#### sudoku -`password` 为加密密码,服务端客户端需一致。 +```json +{ + "password": "", + "ascii": "", -> `header-dns` + "customTable": "", + "customTables": [""], -原 mKCP 的 DNS 伪装。某些校园网在未登录的情况下允许 DNS 查询,给 KCP 添加 DNS 头。 + "paddingMin": 0, + "paddingMax": 0 +} +``` -- `settings`: - ```json - { - "domain": "www.example.com" - } - ``` +> `udp[n].type`: header-custom | header-dns | header-dtls | header-srtp | header-utp | header-wechat | header-wireguard | mkcp-original | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp -`domain` 为用于伪装的域名。 +数组第一个为最外层伪装。 -> `header-dtls` +用于搭配 raw udp | kcp | hysteria | xhttp h3 传输层。 -原 mKCP 的 DTLS 伪装。伪装成 DTLS 1.2 数据包。无额外配置。 +`header-custom`: 总是合包到数据包头。 -> `header-srtp` +`header-dns`: 原 mKCP 的 DNS 伪装。某些校园网在未登录的情况下允许 DNS 查询,给 KCP 添加 DNS 头。 -原 mKCP 的 SRTP 伪装。伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。无额外配置。 +`header-dtls`: 原 mKCP 的 DTLS 伪装。伪装成 DTLS 1.2 数据包。无额外配置。 -> `header-utp` +`header-srtp`: 原 mKCP 的 SRTP 伪装。伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。无额外配置。 -原 mKCP 的 uTP 伪装。伪装成 uTP 数据包,会被识别为 BT 下载数据。无额外配置。 +`header-utp`: 原 mKCP 的 uTP 伪装。伪装成 uTP 数据包,会被识别为 BT 下载数据。无额外配置。 -> `header-wechat` +`header-wechat`: 原 mKCP 的 WeChat Video 伪装。伪装成微信视频通话的数据包。无额外配置。 -原 mKCP 的 WeChat Video 伪装。伪装成微信视频通话的数据包。无额外配置。 +`header-wireguard`: 原 mKCP 的 WireGuard 伪装。伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)无额外配置。 -> `header-wireguard` +`mkcp-original`: mKCP 曾经默认应用的简单混淆,你可能需要配置它来连接以前的 mKCP 服务器。无额外配置。 -原 mKCP 的 WireGuard 伪装。伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)无额外配置。 +`mkcp-aes128gcm`: 对应原 mKCP 的 `seed` 功能。使用 AES-128-GCM 进行混淆。 -> `xdns` +`noise`: 在发送数据前发送的噪声。 -实验性功能,利用 DNS 查询来传输数据(类似 DNSTT)。它将执行标准的 DNS TXT 查询来传输载荷。 +`salamander`: Salamander 混淆。(来自 Hysteria2) -由于技术限制,它给出的 MTU 非常小,无法使用 QUIC,建议搭配 mKCP 使用。推荐的 MTU 值:客户端 130,服务端 900。 +`sudoku`: -- `settings`: - ```json - { - "domain": "www.example.com" - } - ``` +`xdns`: 利用 DNS 查询来传输数据(类似 DNSTT)。它将执行标准的 DNS TXT 查询来传输载荷。 -`domain` 为用于查询的域名。 +由于技术限制,它给出的 MTU 非常小,无法使用 QUIC,建议搭配 mKCP 使用。推荐的 MTU 值:客户端 130,服务端 900。 因为执行的查询是标准的,它可以透过任何 UDP DNS 服务器进行转发,尽管效率可能十分不理想。 要使用这个功能,需要服务端监听 53 端口,然后代理协议将目标指向一个 DNS 服务器(如 8.8.8.8:53),并且你拥有 `domain` 的域名,然后将其 NS 记录指向服务端。 -> `salamander` +比如持有 example.com,那么设置 a.example.com A记录 指向 ip,设置 t.example.com NS记录 指向 t.example.com,最后使用的是 t.example.com。设置 A记录 的不能为 NS记录 的子域。 -Salamander 混淆。(来自 Hysteria2) +`xicmp`: -- `settings`: - ```json - { - "password": "your-password" - } - ``` +> `udp[n].settings`: header-custom | header-dns | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp + +#### header-custom + +```json +{ + "client": [ + { + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ], + "server": [ + { + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] +} +``` + +`client[n].rand`: 添加指定长度随机字节,与 `packet` 冲突。 + +`client[n].randRange`: 随机字节范围,默认 0-255。 + +`client[n].type`: `packet` 类型,`array | str | hex | base64`,默认为 array。 + +`client[n].packet`: 添加固定数据,与 `rand` 冲突。 + +#### header-dns + +```json +{ + "domain": "www.example.com" +} +``` + +#### mkcp-aes128gcm + +```json +{ + "password": "your-password" +} +``` + +#### noise + +```json +{ + "reset": 0, + "noise": [ + { + "rand": "1-8192", + "randRange": "0-255", + "type": "", + "packet": [], + "delay": "10-20" + } + ] +} +``` + +`noise[n].rand`: 添加随机或指定长度随机字节,与 `packet` 冲突。 + +`noise[n].randRange`: 随机字节范围,默认 0-255。 + +`noise[n].type`: `packet` 类型,`array | str | hex | base64`,默认为 array。 + +`noise[n].packet`: 添加固定数据,与 `rand` 冲突 + +`noise[n].delay`: 单位毫秒,发送噪声后延迟指定时间后再发下一个。 + +#### salamander + +```json +{ + "password": "your-password" +} +``` + +#### sudoku + +```json +{ + "password": "", + "ascii": "", + + "customTable": "", + "customTables": [""], + + "paddingMin": 0, + "paddingMax": 0 +} +``` + +#### xdns + +```json +{ + "domain": "www.example.com" +} +``` + +#### xicmp + +```json +{ + "listenIp": "0.0.0.0", + "id": 0 +} +``` + +> `quicParams`: [quicParamsObject](#quicParams) + +#### quicParams + +```json +{ + "congestion": "force-brutal", + "debug": false, + "brutalUp": "60 mbps", + "brutalDown": 0, + "udpHop": { + "ports": "20000-50000", + "interval": "5-10" + }, + "initStreamReceiveWindow": 8388608, + "maxStreamReceiveWindow": 8388608, + "initConnectionReceiveWindow": 20971520, + "maxConnectionReceiveWindow": 20971520, + "maxIdleTimeout": 30, + "keepAlivePeriod": 0, + "disablePathMTUDiscovery": false, + "maxIncomingStreams": 1024 +} +``` + +> `congestion`: reno | bbr | brutal | force-brutal + +> `debug`: false | true + +启用 bbr/brutal congestion control 日志。 + +> `brutalUp`: string + +> `brutalDown`: string + +限制的上传/下载速率。默认值为 0。 + +格式用户友好,支持各种常见的比特每秒写法,包括 `1000000` `100kb` `20 mb` `100 mbps` `1g` `1 tbps` 等等等,大小写不敏感,单位之间可以带或者不带空格,无单位时默认为 bps(比特每秒),不能低于 65535 bps。 + +协商行为和 Hysteria 原版一致: + +服务端的值将限制客户端可以选择的最大 Brutal 模式速率,为 0 表示不限制客户端。 + +客户端为 0 则表示使用 BBR 模式,不为 0 则表示使用 Brutal 模式,会受到服务端的限制。 + +注意相对论,服务端的上传是客户端的下载,服务端的下载是客户端的上传。 + +> `udpHop`: {"ports": string, "interval": number} + +UDP 端口跳跃配置。 + +ports 为跳跃的端口范围,可以是一个数值类型的字符串,如 `"1234"`;或者一个数值范围,如 `"1145-1919"` 表示端口 1145 到端口 1919,这 775 个端口。可以使用逗号进行分段,如 `11,13,15-17` 表示端口 11、端口 13、端口 15 到端口 17 这 5 个端口。 + +interval 为端口跳跃间隔,单位为秒,至少为 5,默认 30 秒。 + +> `initStreamReceiveWindow`: number + +> `maxStreamReceiveWindow`: number + +> `initConnectionReceiveWindow`: number + +> `maxConnectionReceiveWindow`: number + +这四个为具体的 QUIC 窗口参数,**除非你完全明白自己在做什么,否则不建议修改这些值**。如果要改,建议保持流接收窗口与连接接收窗口的比例为 2:5 + +> `maxIdleTimeout`: number + +最长空闲超时时间(秒)。服务器会在多长时间没有收到任何客户端数据后关闭连接,范围为 4~120 秒,默认为 30 秒。 + +> `keepAlivePeriod`: number + +QUIC KeepAlive 间隔(秒)。范围为 2~60 秒。默认禁用。 + +> `disablePathMTUDiscovery`: bool + +是否禁用路径 MTU 发现。 + +其他实现里对于 !linux && !windows && !darwin OS 为强制禁用,xray 里则非强制,如果你为非 (linux || windows || darwin) 可能需要手动禁用。 + +> `maxIncomingStreams`: number -`password` 为混淆密码,服务端客户端需一致。 +服务端参数,如果设置则不得小于 8 diff --git a/docs/config/transports/hysteria.md b/docs/config/transports/hysteria.md index 2358aec634..661e591555 100644 --- a/docs/config/transports/hysteria.md +++ b/docs/config/transports/hysteria.md @@ -1,6 +1,14 @@ # Hysteria -Hysteria2 的底层 QUIC 传输的 Xray 实现,通常需要搭配 [hysteria2 出站](../outbounds/hysteria.md) 使用。 +::: tip +搭配 `hysteria protocol` 时默认启用 `quic native udp` + +搭配 `hysteria inbound` 时 `auth` 将会被 `clients` 覆盖 (如果存在) + +搭配其他 `protocol` 能否代理 `udp` 取决于该 `protocol` 是否具有 `uot` 能力 + +启用 `finalmask.udp` 后将会破坏 `masquerade` 的页面伪装 +::: ## HysteriaObject @@ -10,19 +18,22 @@ Hysteria2 的底层 QUIC 传输的 Xray 实现,通常需要搭配 [hysteria2 { "version": 2, "auth": "password", - "up": "0", - "down": "0", - "udphop": { - "port": "1145-1919", - "interval": 30 - }, - "initStreamReceiveWindow": 8388608, - "maxStreamReceiveWindow": 8388608, - "initConnectionReceiveWindow": 20971520, - "maxConnectionReceiveWindow": 20971520, - "maxIdleTimeout": 30, - "keepAlivePeriod": 0, - "disablePathMTUDiscovery": false + "udpIdleTimeout": 60, + "masquerade": { + "type": "", + + "dir": "", + + "url": "", + "rewriteHost": false, + "insecure": false, + + "content": "", + "headers": { + "key": "value" + }, + "statusCode": 0 + } } ``` @@ -34,48 +45,64 @@ Hysteria 版本,必须为 2。 Hysteria 认证密码,服务端和客户端需要保持一致。 -> `up`: string +> `udpIdleTimeout`: number + +单位秒,默认 60。 + +单条 udp 连接空闲等待时间,过大应该不会严格遵守,可能会先被 policy 掐断。 -> `down`: string +> `masquerade`: [MasqObject](#MasqObject) -限制的上传/下载速率。默认值为 0. +http3 页面伪装。 -格式用户友好,支持各种常见的比特每秒写法,包括 `1000000` `100kb` `20 mb` `100 mbps` `1g` `1 tbps` 等等等,大小写不敏感,单位之间可以带或者不带空格,无单位时默认为 bps(比特每秒),不能低于 65535 bps。 +### MasqObject -协商行为和 Hysteria 原版一致: +```json +{ + "type": "", + + "dir": "", -服务端的值将限制客户端可以选择的最大 Brutal 模式速率,为 0 表示不限制客户端。 + "url": "", + "rewriteHost": false, + "insecure": false, -客户端为 0 则表示使用 BBR 模式,不为 0 则表示使用 Brutal 模式,会受到服务端的限制。 + "content": "", + "headers": { + "key": "value" + }, + "statusCode": 0 +} +``` -注意相对论,服务端的上传是客户端的下载,服务端的下载是客户端的上传。 +> `type`: "file" | "proxy" | "string" -> `udphop`: {"port": string, "interval": number} +不填为默认的 404 页面。 -UDP 端口跳跃配置。 +> `dir`: string -port 为跳跃的端口范围,可以是一个数值类型的字符串,如 `"1234"`;或者一个数值范围,如 `"1145-1919"` 表示端口 1145 到端口 1919,这 775 个端口。可以使用逗号进行分段,如 `11,13,15-17` 表示端口 11、端口 13、端口 15 到端口 17 这 5 个端口。 +type 为 file 时的配置项。 -interval 为端口跳跃间隔,单位为秒,至少为 5,默认 30 秒。 +> `url`: string -> `initStreamReceiveWindow`: number +type 为 proxy 时的配置项。 -> `maxStreamReceiveWindow`: number +> `rewriteHost`: false | true -> `initConnectionReceiveWindow`: number +type 为 proxy 时的配置项。 -> `maxConnectionReceiveWindow`: number +> `insecure`: false | true -这四个为具体的 QUIC 窗口参数,**除非你完全明白自己在做什么,否则不建议修改这些值**。如果要改,建议保持流接收窗口与连接接收窗口的比例为 2:5 +type 为 proxy 时的配置项。 -> `maxIdleTimeout`: number +> `content`: string -最长空闲超时时间(秒)。服务器会在多长时间没有收到任何客户端数据后关闭连接,范围为 4~120 秒,默认为 30 秒。 +type 为 string 时的配置项。 -> `keepAlivePeriod`: number +> `headers`: map{ string, string } -QUIC KeepAlive 间隔(秒)。范围为 2~60 秒。默认禁用。 +type 为 string 时的配置项。 -> `disablePathMTUDiscovery`: bool +> `statusCode`: int -是否禁用路径 MTU 发现。 +type 为 string 时的配置项。 diff --git a/docs/en/config/inbound.md b/docs/en/config/inbound.md index c7a6e23f41..3412027a11 100644 --- a/docs/en/config/inbound.md +++ b/docs/en/config/inbound.md @@ -54,7 +54,7 @@ When only one port is specified, Xray will listen for inbound connections on thi Note that listening on a port is a relatively expensive operation. Listening on a port range that is too large may cause a significant increase in resource usage or even cause Xray to fail to work properly. Generally speaking, problems may begin to appear when the number of listening ports approaches four digits. If you need to use a very large range, please consider using iptables for redirection instead of setting it here. -> `protocol`: "dokodemo-door" | "http" | "shadowsocks" | "socks" | "vless" | "vmess" | "trojan" | "wireguard" +> `protocol`: "dokodemo-door" | "http" | "shadowsocks" | "socks" | "vless" | "vmess" | "trojan" | "wireguard" | "hysteria" Connection protocol name. See the list of available [Inbound Protocols](./inbounds/) on the left. diff --git a/docs/en/config/inbounds/hysteria.md b/docs/en/config/inbounds/hysteria.md new file mode 100644 index 0000000000..d190f2d4e2 --- /dev/null +++ b/docs/en/config/inbounds/hysteria.md @@ -0,0 +1,52 @@ +# Hysteria + +::: tip +The `hysteria protocol` itself has no authentication; `clients` only take effect when used with the `hysteria` transport layer. +::: + +## InboundConfigurationObject + +```json +{ + "version": 2, + "clients": [ + { + "auth": "5783a3e7-e373-51cd-8642-c83782b807c5", + "level": 0, + "email": "love@xray.com" + } + ] +} +``` + +> `version`: number + +Hysteria version, must be 2. + +> `clients`: \[ [ClientObject](#clientobject) \] + +An array representing a group of users approved by the server. + +### ClientObject + +```json +{ + "auth": "5783a3e7-e373-51cd-8642-c83782b807c5", + "level": 0, + "email": "love@xray.com" +} +``` + +> `auth`: string + +A string of any length. + +> `level`: number + +User level. The connection will use the [local policy](../policy.md#levelpolicyobject) corresponding to this user level. + +The value of `level` corresponds to the `level` value in [policy](../policy.md#policyobject). If not specified, the default is 0. + +> `email`: string + +User email, used to distinguish traffic from different users (reflected in logs and statistics). diff --git a/docs/en/config/inbounds/index.md b/docs/en/config/inbounds/index.md index b6403813dd..49d4d22060 100644 --- a/docs/en/config/inbounds/index.md +++ b/docs/en/config/inbounds/index.md @@ -10,4 +10,5 @@ Xray supports the following inbound protocols: - [VLESS (XTLS Vision Seed)](vless.md) - [VMess](vmess.md) - [WireGuard](wireguard.md) +- [Hysteria](hysteria.md) - [TUN](tun.md) diff --git a/docs/en/config/outbounds/hysteria.md b/docs/en/config/outbounds/hysteria.md index 7d60118e62..bc4685e7c5 100644 --- a/docs/en/config/outbounds/hysteria.md +++ b/docs/en/config/outbounds/hysteria.md @@ -2,7 +2,11 @@ Client implementation of the Hysteria protocol. -This page is very simple because the Hysteria protocol is actually composed of a simple proxy control protocol and a tuned QUIC underlying transport. In Xray, the proxy protocol and the underlying transport are separated. For more details (such as `brutal`), please refer to [hysteriaSettings](../transports/hysteria.md) in the underlying transport section. +This page is very simple because the Hysteria protocol is actually composed of a simple proxy control protocol and a tuned QUIC underlying transport. In Xray, the proxy protocol and the underlying transport are separated. For more details (such as `brutal`), please refer to [hysteriaSettings](../transports/hysteria.md) [finalmask.quicParams](../transport.md#quicParams) in the underlying transport section. + +::: tip +The `hysteria protocol` itself has no authentication. When using with a non `hysteria` transport layer, it will be unable to proxy `udp`, and using it with other transport layers is not recommended. +::: ## OutboundConfigurationObject diff --git a/docs/en/config/transport.md b/docs/en/config/transport.md index 86bdb95a4b..59c6bb9559 100644 --- a/docs/en/config/transport.md +++ b/docs/en/config/transport.md @@ -21,7 +21,9 @@ Transport specifies a stable method for data transmission. Generally, both ends "wsSettings": {}, "httpupgradeSettings": {}, "finalmask": { - "udp": [] + "tcp": [], + "udp": [], + "quicParams": {} }, "sockopt": { "mark": 0, @@ -906,93 +908,362 @@ FinalMask applies a final layer of obfuscation to the traffic after the core has ```json { + "tcp": [ + { + "type": "", + "settings": {} + } + ], "udp": [ { - "type": "header-dns", - "settings": { - "domain": "[www.baidu.com](https://www.baidu.com)" - } + "type": "", + "settings": {} } + ], + "quicParams": { + "congestion": "force-brutal", + "debug": false, + "brutalUp": "60 mbps", + "brutalDown": 0, + "udpHop": { + "ports": "20000-50000", + "interval": "5-10" + }, + "initStreamReceiveWindow": 8388608, + "maxStreamReceiveWindow": 8388608, + "initConnectionReceiveWindow": 20971520, + "maxConnectionReceiveWindow": 20971520, + "maxIdleTimeout": 30, + "keepAlivePeriod": 0, + "disablePathMTUDiscovery": false, + "maxIncomingStreams": 1024 + } +} +``` + +> `tcp[n].type`: header-custom | fragment | sudoku + +The first element in the array is the outermost camouflage. + +Used in conjunction with raw | httpupgarde | websocket | gRPC | xhttp transport layers. + +`header-custom`: + +`fragment`: + +`sudoku`: + +> `tcp[n].settings`: header-custom | fragment | sudoku + +#### header-custom + +```json +{ + "clients": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] + ], + "servers": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] + ], + "errors": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] ] } ``` -> `udp`: \[ list \] +`clients[n][m].delay`: The unit is milliseconds; a value of 0 indicates that the packet was previously sent in a fragmented manner. -An array representing the list of obfuscations applied to UDP traffic. Multiple obfuscations will be applied sequentially, layer by layer. The `settings` vary depending on the obfuscation type; see below. +`clients[n][m].rand`: Adds a specified length of random bytes, which conflicts with `packet`. -> `mkcp-original` +`clients[n][m].randRange`: Random byte range, default 0-255. -The simple obfuscation that was previously applied by default in mKCP. You may need to configure this to connect to legacy mKCP servers. No additional configuration required. +`clients[n][m].type`: The `packet` type can be `array | str | hex | base64`, with the default being array. -> `mkcp-aes128gcm` +`clients[n][m].packet`: Adding fixed data conflicts with `rand`. -Corresponds to the original mKCP `seed` feature. Uses AES-128-GCM for obfuscation. +#### fragment -- `settings`: - ```json - { - "password": "your-password" - } - ``` +```json +{ + "packets": "tlshello", + "length": "100-200", + "delay": "10-20", + "maxSplit": "3-6" +} +``` -`password` is the encryption password; it must be consistent between the server and the client. +#### sudoku -> `header-dns` +```json +{ + "password": "", + "ascii": "", -Original mKCP DNS obfuscation. Some campus networks allow DNS queries without login, add DNS header to KCP. + "customTable": "", + "customTables": [""], -- `settings`: - ```json - { - "domain": "[www.example.com](https://www.example.com)" - } - ``` + "paddingMin": 0, + "paddingMax": 0 +} +``` -`domain` is the domain name used for obfuscation. +> `udp[n].type`: header-custom | header-dns | header-dtls | header-srtp | header-utp | header-wechat | header-wireguard | mkcp-original | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp -> `header-dtls` +The first element in the array is the outermost camouflage. -Original mKCP DTLS obfuscation. Obfuscates as DTLS 1.2 packets. No additional configuration required. +Used in conjunction with raw udp | kcp | hysteria | xhttp h3 transport layers. -> `header-srtp` +`header-custom`: Always merge packets into the data packet header. -Original mKCP SRTP obfuscation. Obfuscates as SRTP packets, will be recognized as video call data (e.g., FaceTime). No additional configuration required. +`header-dns`: Original mKCP DNS obfuscation. Some campus networks allow DNS queries without login, add DNS header to KCP. -> `header-utp` +`header-dtls`: Original mKCP DTLS obfuscation. Obfuscates as DTLS 1.2 packets. No additional configuration required. -Original mKCP uTP obfuscation. Obfuscates as uTP packets, will be recognized as BT download data. No additional configuration required. +`header-srtp`: Original mKCP SRTP obfuscation. Obfuscates as SRTP packets, will be recognized as video call data (e.g., FaceTime). No additional configuration required. -> `header-wechat` +`header-utp`: Original mKCP uTP obfuscation. Obfuscates as uTP packets, will be recognized as BT download data. No additional configuration required. -Original mKCP WeChat Video obfuscation. Obfuscates as WeChat video call data. No additional configuration required. +`header-wechat`: Original mKCP WeChat Video obfuscation. Obfuscates as WeChat video call data. No additional configuration required. -> `header-wireguard` +`header-wireguard`: Original mKCP WireGuard obfuscation. Obfuscates as WireGuard packets. (Not the real WireGuard protocol) No additional configuration required. -Original mKCP WireGuard obfuscation. Obfuscates as WireGuard packets. (Not the real WireGuard protocol) No additional configuration required. +`mkcp-original`: The simple obfuscation that was previously applied by default in mKCP. You may need to configure this to connect to legacy mKCP servers. No additional configuration required. -> `xdns` +`mkcp-aes128gcm`: Corresponds to the original mKCP `seed` feature. Uses AES-128-GCM for obfuscation. -Experimental feature. Utilizes DNS queries to transport data (similar to DNSTT). It performs standard DNS TXT queries to transport the payload. Due to technical limitations, the resulting MTU is very small, making it incompatible with QUIC; it is recommended to use it with mKCP. Recommended MTU values: Client 130, Server 900. +`noise`: Noise sent before data is transmitted. -- `settings`: - ```json - { - "domain": "[www.example.com](https://www.example.com)" - } - ``` +`salamander`: Salamander obfuscation (from Hysteria2). + +`sudoku`: + +`xdns`: Utilizes DNS queries to transport data (similar to DNSTT). It performs standard DNS TXT queries to transport the payload. Due to technical limitations, the resulting MTU is very small, making it incompatible with QUIC; it is recommended to use it with mKCP. Recommended MTU values: Client 130, Server 900. `domain` is the domain name used for queries. Since the queries performed are standard, they can be forwarded through any UDP DNS server, although efficiency may be very suboptimal. To use this feature, the server needs to listen on port 53, and the proxy protocol should direct the target to a DNS server (e.g., 8.8.8.8:53). Additionally, you must own the domain specified in `domain` and point its NS record to your server. -> `salamander` +For example, if you own example.com, then you can set an A record for a.example.com pointing to the IP address, set an NS record for t.example.com pointing to t.example.com, and ultimately use t.example.com. The A record cannot be a subdomain of an NS record. -Salamander obfuscation (from Hysteria2). +`xicmp`: -- `settings`: - ```json - { - "password": "your-password" - } - ``` +> `udp[n].settings`: header-custom | header-dns | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp + +#### header-custom + +```json +{ + "client": [ + { + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ], + "server": [ + { + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] +} +``` + +`client[n].rand`: Adds a specified length of random bytes, which conflicts with `packet`. + +`client[n].randRange`: Random byte range, default 0-255. + +`client[n].type`: The `packet` type can be `array | str | hex | base64`, with the default being array. + +`client[n].packet`: Adding fixed data conflicts with `rand`. + +#### header-dns + +```json +{ + "domain": "www.example.com" +} +``` + +#### mkcp-aes128gcm + +```json +{ + "password": "your-password" +} +``` + +#### noise + +```json +{ + "reset": 0, + "noise": [ + { + "rand": "1-8192", + "randRange": "0-255", + "type": "", + "packet": [], + "delay": "10-20" + } + ] +} +``` + +`noise[n].rand`: Adds random or specified length of random bytes, which conflicts with `packet`. + +`noise[n].randRange`: Random byte range, default 0-255. + +`noise[n].type`: The `packet` type can be `array | str | hex | base64`, with the default being array. + +`noise[n].packet`: Adding fixed data conflicts with `rand`. + +`noise[n].delay`: The unit is milliseconds. After sending one noise signal, a specified time is delayed before sending the next one. + +#### salamander + +```json +{ + "password": "your-password" +} +``` + +#### sudoku + +```json +{ + "password": "", + "ascii": "", + + "customTable": "", + "customTables": [""], + + "paddingMin": 0, + "paddingMax": 0 +} +``` + +#### xdns + +```json +{ + "domain": "www.example.com" +} +``` + +#### xicmp + +```json +{ + "listenIp": "0.0.0.0", + "id": 0 +} +``` + +> `quicParams`: [quicParamsObject](#quicParams) + +#### quicParams + +```json +{ + "congestion": "force-brutal", + "debug": false, + "brutalUp": "60 mbps", + "brutalDown": 0, + "udpHop": { + "ports": "20000-50000", + "interval": "5-10" + }, + "initStreamReceiveWindow": 8388608, + "maxStreamReceiveWindow": 8388608, + "initConnectionReceiveWindow": 20971520, + "maxConnectionReceiveWindow": 20971520, + "maxIdleTimeout": 30, + "keepAlivePeriod": 0, + "disablePathMTUDiscovery": false, + "maxIncomingStreams": 1024 +} +``` + +> `congestion`: reno | bbr | brutal | force-brutal + +> `debug`: false | true + +Enable bbr/brutal congestion control logging. + +> `brutalUp`: string + +> `brutalDown`: string + +Upload/Download rate limits. Default is 0. + +The format is user-friendly and supports various common bit-per-second notations, including `1000000`, `100kb`, `20 mb`, `100 mbps`, `1g`, `1 tbps`, etc. It is case-insensitive, and spaces between the number and unit are optional. If no unit is specified, it defaults to bps (bits per second). It cannot be lower than 65535 bps. + +The negotiation behavior is consistent with the original Hysteria: + +The server's value limits the maximum Brutal mode rate that the client can choose. 0 means no limit on the client. + +If the client sets this to 0, it uses BBR mode. If not 0, it uses Brutal mode, subject to the server's limit. + +Note relativity: Server upload is client download, and server download is client upload. + +> `udpHop`: {"ports": string, "interval": number} + +UDP port hopping configuration. + +`ports` is the port range for hopping. It can be a numeric string, such as `"1234"`; or a numeric range, such as `"1145-1919"` (indicating ports 1145 to 1919, totaling 775 ports). Commas can be used for segmentation, such as `11,13,15-17` (indicating port 11, port 13, and ports 15 to 17, totaling 5 ports). + +`interval` is the port hopping interval in seconds. Minimum is 5, default is 30 seconds. + +> `initStreamReceiveWindow`: number + +> `maxStreamReceiveWindow`: number + +> `initConnectionReceiveWindow`: number + +> `maxConnectionReceiveWindow`: number + +These four are specific QUIC window parameters. **Unless you fully understand what you are doing, it is not recommended to modify these values.** If you must modify them, it is recommended to keep the ratio of the stream receive window to the connection receive window at 2:5. + +> `maxIdleTimeout`: number + +Maximum idle timeout (seconds). The server will close the connection if no data is received from the client for this duration. Range: 4~120 seconds. Default: 30 seconds. + +> `keepAlivePeriod`: number + +QUIC KeepAlive interval (seconds). Range: 2~60 seconds. Disabled by default. + +> `disablePathMTUDiscovery`: bool + +Whether to disable Path MTU Discovery. + +In other implementations, !linux && !windows && !darwin OS are forcibly disabled, while in xray it is not mandatory. If your OS is not (linux || windows || darwin), you may need to disable it manually. + +> `maxIncomingStreams`: number -`password` is the obfuscation password; it must be consistent between the server and the client. +Server-side parameters, if set, must not be less than 8. diff --git a/docs/en/config/transports/hysteria.md b/docs/en/config/transports/hysteria.md index 7939bf1152..d2188770b1 100644 --- a/docs/en/config/transports/hysteria.md +++ b/docs/en/config/transports/hysteria.md @@ -1,6 +1,14 @@ # Hysteria -The Xray implementation of Hysteria2's underlying QUIC transport. It is usually used in conjunction with [hysteria2 outbound](../outbounds/hysteria.md). +::: tip +When used with the `hysteria protocol`, `quic native udp` is enabled by default. + +When used with `hysteria inbound`, `auth` will be overridden by `clients` (if it exists). + +Whether other `protocols` can proxy `udp` depends on whether that `protocol` has `uot` capabilities. + +Enabling `finalmask.udp` will break the `masquerade` page masquerading. +::: ## HysteriaObject @@ -10,19 +18,22 @@ The Xray implementation of Hysteria2's underlying QUIC transport. It is usually { "version": 2, "auth": "password", - "up": "0", - "down": "0", - "udphop": { - "port": "1145-1919", - "interval": 30 - }, - "initStreamReceiveWindow": 8388608, - "maxStreamReceiveWindow": 8388608, - "initConnectionReceiveWindow": 20971520, - "maxConnectionReceiveWindow": 20971520, - "maxIdleTimeout": 30, - "keepAlivePeriod": 0, - "disablePathMTUDiscovery": false + "udpIdleTimeout": 60, + "masquerade": { + "type": "", + + "dir": "", + + "url": "", + "rewriteHost": false, + "insecure": false, + + "content": "", + "headers": { + "key": "value" + }, + "statusCode": 0 + } } ``` @@ -34,48 +45,64 @@ Hysteria version, must be 2. Hysteria authentication password. Must be consistent between the server and the client. -> `up`: string +> `udpIdleTimeout`: number + +Unit: seconds, default 60. + +Idle wait time for a single UDP connection. If this time is too long, it may not be strictly adhered to and may be terminated by the policy first. -> `down`: string +> `masquerade`: [MasqObject](#MasqObject) -Upload/Download rate limits. Default is 0. +HTTP/3 page masquerading. -The format is user-friendly and supports various common bit-per-second notations, including `1000000`, `100kb`, `20 mb`, `100 mbps`, `1g`, `1 tbps`, etc. It is case-insensitive, and spaces between the number and unit are optional. If no unit is specified, it defaults to bps (bits per second). It cannot be lower than 65535 bps. +### MasqObject -The negotiation behavior is consistent with the original Hysteria: +```json +{ + "type": "", + + "dir": "", -The server's value limits the maximum Brutal mode rate that the client can choose. 0 means no limit on the client. + "url": "", + "rewriteHost": false, + "insecure": false, -If the client sets this to 0, it uses BBR mode. If not 0, it uses Brutal mode, subject to the server's limit. + "content": "", + "headers": { + "key": "value" + }, + "statusCode": 0 +} +``` -Note relativity: Server upload is client download, and server download is client upload. +> `type`: "file" | "proxy" | "string" -> `udphop`: {"port": string, "interval": number} +If left blank, the default 404 page will be displayed. -UDP port hopping configuration. +> `dir`: string -`port` is the port range for hopping. It can be a numeric string, such as `"1234"`; or a numeric range, such as `"1145-1919"` (indicating ports 1145 to 1919, totaling 775 ports). Commas can be used for segmentation, such as `11,13,15-17` (indicating port 11, port 13, and ports 15 to 17, totaling 5 ports). +Configuration items when type is file. -`interval` is the port hopping interval in seconds. Minimum is 5, default is 30 seconds. +> `url`: string -> `initStreamReceiveWindow`: number +Configuration items when type is proxy. -> `maxStreamReceiveWindow`: number +> `rewriteHost`: false | true -> `initConnectionReceiveWindow`: number +Configuration items when type is proxy. -> `maxConnectionReceiveWindow`: number +> `insecure`: false | true -These four are specific QUIC window parameters. **Unless you fully understand what you are doing, it is not recommended to modify these values.** If you must modify them, it is recommended to keep the ratio of the stream receive window to the connection receive window at 2:5. +Configuration items when type is proxy. -> `maxIdleTimeout`: number +> `content`: string -Maximum idle timeout (seconds). The server will close the connection if no data is received from the client for this duration. Range: 4~120 seconds. Default: 30 seconds. +Configuration items when type is string. -> `keepAlivePeriod`: number +> `headers`: map{ string, string } -QUIC KeepAlive interval (seconds). Range: 2~60 seconds. Disabled by default. +Configuration items when type is string. -> `disablePathMTUDiscovery`: bool +> `statusCode`: int -Whether to disable Path MTU Discovery. +Configuration items when type is string. diff --git a/docs/ru/config/inbound.md b/docs/ru/config/inbound.md index c142ee7ac7..0d33a2ccef 100644 --- a/docs/ru/config/inbound.md +++ b/docs/ru/config/inbound.md @@ -59,7 +59,7 @@ Обратите внимание, что прослушивание порта — это довольно ресурсоемкая операция. Прослушивание слишком большого диапазона портов может привести к значительному увеличению потребляемых ресурсов и даже нарушить нормальную работу Xray. Как правило, проблемы могут начаться, когда количество прослушиваемых портов приближается к четырехзначным числам. Если вам нужен большой диапазон, рассмотрите возможность использования iptables для перенаправления вместо того, чтобы настраивать его здесь. -> `protocol`: "dokodemo-door" | "http" | "shadowsocks" | "mixed" | "vless" | "vmess" | "trojan" | "wireguard" +> `protocol`: "dokodemo-door" | "http" | "shadowsocks" | "mixed" | "vless" | "vmess" | "trojan" | "wireguard" | "hysteria" Название протокола соединения. Список доступных протоколов см. в разделе [Входящие протоколы](./inbounds/) в меню слева. diff --git a/docs/ru/config/inbounds/hysteria.md b/docs/ru/config/inbounds/hysteria.md new file mode 100644 index 0000000000..6fdb14cc92 --- /dev/null +++ b/docs/ru/config/inbounds/hysteria.md @@ -0,0 +1,52 @@ +# Hysteria + +::: tip +Сам протокол `hysteria` не предусматривает аутентификации; `клиенты` начинают действовать только при использовании с транспортным уровнем `hysteria`. +::: + +## InboundConfigurationObject + +```json +{ + "version": 2, + "clients": [ + { + "auth": "5783a3e7-e373-51cd-8642-c83782b807c5", + "level": 0, + "email": "love@xray.com" + } + ] +} +``` + +> `version`: number + +Версия Hysteria, должна быть равна 2. + +> `clients`: \[ [ClientObject](#clientobject) \] + +Массив, представляющий группу пользователей, одобренных сервером. + +### ClientObject + +```json +{ + "auth": "5783a3e7-e373-51cd-8642-c83782b807c5", + "level": 0, + "email": "love@xray.com" +} +``` + +> `auth`: string + +Строка любой длины. + +> `level`: number + +Уровень пользователя, для подключения будет использоваться [локальная политика](../policy.md#levelpolicyobject), соответствующая этому уровню пользователя. + +Значение level соответствует значению `level` в разделе [policy](../policy.md#policyobject). Если не указано, используется значение по умолчанию - 0. + +> `email`: string + +Адрес электронной почты пользователя, используется для разделения трафика разных пользователей (отображается в журналах, статистике). diff --git a/docs/ru/config/inbounds/index.md b/docs/ru/config/inbounds/index.md index 914812ac0a..3e6a36e178 100644 --- a/docs/ru/config/inbounds/index.md +++ b/docs/ru/config/inbounds/index.md @@ -10,4 +10,5 @@ Xray поддерживает следующие входящие протоко - [VLESS (XTLS Vision Seed)](vless.md) - [VMess](vmess.md) - [WireGuard](wireguard.md) +- [Hysteria](hysteria.md) - [TUN](tun.md) diff --git a/docs/ru/config/outbounds/hysteria.md b/docs/ru/config/outbounds/hysteria.md index 61e3d0af2c..928831077d 100644 --- a/docs/ru/config/outbounds/hysteria.md +++ b/docs/ru/config/outbounds/hysteria.md @@ -1,22 +1,31 @@ -# Hysteria2 +# Hysteria -Реализация клиента протокола Hysteria2. +Реализация клиента протокола Hysteria. -Эта страница очень проста, так как протокол hysteria2 фактически разделен на простой протокол управления прокси и оптимизированный низкоуровневый транспорт QUIC. В Xray протокол прокси и низкоуровневый транспорт разделены, подробности см. в разделе [hysteriaSettings](../transports/hysteria.md) низкоуровневого транспорта. +Эта страница очень проста, так как протокол hysteria фактически разделен на простой протокол управления прокси и оптимизированный низкоуровневый транспорт QUIC. В Xray протокол прокси и низкоуровневый транспорт разделены, подробности см. в разделе [hysteriaSettings](../transports/hysteria.md) [finalmask.quicParams](../transport.md#quicParams) низкоуровневого транспорта. + +::: tip +Сам протокол `hysteria` не имеет аутентификации. При использовании с транспортным уровнем, отличным от `hysteria`, он не сможет выступать в качестве прокси для `udp`, и его использование с другими транспортными уровнями не рекомендуется. +::: ## OutboundConfigurationObject ```json { + "version": 2, "address": "192.168.108.1", "port": 3128 } ``` +> `version`: number + +Версия Hysteria, должна быть равна 2. + > `address`: string -Адрес прокси-сервера Hysteria2, обязательно. +Адрес прокси-сервера Hysteria, обязательно. > `port`: int -Порт прокси-сервера Hysteria2, обязательно. +Порт прокси-сервера Hysteria, обязательно. diff --git a/docs/ru/config/outbounds/index.md b/docs/ru/config/outbounds/index.md index 759f370360..48ba882b92 100644 --- a/docs/ru/config/outbounds/index.md +++ b/docs/ru/config/outbounds/index.md @@ -13,4 +13,4 @@ Xray поддерживает следующие исходящие проток - [VLESS (XTLS Vision Seed)](vless.md) - [VMess](vmess.md) - [WireGuard](wireguard.md) -- [Hysteria2](hysteria.md) +- [Hysteria](hysteria.md) diff --git a/docs/ru/config/transport.md b/docs/ru/config/transport.md index cc8d7eb1a3..9d06d03c0c 100644 --- a/docs/ru/config/transport.md +++ b/docs/ru/config/transport.md @@ -22,7 +22,9 @@ "wsSettings": {}, "httpupgradeSettings": {}, "finalmask": { - "udp": [] + "tcp": [], + "udp": [], + "quicParams": {} }, "sockopt": { "mark": 0, @@ -929,89 +931,164 @@ PS: Если трафик домена, например, обычный веб- FinalMask применяет последний слой маскировки к трафику после того, как ядро завершит обработку шифрования транспортного уровня, включая TLS/REALITY. -В настоящее время поддерживается только UDP. - ```json { + "tcp": [ + { + "type": "", + "settings": {} + } + ], "udp": [ { - "type": "header-dns", - "settings": { - "domain": "www.baidu.com" - } + "type": "", + "settings": {} } + ], + "quicParams": { + "congestion": "force-brutal", + "debug": false, + "brutalUp": "60 mbps", + "brutalDown": 0, + "udpHop": { + "ports": "20000-50000", + "interval": "5-10" + }, + "initStreamReceiveWindow": 8388608, + "maxStreamReceiveWindow": 8388608, + "initConnectionReceiveWindow": 20971520, + "maxConnectionReceiveWindow": 20971520, + "maxIdleTimeout": 30, + "keepAlivePeriod": 0, + "disablePathMTUDiscovery": false, + "maxIncomingStreams": 1024 + } +} +``` + +> `tcp[n].type`: header-custom | fragment | sudoku + +Первый элемент в массиве — это самый внешний камуфляж. + +Используется совместно с транспортными уровнями raw | httpupgarde | websocket | gRPC | xhttp. + +`header-custom`: + +`fragment`: + +`sudoku`: + +> `tcp[n].settings`: header-custom | fragment | sudoku + +#### header-custom + +```json +{ + "clients": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] + ], + "servers": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] + ], + "errors": [ + [ + { + "delay": 0, + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] ] } ``` -> `udp`: \[ list \] +`clients[n][m].delay`: Единица измерения — миллисекунды; значение 0 указывает на то, что пакет ранее был отправлен фрагментарно. -Массив, представляющий список маскировок, применяемых к UDP-трафику. Несколько маскировок будут применяться последовательно, слой за слоем. +`clients[n][m].rand`: Добавляет заданную длину случайных байтов, что конфликтует с функцией `packet`. -`settings` зависят от типа маскировки, см. ниже. +`clients[n][m].randRange`: Диапазон случайных байтов, по умолчанию 0-255. -> `mkcp-original` +`clients[n][m].type`: Тип `packet` может быть `array | str | hex | base64`, по умолчанию используется `array`. -Простая обфускация, которая раньше применялась в mKCP по умолчанию; возможно, вам понадобится настроить её для подключения к старым серверам mKCP. Без дополнительных настроек. +`clients[n][m].packet`: Добавление фиксированных данных конфликтует с `rand`. -> `mkcp-aes128gcm` +#### fragment -Соответствует функции `seed` оригинального mKCP. Использует AES-128-GCM для обфускации. +```json +{ + "packets": "tlshello", + "length": "100-200", + "delay": "10-20", + "maxSplit": "3-6" +} +``` -- `settings`: - ```json - { - "password": "your-password" - } - ``` +#### sudoku -`password` — пароль шифрования, он должен совпадать на сервере и клиенте. +```json +{ + "password": "", + "ascii": "", -> `header-dns` + "customTable": "", + "customTables": [""], -DNS-маскировка оригинального mKCP. Некоторые кампусные сети разрешают DNS-запросы без входа; добавляет DNS-заголовок к KCP. + "paddingMin": 0, + "paddingMax": 0 +} +``` -- `settings`: - ```json - { - "domain": "www.example.com" - } - ``` +> `udp[n].type`: header-custom | header-dns | header-dtls | header-srtp | header-utp | header-wechat | header-wireguard | mkcp-original | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp -`domain` — домен, используемый для маскировки. +Первый элемент в массиве — это самый внешний камуфляж. -> `header-dtls` +Используется совместно с транспортными слоями raw udp | kcp | hysteria | xhttp h3. -DTLS-маскировка оригинального mKCP. Маскирует как пакеты DTLS 1.2. Без дополнительных настроек. +`header-custom`: Всегда объединяйте пакеты данных в заголовок пакета. -> `header-srtp` +`header-dns`: DNS-маскировка оригинального mKCP. Некоторые кампусные сети разрешают DNS-запросы без входа; добавляет DNS-заголовок к KCP. -SRTP-маскировка оригинального mKCP. Маскирует как пакеты SRTP, будет распознаваться как данные видеозвонков (например, FaceTime). Без дополнительных настроек. +`header-dtls`: DTLS-маскировка оригинального mKCP. Маскирует как пакеты DTLS 1.2. Без дополнительных настроек. -> `header-utp` +`header-srtp`: SRTP-маскировка оригинального mKCP. Маскирует как пакеты SRTP, будет распознаваться как данные видеозвонков (например, FaceTime). Без дополнительных настроек. -Маскировка uTP оригинального mKCP. Маскирует как uTP-пакеты, будет распознаваться как данные загрузок BT. Без дополнительных настроек. +`header-utp`: Маскировка uTP оригинального mKCP. Маскирует как uTP-пакеты, будет распознаваться как данные загрузок BT. Без дополнительных настроек. -> `header-wechat` +`header-wechat`: Маскировка под WeChat Video оригинального mKCP. Маскирует как данные видеозвонков WeChat. Без дополнительных настроек. -Маскировка под WeChat Video оригинального mKCP. Маскирует как данные видеозвонков WeChat. Без дополнительных настроек. +`header-wireguard`: WireGuard-маскировка оригинального mKCP. Маскирует как пакеты WireGuard. (Не настоящий протокол WireGuard) Без дополнительных настроек. -> `header-wireguard` +`mkcp-original`: Простая обфускация, которая раньше применялась в mKCP по умолчанию; возможно, вам понадобится настроить её для подключения к старым серверам mKCP. Без дополнительных настроек. -WireGuard-маскировка оригинального mKCP. Маскирует как пакеты WireGuard. (Не настоящий протокол WireGuard) Без дополнительных настроек. +`mkcp-aes128gcm`: Соответствует функции `seed` оригинального mKCP. Использует AES-128-GCM для обфускации. -> `xdns` +`noise`: Перед передачей данных отправляется шум. -Экспериментальная функция, использующая DNS-запросы для передачи данных (похоже на DNSTT). Она выполняет стандартные запросы DNS TXT для передачи полезной нагрузки. +`salamander`: Обфускация Salamander (из Hysteria2). -Из-за технических ограничений предоставляемый MTU очень мал, использование QUIC невозможно, рекомендуется использовать в паре с mKCP. Рекомендуемые значения MTU: клиент — 130, сервер — 900. +`sudoku`: -- `settings`: - ```json - { - "domain": "www.example.com" - } - ``` +`xdns`: использующая DNS-запросы для передачи данных (похоже на DNSTT). Она выполняет стандартные запросы DNS TXT для передачи полезной нагрузки. + +Из-за технических ограничений предоставляемый MTU очень мал, использование QUIC невозможно, рекомендуется использовать в паре с mKCP. Рекомендуемые значения MTU: клиент — 130, сервер — 900. `domain` — домен, используемый для запросов. @@ -1019,15 +1096,203 @@ WireGuard-маскировка оригинального mKCP. Маскируе Чтобы использовать эту функцию, сервер должен слушать порт 53, затем протокол прокси должен указывать цель на DNS-сервер (например, 8.8.8.8:53), и вы должны владеть доменом `domain` и направить его NS-запись на сервер. -> `salamander` +Например, если вы являетесь владельцем example.com, вы можете установить запись A для a.example.com, указывающую на IP-адрес, установить запись NS для t.example.com, указывающую на t.example.com, и в конечном итоге использовать t.example.com. Запись A не может быть поддоменом записи NS. -Обфускация Salamander (из Hysteria2). +`xicmp`: -- `settings`: - ```json - { - "password": "your-password" - } - ``` +> `udp[n].settings`: header-custom | header-dns | mkcp-aes128gcm | noise | salamander | sudoku | xdns | xicmp + +#### header-custom + +```json +{ + "client": [ + { + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ], + "server": [ + { + "rand": 0, + "randRange": "0-255", + "type": "", + "packet": [] + } + ] +} +``` + +`client[n].rand`: Добавляет заданную длину случайных байтов, что конфликтует с функцией `packet`. + +`client[n].randRange`: Диапазон случайных байтов, по умолчанию 0-255. + +`client[n].type`: Тип `packet` может быть `array | str | hex | base64`, по умолчанию используется `array`. + +`client[n].packet`: Добавление фиксированных данных конфликтует с `rand`. + +#### header-dns + +```json +{ + "domain": "www.example.com" +} +``` + +#### mkcp-aes128gcm + +```json +{ + "password": "your-password" +} +``` + +#### noise + +```json +{ + "reset": 0, + "noise": [ + { + "rand": "1-8192", + "randRange": "0-255", + "type": "", + "packet": [], + "delay": "10-20" + } + ] +} +``` + +`noise[n].rand`: Добавляет случайные или заданные по длине случайные байты, что конфликтует с `packet`. + +`noise[n].randRange`: Диапазон случайных байтов, по умолчанию 0-255. + +`noise[n].type`: Тип `packet` может быть `array | str | hex | base64`, по умолчанию используется `array`. + +`noise[n].packet`: Добавление фиксированных данных конфликтует с `rand`. + +`noise[n].delay`: Единица измерения — миллисекунды. После отправки одного шумового сигнала перед отправкой следующего проходит заданное время задержки. + +#### salamander + +```json +{ + "password": "your-password" +} +``` + +#### sudoku + +```json +{ + "password": "", + "ascii": "", + + "customTable": "", + "customTables": [""], + + "paddingMin": 0, + "paddingMax": 0 +} +``` + +#### xdns + +```json +{ + "domain": "www.example.com" +} +``` + +#### xicmp + +```json +{ + "listenIp": "0.0.0.0", + "id": 0 +} +``` + +> `quicParams`: [quicParamsObject](#quicParams) + +#### quicParams + +```json +{ + "congestion": "force-brutal", + "debug": false, + "brutalUp": "60 mbps", + "brutalDown": 0, + "udpHop": { + "ports": "20000-50000", + "interval": "5-10" + }, + "initStreamReceiveWindow": 8388608, + "maxStreamReceiveWindow": 8388608, + "initConnectionReceiveWindow": 20971520, + "maxConnectionReceiveWindow": 20971520, + "maxIdleTimeout": 30, + "keepAlivePeriod": 0, + "disablePathMTUDiscovery": false, + "maxIncomingStreams": 1024 +} +``` + +> `congestion`: reno | bbr | brutal | force-brutal + +> `debug`: false | true + +Включить логирование в режиме bbr/brutal congestal control. + +> `brutalUp`: string + +> `brutalDown`: string + +Ограничение скорости загрузки/скачивания (upload/download). Значение по умолчанию 0. + +Формат удобен для пользователя, поддерживает различные распространенные записи бит в секунду, включая `1000000`, `100kb`, `20 mb`, `100 mbps`, `1g`, `1 tbps` и т.д. Регистр не важен, пробелы между единицами необязательны. Без единиц измерения по умолчанию используется bps (бит в секунду), значение не может быть ниже 65535 bps. + +Поведение согласования соответствует оригинальной Hysteria: + +Значение на сервере ограничивает максимальную скорость режима Brutal, которую может выбрать клиент; 0 означает отсутствие ограничений для клиента. + +Если на клиенте 0, используется режим BBR; если не 0, используется режим Brutal, который будет ограничен сервером. + +Обратите внимание на относительность: загрузка (upload) сервера — это скачивание (download) клиента, а скачивание (download) сервера — это загрузка (upload) клиента. + +> `udpHop`: {"ports": string, "interval": number} + +`ports` — это диапазон портов для скачков. Может быть строкой с числом, например `"1234"`; или числовым диапазоном, например `"1145-1919"`, что означает 775 портов от 1145 до 1919. Можно использовать запятые для разделения, например `11,13,15-17` означает 5 портов: 11, 13, и с 15 по 17. + +`interval` — это интервал переключения портов в секундах. Минимальное значение — 5, значение по умолчанию — 30 секунд. + +> `initStreamReceiveWindow`: number + +> `maxStreamReceiveWindow`: number + +> `initConnectionReceiveWindow`: number + +> `maxConnectionReceiveWindow`: number + +Эти четыре параметра являются конкретными параметрами окна QUIC. **Не рекомендуется изменять эти значения, если вы не понимаете полностью, что делаете**. Если вы все же меняете их, рекомендуется сохранять соотношение окна приема потока к окну приема соединения как 2:5. + +> `maxIdleTimeout`: number + +Максимальное время ожидания простоя (в секундах). Через какое время сервер закроет соединение, если не получит никаких данных от клиента. Диапазон 4~120 секунд, по умолчанию 30 секунд. + +> `keepAlivePeriod`: number + +Интервал QUIC KeepAlive (в секундах). Диапазон 2~60 секунд. По умолчанию отключено. + +> `disablePathMTUDiscovery`: bool + +Отключить ли обнаружение Path MTU Discovery. + +В других реализациях команды !linux && !windows && !darwin OS принудительно отключены, тогда как в xray это не является обязательным. Если ваша ОС не (linux || windows || darwin), вам может потребоваться отключить их вручную. + +> `maxIncomingStreams`: number -`password` — пароль обфускации, он должен совпадать на сервере и клиенте. +Если заданы параметры на стороне сервера, их количество не должно быть меньше 8. diff --git a/docs/ru/config/transports/hysteria.md b/docs/ru/config/transports/hysteria.md index 18400938d6..d64a0d9fef 100644 --- a/docs/ru/config/transports/hysteria.md +++ b/docs/ru/config/transports/hysteria.md @@ -1,6 +1,14 @@ # Hysteria -Реализация низкоуровневого транспорта QUIC для Hysteria2 в Xray. Обычно используется в сочетании с [исходящим протоколом hysteria2](../outbounds/hysteria.md). +::: tip +При использовании с протоколом `hysteria`, `quic native udp` включен по умолчанию. + +При использовании с `hysteria inbound`, `auth` будет переопределен `clients` (если он существует). + +Возможность использования других `протоколов` в качестве прокси для `udp` зависит от наличия у этого `протокола` возможностей `uot`. + +Включение `finalmask.udp` нарушит работу маскировки страниц `masquerade`. +::: ## HysteriaObject @@ -10,19 +18,22 @@ { "version": 2, "auth": "password", - "up": "0", - "down": "0", - "udphop": { - "port": "1145-1919", - "interval": "30" - }, - "initStreamReceiveWindow": 8388608, - "maxStreamReceiveWindow": 8388608, - "initConnectionReceiveWindow": 20971520, - "maxConnectionReceiveWindow": 20971520, - "maxIdleTimeout": 30, - "keepAlivePeriod": 0, - "disablePathMTUDiscovery": false + "udpIdleTimeout": 60, + "masquerade": { + "type": "", + + "dir": "", + + "url": "", + "rewriteHost": false, + "insecure": false, + + "content": "", + "headers": { + "key": "value" + }, + "statusCode": 0 + } } ``` @@ -34,46 +45,64 @@ Пароль аутентификации Hysteria, должен совпадать на сервере и клиенте. -> `up`: string +> `udpIdleTimeout`: number -> `down`: string +Единица измерения: секунды, по умолчанию 60. -Ограничение скорости загрузки/скачивания (upload/download). Значение по умолчанию 0. +Время ожидания в режиме ожидания для одного UDP-соединения. Если это время слишком велико, соединение может быть не строго соблюдено и может быть сначала разорвано политикой. -Формат удобен для пользователя, поддерживает различные распространенные записи бит в секунду, включая `1000000`, `100kb`, `20 mb`, `100 mbps`, `1g`, `1 tbps` и т.д. Регистр не важен, пробелы между единицами необязательны. Без единиц измерения по умолчанию используется bps (бит в секунду), значение не может быть ниже 65535 bps. +> `masquerade`: [MasqObject](#MasqObject) -Поведение согласования соответствует оригинальной Hysteria: +Маскировка страниц HTTP/3. -Значение на сервере ограничивает максимальную скорость режима Brutal, которую может выбрать клиент; 0 означает отсутствие ограничений для клиента. +### MasqObject + +```json +{ + "type": "", + + "dir": "", + + "url": "", + "rewriteHost": false, + "insecure": false, + + "content": "", + "headers": { + "key": "value" + }, + "statusCode": 0 +} +``` -Если на клиенте 0, используется режим BBR; если не 0, используется режим Brutal, который будет ограничен сервером. +> `type`: "file" | "proxy" | "string" -Обратите внимание на относительность: загрузка (upload) сервера — это скачивание (download) клиента, а скачивание (download) сервера — это загрузка (upload) клиента. +Если оставить это поле пустым, отобразится стандартная страница ошибки 404. -> `udphop`: {"port": string, "interval": number} +> `dir`: string -Конфигурация скачков портов UDP (UDP port hopping). +Элементы конфигурации, когда `type` равен `file`. -`port` — это диапазон портов для скачков. Может быть строкой с числом, например `"1234"`; или числовым диапазоном, например `"1145-1919"`, что означает 775 портов от 1145 до 1919. Можно использовать запятые для разделения, например `11,13,15-17` означает 5 портов: 11, 13, и с 15 по 17. +> `url`: string -> `initStreamReceiveWindow`: number +Элементы конфигурации, когда `type` имеет значение `proxy`. -> `maxStreamReceiveWindow`: number +> `rewriteHost`: false | true -> `initConnectionReceiveWindow`: number +Элементы конфигурации, когда `type` имеет значение `proxy`. -> `maxConnectionReceiveWindow`: number +> `insecure`: false | true -Эти четыре параметра являются конкретными параметрами окна QUIC. **Не рекомендуется изменять эти значения, если вы не понимаете полностью, что делаете**. Если вы все же меняете их, рекомендуется сохранять соотношение окна приема потока к окну приема соединения как 2:5. +Элементы конфигурации, когда `type` имеет значение `proxy`. -> `maxIdleTimeout`: number +> `content`: string -Максимальное время ожидания простоя (в секундах). Через какое время сервер закроет соединение, если не получит никаких данных от клиента. Диапазон 4~120 секунд, по умолчанию 30 секунд. +Элементы конфигурации, когда `type` имеет значение `string`. -> `keepAlivePeriod`: number +> `headers`: map{ string, string } -Интервал QUIC KeepAlive (в секундах). Диапазон 2~60 секунд. По умолчанию отключено. +Элементы конфигурации, когда `type` имеет значение `string`. -> `disablePathMTUDiscovery`: bool +> `statusCode`: int -Отключить ли обнаружение Path MTU Discovery. +Элементы конфигурации, когда `type` имеет значение `string`.