mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-10-08 14:58:12 +03:00
Direct/Freedom outbound: Better Compatibility (#896)
https://github.com/XTLS/Xray-core/pull/6058
This commit is contained in:
+16
-16
@@ -4,23 +4,19 @@
|
||||
|
||||
Xray 内置的 DNS 模块,主要有三大用途:
|
||||
|
||||
- 在路由阶段,解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流。是否解析域名及分流和路由配置模块中 `domainStrategy` 的值有关,只有在设置以下两种值时,才会使用内置 DNS 服务器进行 DNS 查询:
|
||||
- "IPIfNonMatch", 请求一个域名时,进行路由里面的 domain 进行匹配,若无法匹配到结果,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行 IP 路由匹配。
|
||||
- "IPOnDemand", 当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。
|
||||
- 在路由阶段,解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流。<br>
|
||||
是否解析域名用以分流,与路由模块中 `routing.domainStrategy` 的值有关,只有在设置以下两种值时,才会使用内置 DNS 服务器进行 DNS 查询:
|
||||
- "IPIfNonMatch", 请求目标是域名且不附带 IP 时,先用其它条件进行一轮匹配,若本轮没有命中任何一条路由规则,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行一轮路由匹配。
|
||||
- "IPOnDemand", 请求目标是域名且不附带 IP 时,当路由匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。
|
||||
|
||||
- 解析目标地址进行连接:
|
||||
- 如 在 `freedom` 出站中,将 `domainStrategy` 设置为 `UseIP`, 由此出站发出的请求, 会先将域名通过内置服务器解析成 IP, 然后进行连接。
|
||||
- 如 在 `sockopt` 中,将 `domainStrategy` 设置为 `UseIP`, 此出站发起的系统连接,将先由内置服务器解析为 IP, 然后进行连接。
|
||||
- 在出站阶段,解析目标域名,用于连接或发送给远端代理服务器:
|
||||
- 如在 VLESS 出站中,将 `targetStrategy` 设置为 `UseIP`,会先通过本地的内置 DNS 模块解析被代理请求的目标域名,再将解析得到的 IP 发给远端代理服务器。
|
||||
- 如在 VLESS 出站中,将 `sockopt.domainStrategy` 设置为 `UseIP`,会通过内置 DNS 模块解析 VLESS 服务器的域名,再连接解析得到的 IP。
|
||||
- 如在 Freedom 出站中,将 `sockopt.domainStrategy` 设置为 `UseIP`,会通过内置 DNS 模块解析请求的目标域名,再连接解析得到的 IP。
|
||||
- 如在 Wireguard 出站中,协议不允许传递域名作为目标,可选用内置 DNS 模块解析为 IP。
|
||||
|
||||
- TUN/透明代理时通过路由和 DNS 出站组合,以劫持 DNS 流量到此模块;或直接对外暴露 53 端口充当递归 DNS 服务器。
|
||||
|
||||
::: tip TIP 1
|
||||
DNS 服务器默认进入路由系统进行匹配,除非其包含 `+local` 在其中使用域名时,注意可能的回环问题,`hosts` 可能有帮助。
|
||||
:::
|
||||
|
||||
::: tip TIP 2
|
||||
只支持最基本的 IP 查询(A 和 AAAA 记录),CNAME 记录将会重复查询直至返回 A/AAAA 记录为止。其它查询不会进入内置 DNS 服务器,而是根据你在出站中的配置可以丢弃或透传给其它服务器。
|
||||
:::
|
||||
- TUN/透明代理时通过路由和 DNS 出站组合,以劫持 DNS 流量到此模块;或利用 [Tunnel](./inbounds/tunnel.md) 直接对外暴露 53 端口充当递归 DNS 服务器。
|
||||
- 只支持最基本的 IP 查询(A 和 AAAA 记录),CNAME 记录将会重复查询直至返回 A/AAAA 记录为止。其它查询不会进入内置 DNS 服务器,而是根据你在出站中的配置可以丢弃或透传给其它服务器。
|
||||
|
||||
## DNS 处理流程
|
||||
|
||||
@@ -136,6 +132,10 @@ DNS 服务器默认进入路由系统进行匹配,除非其包含 `+local` 在
|
||||
(v1.4.0+) 可以在 [日志](./log.md) 中打开 DNS 查询日志。
|
||||
:::
|
||||
|
||||
::: tip TIP 4
|
||||
DNS 服务器默认进入路由系统进行匹配,除非其包含 `+local` 在其中使用域名时,注意可能的回环问题,`hosts` 可能有帮助。
|
||||
:::
|
||||
|
||||
> `clientIp`: string
|
||||
|
||||
EDNS Client Subnet 扩展中使用的 IP 地址。
|
||||
@@ -297,7 +297,7 @@ DNS 回退(failover)默认是串行的,即默认仅在选中的 DNS 服务
|
||||
|
||||
local 模式将直接由核心向外连接,这种情况下如果地址是一个域名将交由系统本身进行解析,逻辑较为简单。
|
||||
|
||||
非 local 默认将视为一个从 tag 为 dns.tag(不知道在哪? 浏览器 ctrl+f 搜索 `inboundTag`) 的入站进来的请求,将经过正常的核心处理流程,可能会被路由模块分配去本地 freedom 或者其他远端出站,它将被 freedom 的 domainStrategy 解析(注意可能的回环) 或者直接以域名的形式被传送到远端根据服务端本身的解析方式解析。
|
||||
非 local 模式下,DNS 查询会作为内部请求进入路由系统,其 `inboundTag` 由 DNS 配置的 `tag` 指定。若请求被路由到本地 Freedom 出站,DNS 服务器的自身的域名会按该出站的 `sockopt.domainStrategy` 解析(注意可能的回环);若请求被路由到远端代理出站,则可将域名交给远端解析。
|
||||
|
||||
由于普通人可能难以理清其中的逻辑,建议(特别是在透明代理的环境下),直接在 DNS 模块的 host 选项中直接为带域名的服务器设置它们对应的 IP 防止出现回环。
|
||||
|
||||
|
||||
+4
-34
@@ -19,10 +19,6 @@
|
||||
"settings": {},
|
||||
"tag": "标识",
|
||||
"streamSettings": {},
|
||||
"proxySettings": {
|
||||
"tag": "another-outbound-tag",
|
||||
"transportLayer": false
|
||||
},
|
||||
"mux": {},
|
||||
"targetStrategy": "AsIs"
|
||||
}
|
||||
@@ -67,48 +63,22 @@
|
||||
|
||||
此出站的传输配置。
|
||||
|
||||
> `proxySettings`: [ProxySettingsObject](#proxysettingsobject)
|
||||
|
||||
出站代理配置。
|
||||
|
||||
> `mux`: [MuxObject](#muxobject)
|
||||
|
||||
Mux 相关的具体配置。
|
||||
|
||||
> `targetStrategy`: "AsIs" | "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4" | "ForceIP" | "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4"
|
||||
|
||||
如果此出站尝试发送一个域名请求,控制其是否被解析/如何解析为 IP 并发送。
|
||||
适用于 Freedom 以外的出站,控制被代理请求中的目标域名是否在本地解析为 IP,以及使用何种解析策略。
|
||||
|
||||
默认值为 `AsIs` 即保持原样发送到远端服务器。所有参数含义均约等于 [sockopt](./transports/sockopt.md#sockoptobject) 中的 `domainStrategy`。
|
||||
默认值为 `AsIs`,即保持目标域名原样发送到远端服务器。各策略的含义与 [sockopt](./transports/sockopt.md#sockoptobject) 中的 `domainStrategy` 基本相同。
|
||||
|
||||
::: tip
|
||||
这里控制的是**被代理的请求**,如果出站代理服务器的地址是域名,并需要为这个域名本身选择解析策略,则应配置 [sockopt](./transports/sockopt.md#sockoptobject) 中的 `domainStrategy`。
|
||||
|
||||
Freedom 出站的域名解析策略也应配置 `sockopt.domainStrategy`。
|
||||
:::
|
||||
|
||||
### ProxySettingsObject
|
||||
|
||||
```json
|
||||
{
|
||||
"tag": "another-outbound-tag",
|
||||
"transportLayer": false
|
||||
}
|
||||
```
|
||||
|
||||
> `tag`: string
|
||||
|
||||
当指定另一个 outbound 的标识时,此 outbound 发出的数据,将被转发至所指定的 outbound 发出。
|
||||
|
||||
::: danger
|
||||
此选项与 [Sockopt.dialerProxy](./transports/sockopt.md#sockoptobject) 冲突,根据需要任选其一即可。
|
||||
|
||||
默认情况下,这种转发方式**会忽略**此出站自己的 `传输配置` (如有 XHTTP/REALITY/Sockopt...),也就是此 outbound 的 `streamSettings` 将不起作用。<br>
|
||||
如果需要使用支持 `streamSettings` 方式的转发,请改用 `Sockopt.dialerProxy` 或者将这里的 `transportLayer` 设为 `true`。
|
||||
:::
|
||||
|
||||
> `transportLayer`: true | false
|
||||
|
||||
`true` 将此设置转化为 `Sockopt.dialerProxy` 来支持此出站的 `streamSettings`,默认为 `false` 即不转化。
|
||||
|
||||
### MuxObject
|
||||
|
||||
Mux 功能是在一条 TCP 连接上分发多个 TCP 连接的数据。实现细节详见 [Mux.Cool](../development/protocols/muxcool.md)。Mux 是为了减少 TCP 的握手延迟而设计,而非提高连接的吞吐量。使用 Mux 看视频、下载或者测速通常都有反效果。Mux 只需要在客户端启用,服务器端自动适配。Mux 的第二个用途是分发多个 UDP 连接,即 XUDP。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Freedom(fragment、noises)
|
||||
|
||||
Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。
|
||||
Freedom 是一个直连出站协议,通常也是流量的终结点:它接收上游传来的 TCP 或 UDP 流量,并直接向最终目标地址发起连接、收发数据。
|
||||
|
||||
::: warning
|
||||
该出站在服务器端和反向代理端存在默认安全策略,可能会阻止一些目标,放行方式见下文 `finalRules`。
|
||||
@@ -16,9 +16,8 @@ Freedom 是一个出站协议,可以用来向任意网络发送(正常的)
|
||||
{
|
||||
// ...
|
||||
"protocol": "freedom",
|
||||
// [!code focus:29]
|
||||
// [!code focus:28]
|
||||
"settings": {
|
||||
"domainStrategy": "AsIs",
|
||||
"redirect": "127.0.0.1:3366",
|
||||
"userLevel": 0,
|
||||
"fragment": {
|
||||
@@ -51,63 +50,34 @@ Freedom 是一个出站协议,可以用来向任意网络发送(正常的)
|
||||
}
|
||||
```
|
||||
|
||||
> `domainStrategy`: "AsIs"<br>
|
||||
> "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4"<br>
|
||||
> "ForceIP" | "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4"
|
||||
|
||||
默认值 `"AsIs"`。
|
||||
|
||||
所有参数含义均约等于 [sockopt](../transports/sockopt.md#sockoptobject) 中的 domainStrategy.
|
||||
|
||||
在这里使用 AsIs 才可以把域名交给后面的 sockopt 模块,如果在这里设置非 AsIs 导致域名被解析为具体 IP 会使后续的 sockopt.domainStrategy 以及其相关的 happyEyeballs 失效。(如果不调整这两个设置则没有负面影响)
|
||||
|
||||
Freedom 在发送 UDP 时出于一些原因无视 sockopt 中的 domainStrategy 并在默认状态下强制偏好 IPv4.
|
||||
::: tip
|
||||
Freedom 的目标域名解析策略由 [sockopt.domainStrategy](../transports/sockopt.md#sockoptobject) 控制。
|
||||
:::
|
||||
|
||||
> `redirect`: address_port
|
||||
|
||||
Freedom 会强制将所有数据发送到指定地址(而不是 inbound 指定的地址)。
|
||||
Freedom 会将连接的当前目标地址和端口改写为 `redirect` 中指定的地址和端口。
|
||||
|
||||
其值为一个字符串,样例:`"127.0.0.1:80"`,`":1234"`。
|
||||
其值为一个字符串,样例:`"127.0.0.1:80"`、`":1234"`。
|
||||
|
||||
当地址不指定时,如 `":443"`,Freedom 不会修改原先的目标地址。
|
||||
当端口为 `0` 时,如 `"xray.com: 0"`,Freedom 不会修改原先的端口。
|
||||
当端口为 `0` 时,如 `"xray.com:0"`,Freedom 不会修改原先的端口。
|
||||
|
||||
> `userLevel`: number
|
||||
|
||||
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
|
||||
|
||||
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。 如不指定, 默认为 0。
|
||||
userLevel 的值, 对应 [policy](../policy.md#policyobject) 中 `level` 的值。如不指定,默认为 0。
|
||||
|
||||
> `fragment`: map
|
||||
> `fragment`: [FragmentObject](#fragmentobject)
|
||||
|
||||
一些键值对配置项,用于控制发出的 TCP 分片,在某些情况下可以欺骗审查系统,比如绕过 SNI 黑名单。
|
||||
|
||||
`"length"`和`"interval"` 均为 [Int32Range](../../development/intro/guide.md#int32range) 类型
|
||||
> `noises`: \[ [NoiseObject](#noiseobject) \]
|
||||
|
||||
`"packets"`:支持两种分片方式 "1-3" 是 TCP 的流切片,应用于客户端第 1 至第 3 次写数据。"tlshello" 是 TLS 握手包切片。
|
||||
UDP noise, 用于在发出 UDP 连接前发出一些随机数据作为“噪声”,出现该结构体则视为启用,可能可以欺骗嗅探器,也可能破坏正常连接。Use at your own risk. 出于这个原因,它会绕过 53 端口因为这会破坏 DNS。
|
||||
|
||||
`"length"`:分片包长 (byte)
|
||||
|
||||
`"interval"`:分片间隔(ms)
|
||||
|
||||
当其为 0 且设置 `"packets": "tlshello"` 时,被分片的 Client Hello 将会在一个TCP包中发送(如果其原始大小未超过MSS或MTU导致被系统自动分片)
|
||||
|
||||
> `noises`: array
|
||||
|
||||
UDP noise, 用于在发出UDP连接前发出一些随机数据作为“噪声”,出现该结构体则视为启用,可能可以欺骗嗅探器,也可能破坏正常连接。Use at your own risk. 出于这个原因,它会绕过53端口因为这会破坏 DNS
|
||||
|
||||
为一个数组,可以定义多个要发出的噪声数据包,数组中单个元素定义如下
|
||||
|
||||
`"type"`: 噪声数据包类型,目前支持`"rand"`(随机数据), `"str"`(用户自定义字符串), `"base64"`(base64编码过的自定义二进制数据)
|
||||
|
||||
`"packet"`: 基于前面的 `type` 要发送的数据包内容
|
||||
|
||||
- 当 `type` 为 rand 时,这里指定随机数据的长度 可以是固定值 `"100"` 或者浮动值 `"50-150"`
|
||||
- 当 `type` 为 str 时,这里指定要发送的字符串
|
||||
- 当 `type` 为 hex 时,这里指定以 hex 形式表示的的二进制数据
|
||||
- 当 `type` 为 base64 时,这里指定 base64 过的二进制数据
|
||||
|
||||
`"delay"`: 延迟,单位毫秒。发送该噪声包后核心会等待该时间后再发送下一个噪声包或真实数据,默认不等待,为 [Int32Range](../../development/intro/guide.md#int32range) 类型
|
||||
为一个数组,可以定义多个要发出的噪声数据包,数组中每个元素为一个 [NoiseObject](#noiseobject)。
|
||||
|
||||
> `proxyProtocol`: number
|
||||
|
||||
@@ -115,13 +85,23 @@ PROXY protocol 通常配合 `redirect` 重定向到开启了 PROXY protocol 协
|
||||
|
||||
proxyProtocol 的值为 PROXY protocol 版本号,可选 `1` 或 `2`,如不指定,默认为 `0` 不启用。
|
||||
|
||||
> `finalRules`: \[[FinalRuleObject](#finalruleobject)\]
|
||||
> `finalRules`: \[ [FinalRuleObject](#finalruleobject) \]
|
||||
|
||||
按顺序匹配 Freedom 最终出站规则,用于放行或阻止连接目标。
|
||||
|
||||
相比在 `routing` 中封锁,`finalRules` 位于 Freedom 最终出站阶段:在解析出最终 IP 后、拨号前匹配;此外 UDP 在收发时还会逐包匹配,因此更严谨、更彻底;每条规则匹配耗时约 50~150ns。
|
||||
相比在 `routing` 中封锁,`finalRules` 在 Freedom 最终出站阶段、拨号前后匹配;此外 UDP 在收发时还会逐包匹配因此更严谨、彻底。(每条规则匹配耗时约 50~150ns 无需担心性能)
|
||||
|
||||
注意:只要 Freedom 需要执行 `finalRules`,当 `domainStrategy` 为 `AsIs` 且目标为域名时,Freedom 仍会先通过操作系统 DNS 将目标解析为 IP,再执行规则匹配。此时目标已不再是域名,后续的 `sockopt.domainStrategy` 及其 `happyEyeballs` 不再生效。
|
||||
::: details 目标为域名?
|
||||
目标为域名且需要执行规则时,Freedom 会在拨号前按照 `sockopt.domainStrategy` 解析域名,然后对返回的所有 IP 分别按规则顺序匹配;只要其中一个 IP 被阻止,就会阻止整个请求。
|
||||
|
||||
拨号成功后,Freedom 还会按规则再次检查实际连接的远端 IP。因此,拨号前解析失败或两次解析结果不一致时,仍可能在黑洞前发出 TCP 握手报文。
|
||||
|
||||
每个目标为域名的 UDP 数据包在发送时还会解析域名,但逐包检查只对本次选中的目标 IP 按规则顺序匹配并决定是否拦截,不会检查解析返回的所有 IP。
|
||||
:::
|
||||
|
||||
::: tip
|
||||
若此出站配置了 `sockopt.dialerProxy`,Freedom 就不再是最终出站,因此不会执行 `finalRules` 或下述默认安全策略。
|
||||
:::
|
||||
|
||||
::: warning
|
||||
服务器端和反向代理端存在默认兜底安全策略:
|
||||
@@ -129,10 +109,59 @@ proxyProtocol 的值为 PROXY protocol 版本号,可选 `1` 或 `2`,如不
|
||||
若未命中任何显式规则,则使用内置兜底规则:来自 VLESS 反向代理的流量默认阻止所有目标;来自 `VLESS`、`VMess`、`Trojan`、`Shadowsocks`、`Hysteria` 或 `WireGuard` 入站的流量默认阻止私有及保留 IP;其它流量默认全部放行。
|
||||
|
||||
若服务器端需要允许客户端访问某些内网服务,应显式配置 `allow` 规则,并尽量只放行必要的 `network`、`ip` 和 `port`。
|
||||
|
||||
若服务器端还需要依赖域名传递给 `sockopt` 的特性(例如 `sockopt.domainStrategy` 或 `happyEyeballs`),则不能继续依赖这套默认安全策略。可将第一条规则配置为不带任何匹配条件的 `allow`,以恢复此前行为;这样也等同于关闭这套默认安全策略,应自行评估安全影响。
|
||||
:::
|
||||
|
||||
### FragmentObject
|
||||
|
||||
```json
|
||||
{
|
||||
"packets": "tlshello",
|
||||
"length": "100-200",
|
||||
"interval": "10-20"
|
||||
}
|
||||
```
|
||||
|
||||
> `packets`: string
|
||||
|
||||
支持两种分片方式 "1-3" 是 TCP 的流切片,应用于客户端第 1 至第 3 次写数据。"tlshello" 是 TLS 握手包切片。
|
||||
|
||||
> `length`: [Int32Range](../../development/intro/guide.md#int32range)
|
||||
|
||||
分片包长 (byte)
|
||||
|
||||
> `interval`: [Int32Range](../../development/intro/guide.md#int32range)
|
||||
|
||||
分片间隔(ms)
|
||||
|
||||
当其为 0 且设置 `"packets": "tlshello"` 时,被分片的 Client Hello 将会在一个 TCP 包中发送(如果其原始大小未超过 MSS 或 MTU 导致被系统自动分片)
|
||||
|
||||
### NoiseObject
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "base64",
|
||||
"packet": "7nQBAAABAAAAAAAABnQtcmluZwZtc2VkZ2UDbmV0AAABAAE=",
|
||||
"delay": "10-16"
|
||||
}
|
||||
```
|
||||
|
||||
> `type`: string
|
||||
|
||||
噪声数据包类型,目前支持`"rand"`(随机数据), `"str"`(用户自定义字符串), `"base64"`(base64编码过的自定义二进制数据)
|
||||
|
||||
> `packet`: string
|
||||
|
||||
基于前面的 `type` 要发送的数据包内容
|
||||
|
||||
- 当 `type` 为 rand 时,这里指定随机数据的长度 可以是固定值 `"100"` 或者浮动值 `"50-150"`
|
||||
- 当 `type` 为 str 时,这里指定要发送的字符串
|
||||
- 当 `type` 为 hex 时,这里指定以 hex 形式表示的的二进制数据
|
||||
- 当 `type` 为 base64 时,这里指定 base64 过的二进制数据
|
||||
|
||||
> `delay`: [Int32Range](../../development/intro/guide.md#int32range)
|
||||
|
||||
延迟,单位毫秒。发送该噪声包后核心会等待该时间后再发送下一个噪声包或真实数据,默认不等待。
|
||||
|
||||
### FinalRuleObject
|
||||
|
||||
```json
|
||||
@@ -162,7 +191,7 @@ proxyProtocol 的值为 PROXY protocol 版本号,可选 `1` 或 `2`,如不
|
||||
|
||||
目标端口范围,写法与 [路由规则中的 `port`](../routing.md#ruleobject) 一致。省略时匹配所有端口。
|
||||
|
||||
> `ip`: \[string\]
|
||||
> `ip`: \[ string \]
|
||||
|
||||
一个数组,数组内每一项代表一个 IP 范围。当某一项匹配目标 IP 时,此规则生效。写法与 [路由规则中的 `ip`](../routing.md#ruleobject) 一致。省略时匹配所有 IP。
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Loopback 是一个环回出站,用于将流量重新送回 routing 处理,
|
||||
::: tip 用途
|
||||
|
||||
- 在只能指定出站、不能直接写 `balancerTag` 的地方,借由 Loopback 间接使用 balancer<br>
|
||||
例如链式代理中的 `proxySettings`、`dialerProxy` 和负载均衡中的 `fallbackTag`
|
||||
例如链式代理中的 `dialerProxy` 和负载均衡中的 `fallbackTag`
|
||||
- 流量已经分流过一次后,再按更多条件继续细分<br>
|
||||
比如由同一组路由规则分流后的 TCP 流量和 UDP 要走不同的出站
|
||||
|
||||
|
||||
@@ -98,9 +98,9 @@ Wireguard 服务器列表,其中每一项是一个服务器配置。
|
||||
|
||||
当 Wireguard 服务器地址为域名、被代理流量目标地址是域名时,控制它们的域名解析策略。
|
||||
|
||||
不像绝大多数代理协议,Wireguard 不允许传递域名作为目标,所以如果传入目标为一域名需要解析为 IP 地址后传送,这会经由 Xray 内置DNS处理,此处字段含义见 `Freedom` 出站的 `domainStrategy`,默认值为 `ForceIP`。
|
||||
不像绝大多数代理协议,Wireguard 不允许传递域名作为目标,所以如果传入目标为域名,需要先解析为 IP 再传送。此处字段含义与 [sockopt.domainStrategy](../transports/sockopt.md#sockoptobject) 中对应的 `Force` 策略相同,默认值为 `ForceIP`。
|
||||
|
||||
`Freedom` 出站的 `domainStrategy` 包含诸如 `UseIP` 的选项,在这里不提供,因为 Wiregiard 必须获取一个可用的 IP,不能执行 `UseIP` 解析失败后回落为域名的行为。<br>
|
||||
`sockopt.domainStrategy` 包含诸如 `UseIP` 的选项,在这里不提供,因为 Wireguard 必须获取一个可用的 IP,不能执行 `UseIP` 解析失败后回落为域名的行为。<br>
|
||||
注意:作用于被代理流量时,此选项还受 `address` 选项的约束,比如你设置了 ForceIPv6v4 但是 address 中没有设置 IPv6 地址,尽管目标域名有 AAAA 记录也不会解析。
|
||||
|
||||
### Peers
|
||||
|
||||
@@ -97,30 +97,36 @@ Sockopt 用于配置底层网络行为。
|
||||
|
||||
默认值 `"AsIs"`。
|
||||
|
||||
当目标地址为域名时,配置相应的值,Outbound 连接远端服务器的行为模式如下:
|
||||
当出站需要连接的地址为域名时,此选项控制域名的解析方式:
|
||||
|
||||
- 当使用 `"AsIs"` 时, Xray 不对域名进行特殊处理,到最后 Xray 将直接使用 go 自带的 Dial 发起连接,优先级固定为 RFC6724 的默认值(不会遵守 gai.conf 等配置) 通常来说为 IPv6 优先。
|
||||
- 当填写其他值时,将使用 Xray-core [内置 DNS 服务器](../dns.md) 服务器进行解析。若不存在DNSObject,则使用系统DNS。若有多个符合条件的IP地址时,核心会随机选择一个IP作为目标IP。
|
||||
- 当使用 `"AsIs"` 时,Xray 将域名交给 Go 按操作系统 DNS 设置解析并连接。通常 TCP 优先尝试 IPv6,并在连接不顺利时尝试 IPv4;UDP 则优先使用 IPv4。
|
||||
|
||||
::: details AsIs 的地址选择与回退细节
|
||||
TCP 使用 Go 内置的 Happy Eyeballs。解析结果中第一个地址所属的地址族为首选地址族:若在 300 ms 后仍未连接成功,则开始尝试另一地址族;若首选地址族的全部连接尝试提前失败,则立即尝试另一地址族。这不受 Xray `sockopt.happyEyeballs` 配置控制。参见 [Go 拨号实现](https://go.dev/src/net/dial.go)。
|
||||
|
||||
使用纯 Go 编译的 Xray 时,地址按照 RFC 6724 的精简规则排序,条件相当时通常优先 IPv6,不读取 `/etc/gai.conf`。Xray 官方 release 版大多采用这种方式;部分操作系统或下游项目编译的版本行为可能略有不同不再赘述。参见 [Go 地址排序实现](https://go.dev/src/net/addrselect.go)。
|
||||
|
||||
UDP 优先选择解析结果中的 IPv4 地址,没有 IPv4 时才选择 IPv6;发送失败不会自动切换到另一地址族。`Use` 策略回退到 `AsIs` 时也遵循此行为。参见 [Go UDP 地址选择实现](https://go.dev/src/net/ipsock.go)。
|
||||
:::
|
||||
|
||||
- 当填写其他值时,将使用 Xray [内置 DNS 模块](../dns.md) 进行解析。若未配置 `DNSObject`,则使用系统 DNS。若有多个符合条件的 IP 地址,默认随机选择一个;TCP 启用 `sockopt.happyEyeballs` 后则通过竞速选择。
|
||||
- `"IPv4"` 代表只解析 IPv4。`"IPv4v6"` 代表先解析 IPv4,仅当解析报错或没有返回 IP 时再解析 IPv6;如果已经解析出 IPv4,之后连接失败不会回退到 IPv6。`"IPv6"`、`"IPv6v4"` 同理,地址族顺序相反。
|
||||
- 当在内置DNS设置了 `"queryStrategy"` 后,实际行为将会与这个选项取并,只有都被包含的IP类型才会被解析,如 `"queryStrategy": "UseIPv4"` `"domainStrategy": "UseIP"`,实际上等同于 `"domainStrategy": "UseIPv4"`。
|
||||
- 当使用 `"Use"` 开头的选项时,若解析结果不符合要求(如,域名只有IPv4解析结果但使用了UseIPv6),则会回落回AsIs。
|
||||
- 当使用 `"Force"` 开头的选项时,若解析结果不符合要求,则该连接会无法建立。
|
||||
- 当在内置 DNS 模块中设置了 `"queryStrategy"` 后,实际解析的 IP 类型取两个选项的交集,只有两者都允许的 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` 指定的本地地址不匹配,将会导致连接失败。
|
||||
::: tip
|
||||
当使用 `"UseIP"`、`"ForceIP"` 模式时,并且 [出站连接配置](../outbound.md#outboundobject) 中指定了 `sendThrough` 时,核心会根据 `sendThrough` 的值自动判断所需的 IP 类型,IPv4 或 IPv6。若手动指定了单种 IP 类型(如 UseIPv4),但与 `sendThrough` 指定的本地地址不匹配,将会导致连接失败。
|
||||
:::
|
||||
|
||||
::: danger
|
||||
:::: danger 启用了此功能后,不当的配置可能会导致死循环!
|
||||
连接到服务器,需要等待 DNS 查询结果;完成 DNS 查询,需要连接到服务器。
|
||||
|
||||
启用了此功能后,不当的配置可能会导致死循环。
|
||||
**不建议** 经验不足的用户擅自使用此功能。
|
||||
|
||||
一句话版本:连接到服务器,需要等待 DNS 查询结果;完成 DNS 查询,需要连接到服务器。
|
||||
::: details 详细解释
|
||||
|
||||
> Tony: 先有鸡还是先有蛋?
|
||||
|
||||
详细解释:
|
||||
|
||||
1. 触发条件:代理服务器(proxy.com)。内置 DNS 服务器,非 Local 模式。
|
||||
1. 触发条件:代理服务器地址是域名(proxy.com)。内置 DNS 服务器是非 Local 模式。
|
||||
2. Xray 尝试向 proxy.com 建立 TCP 连接 **前** ,通过内置 DNS 服务器查询 proxy.com。
|
||||
3. 内置 DNS 服务器向 dns.com 建立连接,并发送查询,以获取 proxy.com 的 IP。
|
||||
4. **不当的** 的路由规则,导致 proxy.com 代理了步骤 3 中发出的查询。
|
||||
@@ -136,16 +142,12 @@ Sockopt 用于配置底层网络行为。
|
||||
- 用 Hosts。
|
||||
- ~~如果你还是不知道解决方案,就别用这个功能了。~~
|
||||
|
||||
因此,**不建议** 经验不足的用户擅自使用此功能。
|
||||
:::
|
||||
::::
|
||||
|
||||
> `dialerProxy`: ""
|
||||
|
||||
一个出站代理的标识。当值不为空时,将使用指定的 outbound 发出连接。可用于支持传输配置的链式转发。
|
||||
|
||||
::: danger
|
||||
此选项与 ProxySettingsObject.Tag 不兼容
|
||||
:::
|
||||
一个出站代理的标识。当值不为空时,将使用指定的 outbound 发出连接。通常用于配置链式代理。
|
||||
|
||||
> `acceptProxyProtocol`: true | false
|
||||
|
||||
@@ -213,23 +215,19 @@ TCP 拥塞控制算法。仅支持 Linux。
|
||||
默认值 `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` 即关闭
|
||||
使用 SRV 记录或 TXT 记录指定出站使用的目标地址/端口,默认 `none` 即关闭。
|
||||
|
||||
查询直接通过系统DNS而不是Xray的内置DNS, 尝试去查询的域名将会是出站中的域名。如果查询失败请求会按原地址和端口发出
|
||||
查询直接通过系统 DNS 而不是 Xray 的内置 DNS, 尝试去查询的域名将会是出站中的域名。如果查询失败请求会按原地址和端口发出。
|
||||
|
||||
`Srv` 开头代表查询 SRV 记录(标准格式), `Txt` 开头代表查询 TXT 记录(格式形如 `127.0.0.1:80`)
|
||||
`Srv` 开头代表查询 SRV 记录(标准格式), `Txt` 开头代表查询 TXT 记录 (格式形如 `127.0.0.1:80`)。
|
||||
|
||||
`PortOnly` 仅重置端口 `AddressOnly` 仅重置地址 `PortAndAddress` 则重置地址和端口
|
||||
`PortOnly` 仅重置端口 `AddressOnly` 仅重置地址 `PortAndAddress` 则重置地址和端口。
|
||||
|
||||
该选项生效在 sockopt 里的 domainStrategy 解析之前,地址重置后仍会按 domainStrategy 的规则进行解析(如果有), 但是在 Freedom 的 domainStrategy 之后,如果在其中设置了解析为 IP 则本选项无法生效。
|
||||
该选项在 `sockopt.domainStrategy` 解析之前生效,地址重置后仍会按 `domainStrategy` 的规则进行解析。
|
||||
|
||||
PS: 如果有正常上网的域名流量被 AsIs 的 freedom 出站送过来,那么在此设置后会尝试解析并重置地址和端口,比如核心会尝试查询 google.com 的 SRV 记录并按记录重置目标。
|
||||
Freedom 出站不支持此选项。
|
||||
|
||||
> `customSockopt`: []
|
||||
|
||||
@@ -280,13 +278,12 @@ PS: 如果有正常上网的域名流量被 AsIs 的 freedom 出站送过来,
|
||||
|
||||
> `happyEyeballs`: [HappyEyeballsObject](#happyeyeballsobject)
|
||||
|
||||
RFC-8305 实现的 happyEyeballs,仅适用于 TCP。当目标为域名时对它们竞速并选择第一个成功的返回,仅当 `Sockopt.domainStrategy` 被设置为非 `AsIs` 时生效。
|
||||
RFC-8305 实现的 happyEyeballs,仅适用于 TCP。当目标为域名时对它们竞速并选择第一个成功的返回,仅当 `sockopt.domainStrategy` 被设置为非 `AsIs` 时生效。
|
||||
|
||||
注意:`UseIPv4v6` / `ForceIPv4v6` 会使可用的 IP 列表被缩减到仅剩 IPv4,仅当 IPv4 解析报错或没有返回 IP 时才会改为解析 IPv6;IPv4 连接失败不会触发该回退。不推荐这么用。建议使用 UseIP / ForceIP 配合 `HappyEyeballs.interleave`。
|
||||
注意:`UseIPv4v6` / `ForceIPv4v6` 会使可用的 IP 列表被缩减到仅剩 IPv4,仅当 IPv4 解析报错或没有返回 IP 时才会改为解析 IPv6;IPv4 连接失败不会触发该回退。不推荐这么用。建议使用 UseIP / ForceIP 配合 `happyEyeballs.interleave`。
|
||||
|
||||
::: warning
|
||||
使用这个功能时不要使用此出站的 `targetStrategy`,这会导致 `Sockopt` 只能看到被替换完毕的 IP。<br>
|
||||
此外也不能与 `dialerProxy` 一起使用,这会导致 `happyEyeballs` 无法生效。
|
||||
不能与 `dialerProxy` 一起使用,否则 `happyEyeballs` 无法生效。
|
||||
:::
|
||||
|
||||
### HappyEyeballsObject
|
||||
|
||||
Reference in New Issue
Block a user