CN Refactor Transports

This commit is contained in:
Meow
2026-05-09 06:26:55 +08:00
parent 2d64d46210
commit eeca4a15fb
19 changed files with 1373 additions and 1269 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ export const nav: DefaultTheme.Config["nav"] = [
{ text: "基础配置", link: "/config/" },
{ text: "入站协议", link: "/config/inbounds/" },
{ text: "出站协议", link: "/config/outbounds/" },
{ text: "底层传输", link: "/config/transports/" }
{ text: "传输配置", link: "/config/transports/" }
]
},
{
+32 -10
View File
@@ -32,7 +32,7 @@ export const sidebar: DefaultTheme.Config["sidebar"] = {
{ text: "路由", link: "/config/routing.md" },
{ text: "统计信息", link: "/config/stats.md" },
{
text: "传输方式(uTLS、REALITY",
text: "传输配置",
link: "/config/transport.md"
},
{ text: "Metrics", link: "/config/metrics.md" },
@@ -89,20 +89,42 @@ export const sidebar: DefaultTheme.Config["sidebar"] = {
]
},
{
text: "底层传输",
text: "传输配置",
link: "/config/transports/",
collapsed: true,
items: [
{ text: "RAW", link: "/config/transports/raw.md" },
{
text: "XHTTP: Beyond REALITY",
link: "/config/transports/xhttp.md"
text: "传输方式",
items: [
{ text: "RAW", link: "/config/transports/raw.md" },
{
text: "XHTTP: Beyond REALITY",
link: "/config/transports/xhttp.md"
},
{ text: "mKCP", link: "/config/transports/mkcp.md" },
{ text: "gRPC", link: "/config/transports/grpc.md" },
{ text: "WebSocket", link: "/config/transports/websocket.md" },
{
text: "HTTPUpgrade",
link: "/config/transports/httpupgrade.md"
},
{ text: "Hysteria", link: "/config/transports/hysteria.md" }
]
},
{ text: "mKCP", link: "/config/transports/mkcp.md" },
{ text: "gRPC", link: "/config/transports/grpc.md" },
{ text: "WebSocket", link: "/config/transports/websocket.md" },
{ text: "HTTPUpgrade", link: "/config/transports/httpupgrade.md" },
{ text: "Hysteria", link: "/config/transports/hysteria.md" }
{
text: "传输安全",
items: [
{ text: "REALITY", link: "/config/transports/reality.md" },
{ text: "TLS", link: "/config/transports/tls.md" }
]
},
{
text: "附加配置",
items: [
{ text: "FinalMask", link: "/config/transports/finalmask.md" },
{ text: "Sockopt", link: "/config/transports/sockopt.md" }
]
}
]
}
],
+1 -1
View File
@@ -350,7 +350,7 @@ Winter cannot cover the NEXT FUTURE...
## 2022.8.28 <Badge>[v1.5.10](https://github.com/XTLS/Xray-core/releases/tag/v1.5.10)</Badge>
底层传输支持更合理的 TCP Keepalive 配置了。
`sockopt` 支持更合理的 TCP Keepalive 配置了。
## 2022.6.20 <Badge>[v1.5.8](https://github.com/XTLS/Xray-core/releases/tag/v1.5.8)</Badge>
+2 -2
View File
@@ -38,7 +38,7 @@ fallback 也可以将不同类型的流量根据 path 进行分流, 从而实现
`fallbacks` 项是可选的,只能用于 TCP+TLS 传输组合
- 该项有子元素时,[Inbound TLS](../transport.md#tlsobject) 需设置 `"alpn":["http/1.1"]`。\*\*
- 该项有子元素时,[Inbound TLS](../transports/tls.md#tlsobject) 需设置 `"alpn":["http/1.1"]`。\*\*
通常,你需要先设置一组 `alpn``path` 均省略或为空的默认回落,然后再按需配置其它分流。
@@ -56,7 +56,7 @@ VLESS 会把 TLS 解密后首包长度 < 18 或协议版本无效、身份认证
有需要时,VLESS 才会尝试读取 TLS ALPN 协商结果,若成功,输出 info `realAlpn =` 到日志。
用途:解决了 Nginx 的 h2c 服务不能同时兼容 http/1.1 的问题,Nginx 需要写两行 listen,分别用于 1.1 和 h2c。
注意:fallbacks alpn 存在 `"h2"` 时,[Inbound TLS](../transport.md#tlsobject) 需设置 `"alpn":["h2","http/1.1"]`,以支持 h2 访问。
注意:fallbacks alpn 存在 `"h2"` 时,[Inbound TLS](../transports/tls.md#tlsobject) 需设置 `"alpn":["h2","http/1.1"]`,以支持 h2 访问。
::: tip
Fallback 内设置的 `alpn` 是匹配实际协商出的 ALPN,而 Inbound TLS 设置的 `alpn` 是握手时可选的 ALPN 列表,两者含义不同。
+3 -3
View File
@@ -38,7 +38,7 @@
支持填写 Unix domain socket,格式为绝对路径,形如 `"/dev/shm/domain.socket"`,可在开头加 `@` 代表 [abstract](https://www.man7.org/linux/man-pages/man7/unix.7.html)`@@` 则代表带 padding 的 abstract。
填写 Unix domain socket 时,`port``allocate` 将被忽略,协议目前可选 VLESS、VMess、Trojan,仅适用于基于 TCP 的底层传输,如 `tcp` `websocket` `grpc`. 不支持基于 UDP 的传输,如 `mkcp`.
填写 Unix domain socket 时,`port``allocate` 将被忽略,协议目前可选 VLESS、VMess、Trojan,仅适用于基于 TCP 的传输方式,如 `tcp` `websocket` `grpc`. 不支持基于 UDP 的传输,如 `mkcp`.
填写 Unix domain socket 时,填写为形如 `"/dev/shm/domain.socket,0666"` 的形式,即 socket 后加逗号及访问权限指示符,即可指定 socket 的访问权限,可用于解决默认情况下出现的 socket 访问权限问题。
@@ -62,9 +62,9 @@
具体的配置内容,视协议不同而不同。详见每个协议中的 `InboundConfigurationObject`
> `streamSettings`: [StreamSettingsObject](./transport.md#streamsettingsobject)
> `streamSettings`: [StreamSettingsObject](./transport.md)
底层传输方式(transport)是当前 Xray 节点和其它节点对接的方式
此入站的传输配置。
> `tag`: string
+1 -1
View File
@@ -50,7 +50,7 @@ Tunnel(隧道),旧称 dokodemo-door(任意门),可以监听数个本
当值为 `true` 时,dokodemo-door 会识别出由 iptables 转发而来的数据,并转发到相应的目标地址。
可参考 [传输配置](../transport.md#sockoptobject) 中的 `tproxy` 设置。
可参考 [传输配置](../transports/sockopt.md#sockoptobject) 中的 `tproxy` 设置。
> `userLevel`: number
+1 -1
View File
@@ -118,7 +118,7 @@ level 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。
XTLS 仅在以下搭配下可用
- TCP+TLS/Reality 此时将直接在底层对拷加密后的数据(若传输的是 TLS 1.3)。
- TCP+TLS/REALITY 此时将直接在底层对拷加密后的数据(若传输的是 TLS 1.3)。
- VLESS Encryption 无底层传输限制,若底层不支持直接对拷(见上)则仅穿透 Encryption.
> `reverse`: struct
+8 -8
View File
@@ -63,9 +63,9 @@
当其不为空时,其值必须在所有 `tag`**唯一**
:::
> `streamSettings`: [StreamSettingsObject](./transport.md#streamsettingsobject)
> `streamSettings`: [StreamSettingsObject](./transport.md)
底层传输方式(transport)是当前 Xray 节点和其它节点对接的方式
此出站的传输配置
> `proxySettings`: [ProxySettingsObject](#proxysettingsobject)
@@ -79,10 +79,10 @@ Mux 相关的具体配置。
如果此出站尝试发送一个域名请求,控制其是否被解析/如何解析为 IP 并发送。
默认值为 `AsIs` 即保持原样发送到远端服务器。所有参数含义均约等于 [sockopt](./transport.md#sockoptobject) 中的 `domainStrategy`
默认值为 `AsIs` 即保持原样发送到远端服务器。所有参数含义均约等于 [sockopt](./transports/sockopt.md#sockoptobject) 中的 `domainStrategy`
::: tip
这里控制的是**被代理的请求**,如果出站代理服务器的地址是域名,并需要为这个域名本身选择解析策略,则应配置 [sockopt](./transport.md#sockoptobject) 中的 `domainStrategy`
这里控制的是**被代理的请求**,如果出站代理服务器的地址是域名,并需要为这个域名本身选择解析策略,则应配置 [sockopt](./transports/sockopt.md#sockoptobject) 中的 `domainStrategy`
:::
### ProxySettingsObject
@@ -99,15 +99,15 @@ Mux 相关的具体配置。
当指定另一个 outbound 的标识时,此 outbound 发出的数据,将被转发至所指定的 outbound 发出。
::: danger
此选项与 [SockOpt.dialerProxy](./transport.md#sockoptobject) 冲突,根据需要任选其一即可。
此选项与 [Sockopt.dialerProxy](./transports/sockopt.md#sockoptobject) 冲突,根据需要任选其一即可。
默认情况下,这种转发方式**不经过**底层传输方式 (REALITY/XHTTP/gRPC...),也就是此 outbound 的 `streamSettings` 将不起作用。<br>
如果需要使用支持底层传输方式的转发,请改用 `SockOpt.dialerProxy` 或者将 `transportLayer` 设为 `true`
默认情况下,这种转发方式**会忽略**此出站自己的 `传输配置` (如有 XHTTP/REALITY/Sockopt...),也就是此 outbound 的 `streamSettings` 将不起作用。<br>
如果需要使用支持 `streamSettings` 方式的转发,请改用 `Sockopt.dialerProxy` 或者将这里的 `transportLayer` 设为 `true`
:::
> `transportLayer`: true | false
`true` 将此设置转化为 `SockOpt.dialerProxy` 来支持底层传输方式的转发,默认为 `false` 即不转化。
`true` 将此设置转化为 `Sockopt.dialerProxy` 来支持此出站的 `streamSettings`,默认为 `false` 即不转化。
### MuxObject
+1 -1
View File
@@ -57,7 +57,7 @@ Freedom 是一个出站协议,可以用来向任意网络发送(正常的)
默认值 `"AsIs"`
所有参数含义均约等于 [sockopt](../transport.md#sockoptobject) 中的 domainStrategy.
所有参数含义均约等于 [sockopt](../transports/sockopt.md#sockoptobject) 中的 domainStrategy.
在这里使用 AsIs 才可以把域名交给后面的 sockopt 模块,如果在这里设置非 AsIs 导致域名被解析为具体 IP 会使后续的 sockopt.domainStrategy 以及其相关的 happyEyeballs 失效。(如果不调整这两个设置则没有负面影响)
+1 -1
View File
@@ -2,7 +2,7 @@
Hysteria 协议的客户端实现。
这个页面非常简单,因为 hysteria 协议实际上分为一个简单的代理控制协议和经过调优的 QUIC 底层传输,在 Xray 中代理协议和底层传输被拆分,更多内容(如 brutal)详见底层传输的 [hysteriaSettings](../transports/hysteria.md) [finalmask.quicParams](../transport.md#quicParams)
这个页面非常简单,因为 hysteria 协议实际上分为一个简单的代理控制协议和经过调优的 QUIC 传输实现,在 Xray 中代理协议和传输配置被拆分,更多内容(如 brutal)详见传输配置中的 [hysteriaSettings](../transports/hysteria.md) [FinalMask.quicParams](../transports/finalmask.md#quicparams)
::: tip
`hysteria protocol` 本身无认证,搭配非 `hysteria` 传输层将无法代理 `udp`,也不推荐搭配其他传输层
+1 -1
View File
@@ -84,7 +84,7 @@ VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是
XTLS 仅在以下搭配下可用
- TCP+TLS/Reality 此时若传输的是 TLS 1.3,核心将尝试在底层 Splice 加密后的数据,若成功将节省全部的核心 IO 开销。
- TCP+TLS/REALITY 此时若传输的是 TLS 1.3,核心将尝试在底层 Splice 加密后的数据,若成功将节省全部的核心 IO 开销。
- VLESS Encryption 无底层传输限制,若底层不为 TCP 则仅尝试穿透 Encryption,节省 Encryption 的开销,如果是 TCP 则仍将尝试进行 Splice.
::: tip 关于 Splice
+53 -1234
View File
File diff suppressed because it is too large Load Diff
+404
View File
@@ -0,0 +1,404 @@
# FinalMask
FinalMask 在核心处理完包括 TLS/REALITY 在内的传输层加密后,对流量进行最后一层伪装。
可用于 TCP、UDP 方向的多种伪装,以及 QUIC 相关参数调整。
## FinalMaskObject
`FinalMaskObject` 对应 [`StreamSettingsObject`](../transport.md#streamsettingsobject) 中的 `finalmask` 项。
```json
{
// outbound 示例,同样可用于 inbound
"outbounds": [
{
// ...
"streamSettings": {
"finalmask": {
// [!code focus:30]
"tcp": [
{
"type": "",
"settings": {}
}
],
"udp": [
{
"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": []
}
]
]
}
```
`clients[n][m].delay`: 单位毫秒,为 0 则于前面的粘包发送。
`clients[n][m].rand`: 添加指定长度随机字节,与 `packet` 冲突。
`clients[n][m].randRange`: 随机字节范围,默认 0-255。
`clients[n][m].type`: `packet` 类型,`array | str | hex | base64`,默认为 array。
`clients[n][m].packet`: 添加固定数据,与 `rand` 冲突。
### fragment
```json
{
"packets": "tlshello",
"length": "100-200",
"delay": "10-20",
"maxSplit": "3-6"
}
```
### sudoku
```json
{
"password": "",
"ascii": "",
"customTable": "", // 官方文档字段名为 custom_table
"customTables": [""], // 官方文档字段名为 custom_tables
"paddingMin": 0, // 官方文档字段名为 padding_min
"paddingMax": 0 // 官方文档字段名为 padding_max
}
```
含义见其 [官方文档](https://github.com/SUDOKU-ASCII/sudoku/blob/main/configs/README.zh_CN.md) 文档字段
> `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
数组第一个为最外层伪装。
用于搭配 raw udp | kcp | hysteria | xhttp h3 传输层。
`header-custom`: 总是合包到数据包头。
`header-dns`: 原 mKCP 的 DNS 伪装。某些校园网在未登录的情况下允许 DNS 查询,给 KCP 添加 DNS 头。
`header-dtls`: 原 mKCP 的 DTLS 伪装。伪装成 DTLS 1.2 数据包。无额外配置。
`header-srtp`: 原 mKCP 的 SRTP 伪装。伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。无额外配置。
`header-utp`: 原 mKCP 的 uTP 伪装。伪装成 uTP 数据包,会被识别为 BT 下载数据。无额外配置。
`header-wechat`: 原 mKCP 的 WeChat Video 伪装。伪装成微信视频通话的数据包。无额外配置。
`header-wireguard`: 原 mKCP 的 WireGuard 伪装。伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)无额外配置。
`mkcp-original`: mKCP 曾经默认应用的简单混淆,你可能需要配置它来连接以前的 mKCP 服务器。无额外配置。
`mkcp-aes128gcm`: 对应原 mKCP 的 `seed` 功能。使用 AES-128-GCM 进行混淆。
`noise`: 在发送数据前发送的噪声。
`salamander`: Salamander 混淆。(来自 Hysteria2
`sudoku`:
`xdns`: 利用 DNS 查询来传输数据(类似 DNSTT)。它将执行标准的 DNS TXT 查询来传输载荷。
由于技术限制,它给出的 MTU 非常小,无法使用 QUIC,建议搭配 mKCP 使用。推荐的 MTU 值:客户端 130,服务端 900。
因为执行的查询是标准的,它可以透过任何 UDP DNS 服务器进行转发,尽管效率可能十分不理想。
要使用这个功能,需要服务端监听 53 端口,然后代理协议将目标指向一个 DNS 服务器(如 8.8.8.8:53),并且你拥有 `domain` 的域名,然后将其 NS 记录指向服务端。
比如持有 example.com,那么设置 a.example.com A记录 指向 ip,设置 t.example.com NS记录 指向 t.example.com,最后使用的是 t.example.com。设置 A记录 的不能为 NS记录 的子域。
`xicmp`: 要求至少 `CAP_NET_RAW` 权限且在最外层,也就是数组第一个,不可搭配 `udpHop``dialerProxy`
> `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
}
```
同 TCP 版本
### xdns
```json
{
"domain": "www.example.com"
}
```
### xicmp
```json
{
"listenIp": "0.0.0.0",
"id": 0
}
```
`listenIp`: 监听的 ip。
`id`: 如果同 ip 下有多客户端,建议服务端保持为 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
}
```
用于 XHTTP H3 以及 hysteria 的 QUIC 配置调整。其中 XHTTP
> `congestion`: reno | bbr | brutal | force-brutal
拥塞控制算法,Hysteria 默认为 `brutal`XHTTP H3 默认使用 `bbr`
`reno`/`bbr`: 知名算法。
`brutal`: 与对端协商固定发包速率或降级到 BBR,只支持 Hysteria 传输(因为 XHTTP 无协商机制)。
`force-brutal`: 同 `brutal`,但强制使上行使用 `brutalUp` 固定发包速率,无视对端协商。
> `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 一致:
服务端的值将限制客户端可以选择的最大 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
服务端参数,如果设置则不得小于 8
+2 -2
View File
@@ -7,9 +7,9 @@
**推荐换用 [XHTTP](https://github.com/XTLS/Xray-core/discussions/4113),以避免 HTTPUpgrade “ALPN 是 http/1.1” 等显著流量特征。**
:::
## HttpUpgradeObject
## HTTPUpgradeObject
`HttpUpgradeObject` 对应 [`StreamSettingsObject`](../transport.md#streamsettingsobject) 中的 `httpupgradeSettings` 项。
`HTTPUpgradeObject` 对应 [`StreamSettingsObject`](../transport.md#streamsettingsobject) 中的 `httpupgradeSettings` 项。
```json
{
+14 -2
View File
@@ -1,6 +1,8 @@
# Xray 传输列表
# Xray 传输配置列表
Xray 支持以下传输
Xray 支持以下传输配置
## 传输方式
- [RAW](raw.md)
- [XHTTP: Beyond REALITY](xhttp.md)
@@ -9,3 +11,13 @@ Xray 支持以下传输层:
- [WebSocket](websocket.md)
- [HTTPUpgrade](httpupgrade.md)
- [Hysteria](hysteria.md)
## 传输安全
- [REALITY](reality.md)
- [TLS](tls.md)
## 附加配置
- [FinalMask](finalmask.md)
- [Sockopt](sockopt.md)
+1 -1
View File
@@ -37,7 +37,7 @@ mKCP 牺牲带宽来降低延迟。传输同样的内容,mKCP 一般比 TCP
```
::: tip
`header``seed` 字段已被移除,请使用 [FinalMask](../transport.md#finalmaskobject) 进行配置。
`header``seed` 字段已被移除,请使用 [FinalMask](../transports/finalmask.md#finalmaskobject) 进行配置。
并且曾经默认的 mKCP 混淆也被移除,要连接旧版服务端,需要在 FinalMask 中配置 `mkcp-original`
:::
+203
View File
@@ -0,0 +1,203 @@
# REALITY
REALITY 是对 TLS 的一种修改,通过借用目标站点的 TLS 外观与握手特征来完成伪装。
:::: tip
REALITY 是目前最安全的传输安全方案之一, 且外部看来流量类型和正常上网具有一致性。<br>
启用 REALITY 并且配置合适的 XTLS Vision 流控模式, 可以达到数倍甚至十几倍的性能提升。
::: details 致开发者
REALITY 只是修改了 TLS,客户端的实现只需要轻度修改完全随机的 session id 和自定义证书验证即可,理论上与大多数 TLS 组合完全兼容。
更多信息请参考 [REALITY 项目](https://github.com/XTLS/REALITY).
:::
::::
## RealityObject
`RealityObject` 对应 [`StreamSettingsObject`](../transport.md#streamsettingsobject) 中的 `realitySettings` 项。
```json
{
// outbound 示例,同样可用于 inbound
"outbounds": [
{
// ...
"streamSettings": {
"security": "reality",
"realitySettings": {
// [!code focus:28]
// 入站(服务端)配置
"show": false,
"target": "example.com:443",
"xver": 0,
"serverNames": ["example.com", "www.example.com"],
"privateKey": "",
"minClientVer": "",
"maxClientVer": "",
"maxTimeDiff": 0,
"shortIds": ["", "0123456789abcdef"],
"mldsa65Seed": "",
"limitFallbackUpload": {
"afterBytes": 0,
"bytesPerSec": 0,
"burstBytesPerSec": 0
},
"limitFallbackDownload": {
"afterBytes": 0,
"bytesPerSec": 0,
"burstBytesPerSec": 0
},
// 出站(客户端)配置
"serverName": "",
"fingerprint": "chrome",
"password": "",
"shortId": "",
"mldsa65Verify": "",
"spiderX": ""
}
}
}
]
}
```
> `show` : true | false
当值为 `true` 时,输出调试信息。
::: tip
以下为**入站**(**服务端**)配置。
:::
> `target` : string
必填,格式同 VLESS `fallbacks` 的 [dest](../features/fallback.md#fallbackobject)。
旧称 dest, 当前版本两个字段互为alias
如果 target 支持后量子密钥交换算法 X25519MLKEM768, 那么 REALITY 客户端也会自动使用该后量子算法进行密钥协商。具体是否支持可以使用 `xray tls ping cloudflare.com` (网址更改为dest, 可以带端口号) 检查。
核心按照这个字段是否存在区分是当前是客户端还是服务端配置,不要在客户端填写,否则会造成识别异常。
::: warning
为了伪装的效果考虑,Xray 对于鉴权失败(非合法 REALITY 请求)的流量,会**直接转发**至 target.
如果 target 网站的 IP 地址特殊(如使用了 CloudFlare CDN 的网站) 则相当于你的服务器充当了 CloudFlare 的端口转发,可能造成被扫描后偷跑流量的情况。
为了杜绝这种情况,可以考虑前置 Nginx 等方法过滤掉不符合要求的 SNI。
或者也可以考虑配置 `limitFallbackUpload``limitFallbackDownload`,限制其速率。
:::
> `xver` : number
选填,格式同 VLESS `fallbacks` 的 [xver](../features/fallback.md#fallbackobject)
> `serverNames` : \[string\]
必填,客户端可用的 `serverName` 列表,不支持 \* 通配符。
一般与 target 保持一致即可,实际的可选值为服务器所接受的任何 SNI(依据 target 本身的配置有所不同),一般是参考是所返回证书的 [SAN](https://zh.wikipedia.org/wiki/%E4%B8%BB%E9%A2%98%E5%A4%87%E7%94%A8%E5%90%8D%E7%A7%B0).
其中可包含空值 `""` 代表接受没有SNI的连接。使用此特性不要求 `target` 具有 IP 证书,只需确保在收到无 SNI 的 Client Hello 其不会拒绝连接。使用这一特性时客户端 `serverName` 不能为空,需要填入任意有效 IP 地址占位。
可以使用 `xray tls ping` 观察服务端对无 SNI 请求的响应行为。
> `privateKey` : string
必填,执行 `./xray x25519` 生成。
> `minClientVer` : string
选填,客户端 Xray 最低版本,格式为 `x.y.z`
> `maxClientVer` : string
选填,客户端 Xray 最高版本,格式为 `x.y.z`
> `maxTimeDiff` : number
选填,允许的最大时间差,单位为毫秒。
> `shortIds` : \[string\]
必填,客户端可用的 `shortId` 列表,可用于区分不同的客户端。
格式要求见 `shortId`
若包含空值,客户端 `shortId` 可为空。
> `mldsa65Seed` : string
仅服务端,为发送给 REALITY 客户端的证书添加额外的后量子签名所使用的私钥,使用 ML-DSA-65 (如果存在可以破解 x25519 的量子计算机,password 泄露可能导致连接可以被 mitm, 该功能可以防止未来的这种攻击)
使用 `xray mldsa65` 生成使用的公私钥对,服务端配置私钥后只会在证书扩展中添加,不影响旧版客户端或没启用该功能的客户端。
注意,配置该功能后 target 所返回的证书长度**必须**大于 3500, 因为后量子签名会导致 REALITY 返回的临时证书变大,为了防止产生特征 target 返回的证书也要很大。 可以使用 `xray tls ping example.com` 进行查看检查。同时为了完美的后量子安全,target 也需要支持后量子密钥交换 X25519MLKEM768, 支持情况一样可以通过前面的命令查看。
> `limitFallbackUpload`/`limitFallbackDownload`
::: warning
警告:对于 REALITY 最佳实践始终是偷同 ASN 的证书,那么你大概率用不到此功能;只有当你迫不得已偷了 Cloudflare 这种免费 CDN 的证书时,为避免你服务器成为别人加速节点时可考虑开启此功能。
回落限速是一种特征,不建议启用,如果您是面板/一键脚本开发者,务必让这些参数随机化。
:::
::: tip
`limitFallbackUpload``limitFallbackDownload` 为选填,可对未通过验证的回落连接限速,`bytesPerSec` 默认为 0 即不启用。
原理:针对每个未通过验证的回落连接,当传输了 afterBytes 字节后开启限速算法。
限速采用令牌桶算法,桶的容量是 burstBytesPerSec,每传输一个字节用掉一个令牌,初始 burstBytesPerSec 是满的。
每秒以 bytesPerSec 个令牌填充桶,直到容量满。
举例:`afterBytes=10485760`, `burstBytesPerSec=5242880`, `bytesPerSec=1048576` 代表传输 15MB 后开始限速为 1MB/s,如果暂停传输,5 秒后能突发到 5MB/s,然后又恢复到 1MB/s。
建议:过大的 `afterBytes``burstBytesPerSec` 将起不到限速效果,过小的 `bytesPerSec``burstBytesPerSec` 则十分容易被探测。
应结合被偷网站的资源大小合理设置参数,如果不允许突发,可以把 `burstBytesPerSec` 设为 0。
:::
> `afterBytes` : number
选填,对回落的 REALITY 连接限速,限制传输指定字节后开始限速,默认为 0。
> `bytesPerSec` : number
选填,对回落的 REALITY 连接限速,限制基准速率(字节/秒),默认为 0 即不启用限速功能。
> `burstBytesPerSec` : number
选填,对回落的 REALITY 连接限速,限制突发速率(字节/秒),大于 `bytesPerSec` 时生效。
::: tip
以下为**出站**(**客户端**)配置。
:::
> `serverName` : string
服务端 `serverNames` 之一。
特别地,客户端可以将其设置为任意 IP 地址,Xray 将会发送无 SNI 扩展的 Client Hello. 要使用这一特性请确保服务端 `serverNames` 中包含空值 `""`
> `fingerprint` : string
必填,同 [TLSObject](./tls.md#tlsobject)。 注意:此处不支持使用 `unsafe` 禁用 utls, 因为 REALITY 协议实现使用了该库以操作底层 TLS 参数。
> `shortId` : string
服务端 shortIds 之一。
长度为 8 个字节,即 16 个 0~f 的数字字母,可以小于16个,核心将会自动在后面补0, 但位数必须是**偶数** (因为一个字节有2位16进制数)
`aa1234` 会被自动补全为 `aa12340000000000`, 但是`aaa1234` 则会导致错误。
0也是偶数,所以若服务端的 `shordIDs` 包含空值 `""` ,客户端也可为空。
> `password` : string
必填,服务端私钥对应的公钥。使用 `./xray x25519 -i "服务器私钥"` 生成。旧称 publicKey, 为防止误解更名(这个东西地位上确实是 x25519 公钥但是在 REALITY 的设计中是客户端持有,不能公开)
> `mldsa65Verify`
可选,mldsa65 签名验证使用的公钥,非空时使用该公钥检查服务端返回的证书,详情见 `"mldsa65Seed"` 的描述。
> `spiderX` : string
爬虫初始路径与参数,建议每个客户端不同。
+304
View File
@@ -0,0 +1,304 @@
# Sockopt
Sockopt 用于配置底层网络行为。
可用于调整透明代理、域名解析策略以及各类底层 socket 选项。
## SockoptObject
`SockoptObject` 对应 [`StreamSettingsObject`](../transport.md#streamsettingsobject) 中的 `sockopt` 项。
```json
{
// outbound 示例,同样可用于 inbound
"outbounds": [
{
// ...
"streamSettings": {
"sockopt": {
// [!code focus:18]
"mark": 0,
"tcpMaxSeg": 1440,
"tcpFastOpen": false,
"tproxy": "off",
"domainStrategy": "AsIs",
"happyEyeballs": {},
"dialerProxy": "",
"acceptProxyProtocol": false,
"tcpKeepAliveInterval": 0,
"tcpKeepAliveIdle": 300,
"tcpUserTimeout": 10000,
"tcpcongestion": "bbr",
"interface": "wg0",
"V6Only": false,
"tcpWindowClamp": 600,
"tcpMptcp": false,
"addressPortStrategy": "",
"customSockopt": []
}
}
}
]
}
```
> `mark`: number
一个整数。当其值非零时,在 outbound 连接上以此数值标记 SO_MARK。
- 仅适用于 Linux 系统。
- 需要 CAP_NET_ADMIN 权限。
> `tcpMaxSeg`: number
用于设置 TCP 数据包的最大传输单元。
> `tcpFastOpen`: true | false | number
是否启用 [TCP Fast Open](https://zh.wikipedia.org/wiki/TCP%E5%BF%AB%E9%80%9F%E6%89%93%E5%BC%80)。
当其值为 `true``正整数`时,启用 TFO;当其值为 `false``负数`时,强制关闭 TFO;当此项不存在或为 `0` 时,使用系统默认设置。 可用于 inbound/outbound。
- 仅在以下版本(或更新版本)的操作系统中可用:
- Linux 3.16:需要通过内核参数 `net.ipv4.tcp_fastopen` 进行设定,此参数是一个 bitmap,`0x1` 代表客户端允许启用,`0x2` 代表服务器允许启用;默认值为 `0x1`,如果服务器要启用
TFO,请把此内核参数值设为 `0x3`
- ~~Windows 10 (1607)~~(实现不正确)
- Mac OS 10.11 / iOS 9(需要测试)
- FreeBSD 10.3 (Server) / 12.0 (Client):需要把内核参数 `net.inet.tcp.fastopen.server_enabled`
以及 `net.inet.tcp.fastopen.client_enabled` 设为 `1`。(需要测试)
- 对于 Inbound,此处所设定的`正整数`代表 [待处理的 TFO 连接请求数上限](https://tools.ietf.org/html/rfc7413#section-5.1) ,**注意并非所有操作系统都支持在此设定**:
- Linux / FreeBSD:此处的设定的`正整数`值代表上限,可接受的最大值为 2147483647,为 `true` 时将取 `256`;注意在 Linux`net.core.somaxconn`
会限制此值的上限,如果超过了 `somaxconn`,请同时提高 `somaxconn`
- Mac OS:此处为 `true``正整数`时,仅代表启用 TFO,上限需要通过内核参数 `net.inet.tcp.fastopen_backlog` 单独设定。
- Windows:此处为 `true``正整数`时,仅代表启用 TFO。
- 对于 Outbound,设定为 `true``正整数`在任何操作系统都仅表示启用 TFO。
> `tproxy`: "redirect" | "tproxy" | "off"
是否开启透明代理(仅适用于 Linux)。
- `"redirect"`:使用 Redirect 模式的透明代理。支持所有基于 IPv4/6 的 TCP 连接。
- `"tproxy"`:使用 TProxy 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
- `"off"`:关闭透明代理。
透明代理需要 Root 或 `CAP_NET_ADMIN` 权限。
::: danger
当 [Dokodemo-door](../inbounds/tunnel.md) 中指定了 `followRedirect``true`,且 Sockopt 设置中的`tproxy` 为空时,Sockopt
设置中的`tproxy` 的值会被设为 `"redirect"`
:::
> `domainStrategy`: "AsIs"<br>
> "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4"<br>
> "ForceIP" | "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4"
默认值 `"AsIs"`
当目标地址为域名时,配置相应的值,Outbound 连接远端服务器的行为模式如下:
- 当使用 `"AsIs"` 时, Xray 不对域名进行特殊处理,到最后 Xray 将直接使用 go 自带的 Dial 发起连接,优先级固定为 RFC6724 的默认值(不会遵守 gai.conf 等配置) 通常来说为 IPv6 优先。
- 当填写其他值时,将使用 Xray-core [内置 DNS 服务器](../dns.md) 服务器进行解析。若不存在DNSObject,则使用系统DNS。若有多个符合条件的IP地址时,核心会随机选择一个IP作为目标IP。
- `"IPv4"` 代表尝试仅使用 IPv4 进行连接,`"IPv4v6"` 代表尝试使用 IPv4 或 IPv6 连接,但对于双栈域名,使用 IPv4。(v4v6 调换后同理,不再赘述)
- 当在内置DNS设置了 `"queryStrategy"` 后,实际行为将会与这个选项取并,只有都被包含的IP类型才会被解析,如 `"queryStrategy": "UseIPv4"` `"domainStrategy": "UseIP"`,实际上等同于 `"domainStrategy": "UseIPv4"`
- 当使用 `"Use"` 开头的选项时,若解析结果不符合要求(如,域名只有IPv4解析结果但使用了UseIPv6),则会回落回AsIs。
- 当使用 `"Force"` 开头的选项时,若解析结果不符合要求,则该连接会无法建立。
::: tip TIP
当使用 `"UseIP"``"ForceIP"` 模式时,并且 [出站连接配置](../outbound.md#outboundobject) 中指定了 `sendThrough` 时,核心会根据 `sendThrough` 的值自动判断所需的 IP 类型,IPv4 或 IPv6。若手动指定了单种IP类型(如UseIPv4),但与 `sendThrough` 指定的本地地址不匹配,将会导致连接失败。
:::
::: danger
启用了此功能后,不当的配置可能会导致死循环。
一句话版本:连接到服务器,需要等待 DNS 查询结果;完成 DNS 查询,需要连接到服务器。
> Tony: 先有鸡还是先有蛋?
详细解释:
1. 触发条件:代理服务器(proxy.com)。内置 DNS 服务器,非 Local 模式。
2. Xray 尝试向 proxy.com 建立 TCP 连接 **前** ,通过内置 DNS 服务器查询 proxy.com。
3. 内置 DNS 服务器向 dns.com 建立连接,并发送查询,以获取 proxy.com 的 IP。
4. **不当的** 的路由规则,导致 proxy.com 代理了步骤 3 中发出的查询。
5. Xray 尝试向 proxy.com 建立另一个 TCP 连接。
6. 在建立连接前,通过内置 DNS 服务器查询 proxy.com。
7. 内置 DNS 服务器复用步骤 3 中的连接,发出查询。
8. 问题出现。步骤 3 中连接的建立,需要等待步骤 7 中的查询结果;步骤 7 完成查询,需要等待步骤 3 中的连接完全建立。
9. Good Game
解决方案:
- 改内置 DNS 服务器的分流。
- 用 Hosts。
- ~~如果你还是不知道解决方案,就别用这个功能了。~~
因此,**不建议** 经验不足的用户擅自使用此功能。
:::
> `dialerProxy`: ""
一个出站代理的标识。当值不为空时,将使用指定的 outbound 发出连接。可用于支持传输配置的链式转发。
::: danger
此选项与 ProxySettingsObject.Tag 不兼容
:::
> `acceptProxyProtocol`: true | false
仅用于 inbound,指示是否接收 PROXY protocol。
[PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt) 专用于传递请求的真实来源 IP 和端口,**若你不了解它,请先忽略该项**。
常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。
填写 `true` 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。
> `tcpKeepAliveIdle`: number
TCP 空闲时间阈值,单位为秒。当 TCP 连接空闲时间达到这个阈值时,将开始发送 Keep-Alive 探测包。
对于出站, xray 使用 Chrome 的默认值 idle 与 interval 均为 45s, 该选项与 `tcpKeepAliveInterval` 任意一个设置为负数将禁用该默认 keepalive, 正数则会覆盖该默认值。
对于入站, Keep-Alive 默认禁用,该选项与 `tcpKeepAliveInterval` 任意一个非零时启用,如果只设置二者之一那么另一个将跟随操作系统设置。
> `tcpKeepAliveInterval`: number
TCP 进入 Keep-Alive 状态后发送 Keep-Alive 数据包间的时间间隔,单位为秒。其他行为见上。
> `tcpUserTimeout`: number
单位为毫秒。详细介绍:https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md
> `tcpcongestion`: ""
TCP 拥塞控制算法。仅支持 Linux。
不配置此项表示使用系统默认值。
::: tip 常见的算法
- bbr(推荐)
- cubic
- reno
:::
::: tip
执行命令 `sysctl net.ipv4.tcp_congestion_control` 获取系统默认值。
:::
> `interface`: ""
指定绑定出口网卡名称,支持 linux / iOS / Mac OS / Windows。
> `V6Only`: true | false
填写 `true` 时,监听 `::` 地址仅接受 IPv6 连接。仅支持 Linux。
> `tcpWindowClamp`: number
绑定通告的 windows 大小为该值。内核会在它与 SOCK_MIN_RCVBUF/2 之间选一个最大值。
> `tcpMptcp`: true | false
默认值 `false`,填写 `true` 时,启用 [Multipath TCP](https://en.wikipedia.org/wiki/Multipath_TCP),仅客户端参数,因为 golang 在 1.24+ 版本已默认在监听时启用 MPTCP.
当前仅支持Linux,需要Linux Kernel 5.6及以上。
> `tcpNoDelay`: true | false
该选项已被删除,因为 golang 默认启用 TCP no delay。 相反地,如果想要禁用,请通过使用 customSockopt 禁用。
> `addressPortStrategy`: "none" | "SrvPortOnly" | "SrvAddressOnly" | "SrvPortAndAddress" | "TxtPortOnly" | "TxtAddressOnly" | "TxtPortAndAddress"
使用 SRV 记录或 TXT 记录指定出站使用的目标地址/端口,默认 `none` 即关闭
查询直接通过系统DNS而不是Xray的内置DNS, 尝试去查询的域名将会是出站中的域名。如果查询失败请求会按原地址和端口发出
`Srv` 开头代表查询 SRV 记录(标准格式), `Txt` 开头代表查询 TXT 记录(格式形如 `127.0.0.1:80`)
`PortOnly` 仅重置端口 `AddressOnly` 仅重置地址 `PortAndAddress` 则重置地址和端口
该选项生效在 sockopt 里的 domainStrategy 解析之前,地址重置后仍会按 domainStrategy 的规则进行解析(如果有), 但是在 Freedom 的 domainStrategy 之后,如果在其中设置了解析为 IP 则本选项无法生效。
PS: 如果有正常上网的域名流量被 AsIs 的 freedom 出站送过来,那么在此设置后会尝试解析并重置地址和端口,比如核心会尝试查询 google.com 的 SRV 记录并按记录重置目标。
> `customSockopt`: []
一个数组,用于高级用户指定需要的任何 sockopt, 理论上上述所有与连接有关的设置均可以在此等价设置, 自然也可以设置存在但是核心未添加的其他选项。目前支持 Linux Winows Darwin 操作系统。下方示例等价于核心中的 `"tcpcongestion": "bbr"`
使用前请确保你了解 Socket 编程。
```json
"customSockopt": [
{
"system": "linux",
"type": "str",
"level":"6",
"opt": "13",
"value": "bbr"
}
]
```
> `system`: ""
可选,指定生效的系统,如果运行的系统不匹配则跳过该 sockopt. 目前可选 `linux` `windows` `darwin` (全部小写). 若留空则直接执行
> `type`: ""
必填,设置的类型,目前可选int或str.
> `level`: ""
可选,协议级别,用于指定生效范围,默认为6, 即TCP.
> `opt`: ""
操作的选项名称,使用十进制(此处示例为 TCP_CONGESTION 的值 定义为 0xd 转换为10进制即为13)
> `value`: ""
要设置的选项值,此处示例为设置为bbr.
当 type 指定为 int 时需要使用十进制数字。
> `happyEyeballs`: [HappyEyeballsObject](#happyeyeballsobject)
RFC-8305 实现的 happyEyeballs,仅适用于 TCP。当目标为域名时对它们竞速并选择第一个成功的返回,仅当 `Sockopt.domainStrategy` 被设置为非 `AsIs` 时生效。
注意:`UseIPv4v6` / `ForceIPv4v6` 会使可用的 IP 列表被缩减到仅剩 IPv4,仅查询失败时才会回退查询 IPv6。不推荐这么用。建议使用 UseIP / ForceIP 配合 `HappyEyeballs.interleave`
::: warning
使用这个功能时不要使用 `Freedom` 出站的 `domainStrategy`, 这会导致 `Sockopt` 只能看到被替换完毕的 IP.
:::
### HappyEyeballsObject
```json
"happyEyeballs": {
"tryDelayMs": 250,
"prioritizeIPv6": false,
"interleave": 1,
"maxConcurrentTry": 4
}
```
> `tryDelayMs`: number
每个竞速请求发起时间的间隔,单位毫秒,默认为0(代表禁用该功能),推荐值为 250.
> `prioritizeIPv6`: bool
排序 IP 时首个 IP 的类型,默认为 false (即 IPv4 会被排在第一个)
> `interleave`: number
RFC-8305 中的 "First Address Family count", 默认值为 1. 它定义了对不同IP版本进行排序时的交错行为。
比如等待 dial 的 IP 队列会被排序为 46464646 (设置为1) 44664466 (设置为2) (6 代表 IPv6 地址, 4 代表 IPv4 地址).
> `maxConcurrentTry`: number
最大并发数量,用于防止解析出的IP过多且均未成功时候核心也对这些IP产生大量连接。默认为4, 设置为0代表禁用 happyEyeballs.
+340
View File
@@ -0,0 +1,340 @@
# TLS
TLS 是常见的传输层加密方式。
可用于为传输层提供加密、证书校验与客户端指纹等相关配置。
## TLSObject
`TLSObject` 对应 [`StreamSettingsObject`](../transport.md#streamsettingsobject) 中的 `tlsSettings` 项。
```json
{
// outbound 示例,同样可用于 inbound
"outbounds": [
{
// ...
"streamSettings": {
"security": "tls",
"tlsSettings": {
// [!code focus:18]
"serverName": "xray.com",
"verifyPeerCertByName": "",
"rejectUnknownSni": false,
"allowInsecure": false,
"alpn": ["h2", "http/1.1"],
"minVersion": "1.2",
"maxVersion": "1.3",
"cipherSuites": "此处填写你需要的加密套件名称,每个套件名称之间用:进行分隔",
"certificates": [],
"disableSystemRoot": false,
"enableSessionResumption": false,
"fingerprint": "",
"pinnedPeerCertSha256": "",
"curvePreferences": [""],
"masterKeyLog": "",
"echServerKeys": "",
"echConfigList": "",
"echSockopt": {}
}
}
}
]
}
```
> `serverName`: string
服务器名称,服务器端证书的 SAN 中需要包含该值,可以是域名或者 IP 地址。当为域名时将在 Client Hello 中的 SNI 扩展中发送,IP 地址则不会发送 SNI 扩展(SNI 扩展不允许包含 IP 地址)。如果填入 IPv6 要使用 `[]` 包裹
当留空时,自动使用 address 中的值(如果是域名)。
特殊值 `"FromMitM"`, 这会使其使用入来自 dokodemo-door 入站解密的 TLS 中包含的 SNI.
> `verifyPeerCertByName`: string
仅客户端,用于校验证书使用的 SNI,可以用 `,` 分割多个域名(只需要证书中有一个 SAN 在该列表中即可), 将会覆盖本用于校验的 `serverName`, 用于域前置等特殊目的。
特殊值 `"FromMitM"`, 这会使其额外加入来自 dokodemo-door 入站解密的 TLS 中包含的 SNI.
> `rejectUnknownSni`: bool
当值为 `true` 时,服务端接收到的 SNI 与证书域名不匹配即拒绝 TLS 握手,默认为 false。
> `alpn`: \[ string \]
一个字符串数组,指定了 TLS 握手时指定的 ALPN 数值。默认值为 `["h2", "http/1.1"]`
特殊值:`["FromMitM"]` (有且仅有这一个元素时) 会使出站 TLS 使用来自 dokodemo-door 入站解密的 TLS 连接使用的 alpn.
> `minVersion`: string
minVersion 为可接受的最小 TLS 版本。
> `maxVersion`: string
maxVersion 为可接受的最大 TLS 版本。
> `cipherSuites`: string
CipherSuites 用于配置受支持的密码套件列表, 每个套件名称之间用:进行分隔.
你可以在 [这里](https://golang.org/src/crypto/tls/cipher_suites.go#L500)或 [这里](https://golang.org/src/crypto/tls/cipher_suites.go#L44)
找到 golang 加密套件的名词和说明
::: danger
以上两项配置为非必要选项,正常情况下不影响安全性 在未配置的情况下 golang 根据设备自动选择. 若不熟悉, 请勿配置此选项, 填写不当引起的问题自行负责
:::
> `allowInsecure`: true | false
是否允许不安全连接(仅用于客户端)。默认值为 `false`
当值为 `true` 时,Xray 不会检查远端主机所提供的 TLS 证书的有效性。
::: danger
~~出于安全性考虑,这个选项不应该在实际场景中选择 true,否则可能遭受中间人攻击。~~
该选项已被弃用,使用 `pinnedPeerCertSha256` 手动指定需要的证书。
:::
> `disableSystemRoot`: true | false
是否禁用操作系统自带的 CA 证书。默认值为 `false`
当值为 `true` 时,Xray 只会使用 `certificates` 中指定的证书进行 TLS 握手。当值为 `false` 时,Xray 只会使用操作系统自带的 CA 证书进行 TLS 握手。
> `enableSessionResumption`: true | false
是否启用会话恢复,默认禁用,只有服务端和客户端都启用时候才会尝试协商会话恢复。
如果协商成功将可以不在握手过程中传输证书。稍微节省一点点握手时间(几乎可以忽略不计)
注意,这不是 TLS 0RTT, gotls 尚未支持此功能,这不会减少 TLS 握手的 RTT.
> `fingerprint` : string
此参数用于配置指定 `TLS Client Hello` 的指纹。默认值为 `chrome` 要恢复为原生 go TLS, 请设置为 `unsafe`. 启用后,Xray 将通过 uTLS 库 **模拟** `TLS` 指纹,或随机生成。支持三种配置方式:
1. 常见浏览器最新版本的 TLS 指纹 包括
- `"chrome"`
- `"firefox"`
- `"safari"`
- `"ios"`
- `"android"`
- `"edge"`
- `"360"`
- `"qq"`
2. 在 xray 启动时自动生成一个指纹
- `"random"`: 在较新版本的浏览器里随机抽取一个
- `"randomized"`: 完全随机生成一个独一无二的指纹 (100% 支持 TLS 1.3 使用 X25519)
3. 使用 uTLS 原生指纹变量名 例如`"HelloRandomizedNoALPN"` `"HelloChrome_106_Shuffle"`。完整名单见 [uTLS 库](https://github.com/refraction-networking/utls/blob/master/u_common.go#L434)
::: tip
此功能仅 **模拟** `TLS Client Hello` 的指纹,行为、其他指纹与 Golang 相同。如果你希望更加完整地模拟浏览器 `TLS`
指纹与行为,可以使用 [Browser Dialer](./websocket.md#browser-dialer)。
:::
::: tip
当使用此功能时,TLS 的部分影响TLS指纹的选项将被 utls 库覆盖不再生效,列如ALPN。
会被传递的参数有
`"serverName" "disableSystemRoot" "pinnedPeerCertSha256" "masterKeyLog"`
:::
> `pinnedPeerCertSha256`: string
用于指定远程服务器的证书 SHA256 散列值,使用 hex 且大小写不敏感。如 `e8e2d387fdbffeb38e9c9065cf30a97ee23c0e3d32ee6f78ffae40966befccc9`,可以使用 `,` 连接更多的散列值,匹配到任何一个即通过验证。
该编码与 Chrome 证书查看器 SHA-256 证书指纹,以及 crt.sh 的 Certificate Fingerprints SHA-256 格式均相同。可以使用 `xray tls hash --cert <cert.pem>` 进行计算,也可以使用 `openssl x509 -noout -fingerprint -sha256 -in cert.pem` (兼容它生成的带冒号的格式), `xray tls ping` 同样会输出远程证书的 SHA256 散列值。
该验证将覆盖默认的证书校验,分两种情况:
- 1.当核心找到匹配的散列值为叶子证书,验证直接通过。
- 2.当核心找到匹配的值为 CA 证书(可以是根证书也可以是中级证书),将使用 `serverName` 里的值验证叶子证书上的签名是否来自该 CA 授权。
> `certificates`: \[ [CertificateObject](#certificateobject) \]
证书列表,其中每一项表示一个证书(建议 fullchain)。
::: tip
如果要在 ssllibs 或者 myssl 获得 A/A+ 等级的评价,
请参考 [这里](https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600).
:::
> `curvePreferences`: \[ string \]
一个字符串数组,指定 TLS 握手执行ECDHE时支持的曲线。支持的曲线列表如下(大小写不敏感).
```
CurveP256
CurveP384
CurveP521
X25519
X25519MLKEM768
SecP256r1MLKEM768*
SecP384r1MLKEM1024*
```
\*: 未被 utls 支持
默认值截止至 go1.26 为包含上述全部曲线。调整顺序并不会使客户端或者服务器偏好使用哪种曲线,实际曲线将由密钥交换机制自行协商。
> `masterKeyLog` : string
(Pre)-Master-Secret log 文件路径,可用于Wireshark等软件解密Xray发送的TLS连接。
> `echServerKeys` : string
仅服务端参数,用于服务端启用 Encrypted Client Hello.
使用 `xray tls ech --serverName example.com` 生成可用的 ECH Server Key 和对应的 Config, 其中 example.com 是在 SNI 被加密用用于暴露在外部的 SNI, 可以随便填。Server Key 包含了 ECHConfig, 如果你不慎弄丢了客户端用的 Config 可以使用 `xray tls ech -i "你的 server key"` 重新获得。你可以把它发布到 DNS 的 HTTPS 记录中,格式参考[这里](https://dns.google/query?name=encryptedsni.com&rr_type=HTTPS) 或者 RFC 9460
注意服务端配置 ECH 后仍然接受正常的非 ECH 连接。
> `echConfigList` : string
仅客户端参数,配置 ECHConfig, 不为空则代表客户端启用 Encrypted Client Hello. 支持两种格式
第一种直接 固定 ECHConfig, 如 `"AF7+DQBaAAAgACA51i3Ssu4wUMV4FNCc8iRX5J+YC4Bhigz9sacl2lCfSQAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAAtleGFtcGxlLmNvbQAA"`
第二种从 DNS 服务器查询,比方说使用 CDN 时可以通过 HTTPS 记录动态获取其配置的 ECHConfig, 如果获取到有效 ECH Config, Xray 会遵守服务器下发的 TTL,查询目标会是配置的 SNI, 或者配置的服务器域名(如果 SNI 为空且目标为一个域名)
基础格式为 `"udp://1.1.1.1"` 表示从 UDP DNS 1.1.1.1 查询,也可以使用 `"https://1.1.1.1/dns-query"`(或者 `h2c://`) 这样的格式,代表使用 DOH(h2c) 进行查询(实际使用请替换成当地可用的服务器). 上述三种均支持修改端口号,如 `udp://1.1.1.1:53`,没写会按照协议默认 53/443.
特别地,可以使用指定的域名用于查询 ECHConfig, 格式为 `"example.com+https://1.1.1.1/dns-query"` 这样 Xray 会强制使用 example.com 的 DNS 记录中的 ECHConfig 用于连接,如果你想从 DNS 获取 ECHConfig 但又不想暴露自己在查询这个域名的 HTTPS 记录或者在这个域名下发布 HTTPS 记录时有一些用。
> `echSockopt` : [SockoptObject](./sockopt.md#sockoptobject)
调整使用 DNS 查询 ECH 记录时使用的连接的底层 socket 选项。
### CertificateObject
```json
{
"ocspStapling": 0,
"oneTimeLoading": false,
"usage": "encipherment",
"buildChain": false,
"certificateFile": "/path/to/certificate.crt",
"keyFile": "/path/to/key.key",
"certificate": [
"--BEGIN CERTIFICATE--",
"MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",
"ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",
"DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",
"3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",
"OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",
"pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",
"OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",
"noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",
"A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",
"MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",
"7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",
"9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",
"6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",
"r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",
"d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",
"--END CERTIFICATE--"
],
"key": [
"--BEGIN RSA PRIVATE KEY--",
"MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",
"bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",
"GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",
"jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",
"itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",
"IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",
"qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",
"C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",
"/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",
"aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",
"/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",
"bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",
"8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",
"pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",
"L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",
"3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",
"az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",
"gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",
"TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",
"eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",
"64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",
"8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",
"GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",
"ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",
"cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",
"--END RSA PRIVATE KEY--"
]
}
```
服务端证书,每隔 3600 秒(即一小时)将进行热重载。
> `ocspStapling`: number
OCSP 装订更新间隔,单位为秒,默认值为 0. 任意非 0 值将启用 OCSP 装订且覆盖默认的 3600 秒证书热重载时间(重载的同时执行 OCSP 装订)。
> `oneTimeLoading`: true | false
仅加载一次,默认 false. 值为 `true` 时将关闭证书热重载功能与 OCSP 装订功能。
> `usage`: "encipherment" | "verify" | "issue"
证书用途,默认值为 `"encipherment"`
- `"encipherment"`:证书用于 TLS 认证和加密。
- `"verify"`:证书用于验证远端 TLS 的证书。当使用此项时,当前证书必须为 CA 证书。
- `"issue"`:证书用于签发其它证书。当使用此项时,当前证书必须为 CA 证书。
::: tip TIP 1
在 Windows 平台上可以将自签名的 CA 证书安装到系统中,即可验证远端 TLS 的证书。
:::
::: tip TIP 2
当有新的客户端请求时,假设所指定的 `serverName``"xray.com"`,Xray 会先从证书列表中寻找可用于 `"xray.com"` 的证书,如果没有找到,则使用任一 `usage`
`"issue"` 的证书签发一个适用于 `"xray.com"` 的证书,有效期为一小时。并将新的证书加入证书列表,以供后续使用。
:::
::: tip TIP 3
`certificateFile``certificate` 同时指定时,Xray 优先使用 `certificateFile``keyFile``key` 也一样。
:::
::: tip TIP 4
`usage``"verify"` 时,`keyFile``key` 可均为空。
:::
::: tip TIP 5
使用 `xray tls cert` 可以生成自签名的 CA 证书。
:::
::: tip TIP 6
如已经拥有一个域名, 可以使用工具便捷的获取免费第三方证书,如[acme.sh](https://github.com/acmesh-official/acme.sh)
:::
> `buildChain`: true | false
仅当证书用途为 `issue` 时生效,若值为 `true` ,签发证书时将CA证书嵌入证书链。
::: tip TIP 1
不应该将根证书嵌入证书链。该选项只适合在签名CA证书为中间证书时启用。
:::
> `certificateFile`: string
证书文件路径,如使用 OpenSSL 生成,后缀名为 .crt。
> `certificate`: \[ string \]
一个字符串数组,表示证书内容,格式如样例所示。`certificate``certificateFile` 二者选一。
> `keyFile`: string
密钥文件路径,如使用 OpenSSL 生成,后缀名为 .key。目前暂不支持需要密码的 key 文件。
> `key`: \[ string \]
一个字符串数组,表示密钥内容,格式如样例如示。`key``keyFile` 二者选一。