mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-09-22 22:38:05 +03:00
Refine domainStrategy
This commit is contained in:
+14
-5
@@ -4,20 +4,29 @@
|
|||||||
|
|
||||||
Xray 内置的 DNS 模块,主要有三大用途:
|
Xray 内置的 DNS 模块,主要有三大用途:
|
||||||
|
|
||||||
- 在路由阶段,解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流。<br>
|
- 在路由阶段,解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流。
|
||||||
是否解析域名用以分流,与路由模块中 `routing.domainStrategy` 的值有关,只有在设置以下两种值时,才会使用内置 DNS 服务器进行 DNS 查询:
|
::: details 详细说明
|
||||||
- "IPIfNonMatch", 请求目标是域名且不附带 IP 时,先用其它条件进行一轮匹配,若本轮没有命中任何一条路由规则,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行一轮路由匹配。
|
是否解析域名用以 IP 分流,取决于 `routing.domainStrategy` 的值,只有在设置以下两种值时,才有可能使用内置 DNS 服务器进行 DNS 查询:
|
||||||
- "IPOnDemand", 请求目标是域名且不附带 IP 时,当路由匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。
|
- `"IPIfNonMatch"`:第一轮路由匹配未命中任何规则时,只要存在包含 `ip` 条件的规则且目标包含域名,就会使用内置 DNS 解析域名。
|
||||||
|
- `"IPOnDemand"`:只要目标包含域名,并遇到包含 `ip` 条件的规则,就会使用内置 DNS 解析域名。
|
||||||
|
|
||||||
- 在出站阶段,解析目标域名,用于连接或发送给远端代理服务器:
|
:::
|
||||||
|
|
||||||
|
- 在出站阶段,解析目标域名,用于连接或发送给远端代理服务器。
|
||||||
|
::: details 详细说明
|
||||||
- 如在 VLESS 出站中,将 `targetStrategy` 设置为 `UseIP`,会先通过本地的内置 DNS 模块解析被代理请求的目标域名,再将解析得到的 IP 发给远端代理服务器。
|
- 如在 VLESS 出站中,将 `targetStrategy` 设置为 `UseIP`,会先通过本地的内置 DNS 模块解析被代理请求的目标域名,再将解析得到的 IP 发给远端代理服务器。
|
||||||
- 如在 VLESS 出站中,将 `sockopt.domainStrategy` 设置为 `UseIP`,会通过内置 DNS 模块解析 VLESS 服务器的域名,再连接解析得到的 IP。
|
- 如在 VLESS 出站中,将 `sockopt.domainStrategy` 设置为 `UseIP`,会通过内置 DNS 模块解析 VLESS 服务器的域名,再连接解析得到的 IP。
|
||||||
- 如在 Freedom 出站中,将 `sockopt.domainStrategy` 设置为 `UseIP`,会通过内置 DNS 模块解析请求的目标域名,再连接解析得到的 IP。
|
- 如在 Freedom 出站中,将 `sockopt.domainStrategy` 设置为 `UseIP`,会通过内置 DNS 模块解析请求的目标域名,再连接解析得到的 IP。
|
||||||
- 如在 Wireguard 出站中,协议不允许传递域名作为目标,可选用内置 DNS 模块解析为 IP。
|
- 如在 Wireguard 出站中,协议不允许传递域名作为目标,可选用内置 DNS 模块解析为 IP。
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
- TUN/透明代理时通过路由和 DNS 出站组合,以劫持 DNS 流量到此模块;或利用 [Tunnel](./inbounds/tunnel.md) 直接对外暴露 53 端口充当递归 DNS 服务器。
|
- TUN/透明代理时通过路由和 DNS 出站组合,以劫持 DNS 流量到此模块;或利用 [Tunnel](./inbounds/tunnel.md) 直接对外暴露 53 端口充当递归 DNS 服务器。
|
||||||
|
::: details 详细说明
|
||||||
- 只支持最基本的 IP 查询(A 和 AAAA 记录),CNAME 记录将会重复查询直至返回 A/AAAA 记录为止。其它查询不会进入内置 DNS 服务器,而是根据你在出站中的配置可以丢弃或透传给其它服务器。
|
- 只支持最基本的 IP 查询(A 和 AAAA 记录),CNAME 记录将会重复查询直至返回 A/AAAA 记录为止。其它查询不会进入内置 DNS 服务器,而是根据你在出站中的配置可以丢弃或透传给其它服务器。
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## DNS 处理流程
|
## DNS 处理流程
|
||||||
|
|
||||||
域名将先执行 Hosts 映射检查(详见 `hosts` 字段),若没有查出需要的 IP,则继续使用 DNS 服务器进行查询。
|
域名将先执行 Hosts 映射检查(详见 `hosts` 字段),若没有查出需要的 IP,则继续使用 DNS 服务器进行查询。
|
||||||
|
|||||||
@@ -24,15 +24,13 @@
|
|||||||
|
|
||||||
域名解析策略,根据不同的设置使用不同的策略。
|
域名解析策略,根据不同的设置使用不同的策略。
|
||||||
|
|
||||||
- `"AsIs"`:不进行额外操作,使用目标地址里的域名或者 sniff 到的域名。默认值;
|
- `"AsIs"`:不进行 DNS 解析。默认值;
|
||||||
- `"IPIfNonMatch"`:一整轮匹配结束后,当没有命中任何规则时,将域名解析成 IP 再次进行二次匹配;
|
- `"IPIfNonMatch"`:先不进行域名解析,若一整轮匹配结束后未命中任何规则且目标包含域名,则重新开始第二轮匹配;第二轮遇到包含 `ip` 条件的规则时,使用内置 DNS 将域名解析为 IP 后进行匹配;
|
||||||
- `"IPOnDemand"`:在开始进行匹配前,直接先将域名解析为 IP 进行匹配;
|
- `"IPOnDemand"`:若目标包含域名,遇到包含 `ip` 条件的规则时,使用内置 DNS 将域名解析为 IP 后进行匹配;若解析失败,则使用原始目标 IP 进行匹配;
|
||||||
|
|
||||||
实际解析行为会被推迟到第一次遇到 IP 规则以降低延迟。结果将同时包含 IPv4 与 IPv6(你可以在内置 DNS 的 `queryStrategy` 进行二次限制) 域名解析出多条 IP 时每条规则将依次尝试全部 IP,只要任意一 IP 符合要求即视为命中规则。
|
解析结果将同时包含 IPv4 与 IPv6(可通过内置 DNS 的 `queryStrategy` 进一步限制)。域名解析出多个 IP 时,每条规则会依次尝试所有 IP;任一 IP 符合条件,即视为命中该规则。
|
||||||
|
|
||||||
当开启 sniff + routeOnly 使路由系统可以同时看见 IP 和域名时,如果发生上述的解析,路由系统只能看到由域名解析出的 IP 而无法看见原始目标 IP, 除非解析失败。
|
原始目标可能是 IP,也可能是域名。当开启 [`sniffing`](./inbound.md#sniffingobject) 且启用 `routeOnly` 时,路由系统除了原始目标外,还能看到嗅探得到的域名。因此,即使没有进行 DNS 解析,只要原始目标中已有 IP,路由系统仍可使用该 IP 进行规则匹配。当原始目标域名与嗅探结果同时存在时,无论用于 DNS 解析还是域名匹配,嗅探结果的优先级始终更高。
|
||||||
|
|
||||||
当存在两个域名时(目标域名 + sniff 结果), 无论是用于解析还是用于域名匹配,sniff 结果的优先级总是更高。
|
|
||||||
|
|
||||||
无论解析与否,路由系统不会影响真正目标地址,请求的目标仍然是原始目标。
|
无论解析与否,路由系统不会影响真正目标地址,请求的目标仍然是原始目标。
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,12 @@ Sockopt 用于配置底层网络行为。
|
|||||||
|
|
||||||
默认值 `"AsIs"`。
|
默认值 `"AsIs"`。
|
||||||
|
|
||||||
当出站需要连接的地址为域名时,此选项控制域名的解析方式:
|
此选项控制出站建立底层连接时,对连接目标域名的解析方式。
|
||||||
|
|
||||||
|
- VLESS、VMess、Trojan 等代理出站:底层连接的目标是代理服务器,因此此选项控制代理服务器域名的解析。被代理请求中的目标域名是否在本地解析,由出站的 [`targetStrategy`](../outbound.md#outboundobject) 控制。
|
||||||
|
- Freedom 出站:底层连接的目标就是请求的目标,因此此选项控制请求目标域名的解析。
|
||||||
|
|
||||||
|
各策略的含义如下:
|
||||||
|
|
||||||
- 当使用 `"AsIs"` 时,Xray 将域名交给 Go 按操作系统 DNS 设置解析并连接。通常 TCP 优先尝试 IPv6,并在连接不顺利时尝试 IPv4;UDP 则优先使用 IPv4。
|
- 当使用 `"AsIs"` 时,Xray 将域名交给 Go 按操作系统 DNS 设置解析并连接。通常 TCP 优先尝试 IPv6,并在连接不顺利时尝试 IPv4;UDP 则优先使用 IPv4。
|
||||||
|
|
||||||
@@ -106,7 +111,9 @@ Sockopt 用于配置底层网络行为。
|
|||||||
|
|
||||||
使用纯 Go 编译的 Xray 时,地址按照 RFC 6724 的精简规则排序,条件相当时通常优先 IPv6,不读取 `/etc/gai.conf`。Xray 官方 release 版大多采用这种方式;部分操作系统或下游项目编译的版本行为可能略有不同不再赘述。参见 [Go 地址排序实现](https://go.dev/src/net/addrselect.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)。
|
UDP 优先选择解析结果中的 IPv4 地址,没有 IPv4 时才选择 IPv6;发送失败不会自动切换到另一地址族。参见 [Go UDP 地址选择实现](https://go.dev/src/net/ipsock.go)。
|
||||||
|
|
||||||
|
注意,`Use` 策略可能因解析失败或结果不符合要求而回退到 `AsIs`,此时 TCP 和 UDP 均遵循上述行为。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
- 当填写其他值时,将使用 Xray [内置 DNS 模块](../dns.md) 进行解析。若未配置 `DNSObject`,则使用系统 DNS。若有多个符合条件的 IP 地址,默认随机选择一个;TCP 启用 `sockopt.happyEyeballs` 后则通过竞速选择。
|
- 当填写其他值时,将使用 Xray [内置 DNS 模块](../dns.md) 进行解析。若未配置 `DNSObject`,则使用系统 DNS。若有多个符合条件的 IP 地址,默认随机选择一个;TCP 启用 `sockopt.happyEyeballs` 后则通过竞速选择。
|
||||||
@@ -136,6 +143,8 @@ Sockopt 用于配置底层网络行为。
|
|||||||
8. 问题出现。步骤 3 中连接的建立,需要等待步骤 7 中的查询结果;步骤 7 完成查询,需要等待步骤 3 中的连接完全建立。
|
8. 问题出现。步骤 3 中连接的建立,需要等待步骤 7 中的查询结果;步骤 7 完成查询,需要等待步骤 3 中的连接完全建立。
|
||||||
9. Good Game!
|
9. Good Game!
|
||||||
|
|
||||||
|
Freedom 直连也可能出现同样的问题:若连接 DNS 服务器前,需要通过该服务器解析其自身域名,就会形成循环依赖。
|
||||||
|
|
||||||
解决方案:
|
解决方案:
|
||||||
|
|
||||||
- 改内置 DNS 服务器的分流。
|
- 改内置 DNS 服务器的分流。
|
||||||
|
|||||||
+14
-5
@@ -4,20 +4,29 @@
|
|||||||
|
|
||||||
The built-in DNS module in Xray has three main purposes:
|
The built-in DNS module in Xray has three main purposes:
|
||||||
|
|
||||||
- **Routing Phase:** Resolves domain names to IPs and matches rules based on the resolved IPs for traffic splitting.<br>
|
- **Routing Phase:** Resolves domain names to IPs and matches rules based on the resolved IPs for traffic splitting.
|
||||||
Whether a domain is resolved for routing depends on `routing.domainStrategy`. The built-in DNS server is used for DNS queries only with the following values:
|
::: details Detailed explanation
|
||||||
- `"IPIfNonMatch"`: When the request target is a domain name without an accompanying IP, Xray first performs a round of matching using the other conditions. If no routing rule matches in that round, it resolves the domain through the built-in DNS server and performs another round of routing rule matching using the returned IP addresses.
|
Whether a domain name is resolved for IP-based routing depends on `routing.domainStrategy`. The built-in DNS server may be used for DNS queries only with the following values:
|
||||||
- `"IPOnDemand"`: When the request target is a domain name without an accompanying IP, the domain is immediately resolved to IPs for matching as soon as routing encounters an IP-based rule.
|
- `"IPIfNonMatch"`: If no rule matches during the first routing pass, resolution occurs whenever the target includes a domain name and at least one rule contains an `ip` condition.
|
||||||
|
- `"IPOnDemand"`: Resolution occurs when the target includes a domain name and a rule containing an `ip` condition is encountered.
|
||||||
|
|
||||||
- **Outbound Phase:** Resolves target domain names for connections or for sending to a remote proxy server:
|
:::
|
||||||
|
|
||||||
|
- **Outbound Phase:** Resolves target domain names for connections or for sending to a remote proxy server.
|
||||||
|
::: details Detailed explanation
|
||||||
- For example, setting `targetStrategy` to `UseIP` in a VLESS outbound resolves the target domain of the proxied request through the local built-in DNS module, then sends the resolved IP to the remote proxy server.
|
- For example, setting `targetStrategy` to `UseIP` in a VLESS outbound resolves the target domain of the proxied request through the local built-in DNS module, then sends the resolved IP to the remote proxy server.
|
||||||
- Setting `sockopt.domainStrategy` to `UseIP` in a VLESS outbound resolves the VLESS server's domain through the built-in DNS module, then connects to the resolved IP.
|
- Setting `sockopt.domainStrategy` to `UseIP` in a VLESS outbound resolves the VLESS server's domain through the built-in DNS module, then connects to the resolved IP.
|
||||||
- Setting `sockopt.domainStrategy` to `UseIP` in a Freedom outbound resolves the request's target domain through the built-in DNS module, then connects to the resolved IP.
|
- Setting `sockopt.domainStrategy` to `UseIP` in a Freedom outbound resolves the request's target domain through the built-in DNS module, then connects to the resolved IP.
|
||||||
- WireGuard does not allow domain names as destinations, so its outbound can use the built-in DNS module to resolve them to IPs.
|
- WireGuard does not allow domain names as destinations, so its outbound can use the built-in DNS module to resolve them to IPs.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
- **TUN/Transparent Proxy DNS Traffic Hijacking:** Combines routing with the DNS outbound to hijack DNS traffic into this module; or uses [Tunnel](./inbounds/tunnel.md) to expose port 53 and act as a recursive DNS server.
|
- **TUN/Transparent Proxy DNS Traffic Hijacking:** Combines routing with the DNS outbound to hijack DNS traffic into this module; or uses [Tunnel](./inbounds/tunnel.md) to expose port 53 and act as a recursive DNS server.
|
||||||
|
::: details Detailed explanation
|
||||||
- Only basic IP queries (A and AAAA records) are supported. CNAME records will be queried repeatedly until an A/AAAA record is returned. Other queries will not enter the built-in DNS server; instead, they may be discarded or transparently forwarded to other servers depending on your outbound configuration.
|
- Only basic IP queries (A and AAAA records) are supported. CNAME records will be queried repeatedly until an A/AAAA record is returned. Other queries will not enter the built-in DNS server; instead, they may be discarded or transparently forwarded to other servers depending on your outbound configuration.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## DNS Processing Flow
|
## DNS Processing Flow
|
||||||
|
|
||||||
The domain first undergoes a Hosts mapping check (see the `hosts` field). If the required IP is not found, the DNS server is used for the query.
|
The domain first undergoes a Hosts mapping check (see the `hosts` field). If the required IP is not found, the DNS server is used for the query.
|
||||||
|
|||||||
@@ -24,15 +24,13 @@ For a more detailed analysis of the routing function: [Analysis of Routing (Part
|
|||||||
|
|
||||||
Domain resolution strategy. Different strategies are used based on different settings.
|
Domain resolution strategy. Different strategies are used based on different settings.
|
||||||
|
|
||||||
- `"AsIs"`: No extra operation. Uses the domain in the destination address or the sniffed domain. Default value.
|
- `"AsIs"`: Does not perform DNS resolution. Default value.
|
||||||
- `"IPIfNonMatch"`: When no rule is matched after a full round of matching, resolve the domain to an IP and perform a second round of matching.
|
- `"IPIfNonMatch"`: Domain names are not resolved initially. If no rule matches after the full pass and the target includes a domain name, Xray starts a second pass. During that pass, when it encounters a rule containing an `ip` condition, it uses the built-in DNS server to resolve the domain name to IPs for matching.
|
||||||
- `"IPOnDemand"`: Before starting matching, resolve the domain to an IP immediately for matching.
|
- `"IPOnDemand"`: If the target includes a domain name, Xray uses the built-in DNS server to resolve it to IPs for matching when it encounters a rule containing an `ip` condition. If resolution fails, the original destination IP is used for matching.
|
||||||
|
|
||||||
Actual resolution behavior will be delayed until the first IP rule is encountered to reduce latency. The result will contain both IPv4 and IPv6 (you can further restrict this via `queryStrategy` in the built-in DNS). When a domain resolves to multiple IPs, each rule will try all IPs in turn. If any IP meets the requirement, the rule is considered matched.
|
Resolution results contain both IPv4 and IPv6 addresses (this can be further restricted through the built-in DNS module's `queryStrategy`). When a domain name resolves to multiple IPs, each rule tries all of them in turn. If any IP meets the condition, the rule is considered matched.
|
||||||
|
|
||||||
When `sniff` + `routeOnly` is enabled, allowing the routing system to see both IP and domain, if the aforementioned resolution occurs, the routing system can only see the IP resolved from the domain and cannot see the original destination IP, unless resolution fails.
|
The original destination may be either an IP address or a domain name. When [`sniffing`](./inbound.md#sniffingobject) and `routeOnly` are enabled, the routing system can see the domain name obtained through sniffing in addition to the original destination. Therefore, even if no DNS resolution occurs, it can still use an IP already present in the original destination for rule matching. If both the original destination domain and the sniffing result are available, the sniffing result always takes precedence for both DNS resolution and domain matching.
|
||||||
|
|
||||||
When two domains exist (target domain + sniffed result), the priority of the sniffed result is always higher, whether for resolution or domain matching.
|
|
||||||
|
|
||||||
Regardless of whether resolution occurs, the routing system will not affect the actual destination address. The requested target remains the original target.
|
Regardless of whether resolution occurs, the routing system will not affect the actual destination address. The requested target remains the original target.
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,12 @@ When [tunnel](../inbounds/tunnel.md) has `followRedirect` set to `true`, and `tp
|
|||||||
|
|
||||||
The default value is `"AsIs"`.
|
The default value is `"AsIs"`.
|
||||||
|
|
||||||
When the address an outbound needs to connect to is a domain name, this option controls how it is resolved:
|
This option controls how the connection destination's domain name is resolved when an outbound establishes an underlying connection.
|
||||||
|
|
||||||
|
- Proxy outbounds such as VLESS, VMess, and Trojan: the underlying connection is to the proxy server, so this option controls resolution of the proxy server's domain name. Whether the target domain name in the proxied request is resolved locally is controlled by the outbound's [`targetStrategy`](../outbound.md#outboundobject).
|
||||||
|
- Freedom outbound: the underlying connection is to the request's target itself, so this option controls resolution of the request's target domain name.
|
||||||
|
|
||||||
|
The strategies work as follows:
|
||||||
|
|
||||||
- With `"AsIs"`, Xray passes the domain name to Go, which resolves it using the operating system's DNS settings and connects. TCP usually tries IPv6 first and tries IPv4 if the connection does not proceed smoothly; UDP prefers IPv4.
|
- With `"AsIs"`, Xray passes the domain name to Go, which resolves it using the operating system's DNS settings and connects. TCP usually tries IPv6 first and tries IPv4 if the connection does not proceed smoothly; UDP prefers IPv4.
|
||||||
|
|
||||||
@@ -102,7 +107,9 @@ When the address an outbound needs to connect to is a domain name, this option c
|
|||||||
|
|
||||||
With a pure Go build of Xray, addresses are sorted using a simplified version of RFC 6724, which usually prefers IPv6 when other conditions are equal and does not read `/etc/gai.conf`. Most official Xray release builds use this approach; behavior may differ slightly on some operating systems or in downstream builds. See [Go's address sorting implementation](https://go.dev/src/net/addrselect.go).
|
With a pure Go build of Xray, addresses are sorted using a simplified version of RFC 6724, which usually prefers IPv6 when other conditions are equal and does not read `/etc/gai.conf`. Most official Xray release builds use this approach; behavior may differ slightly on some operating systems or in downstream builds. See [Go's address sorting implementation](https://go.dev/src/net/addrselect.go).
|
||||||
|
|
||||||
UDP prefers an IPv4 address from the resolved results and uses IPv6 only if no IPv4 address is available. A send failure does not automatically switch to the other address family. This also applies when a `Use` strategy falls back to `AsIs`. See [Go's UDP address selection implementation](https://go.dev/src/net/ipsock.go).
|
UDP prefers an IPv4 address from the resolved results and uses IPv6 only if no IPv4 address is available. A send failure does not automatically switch to the other address family. See [Go's UDP address selection implementation](https://go.dev/src/net/ipsock.go).
|
||||||
|
|
||||||
|
Note that a `Use` strategy may fall back to `AsIs` if resolution fails or the results do not meet the requirements. In that case, both TCP and UDP follow the behavior described above.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
- With any other value, Xray uses its [built-in DNS module](../dns.md) for resolution. If no `DNSObject` is configured, system DNS is used. If multiple IP addresses match, one is selected randomly by default; when `sockopt.happyEyeballs` is enabled for TCP, the addresses are raced instead.
|
- With any other value, Xray uses its [built-in DNS module](../dns.md) for resolution. If no `DNSObject` is configured, system DNS is used. If multiple IP addresses match, one is selected randomly by default; when `sockopt.happyEyeballs` is enabled for TCP, the addresses are raced instead.
|
||||||
@@ -132,6 +139,8 @@ This feature is **not recommended** for inexperienced users unless they understa
|
|||||||
8. The problem appears: the connection from step 3 is waiting for the query result from step 7, while step 7 cannot finish until the connection from step 3 is fully established.
|
8. The problem appears: the connection from step 3 is waiting for the query result from step 7, while step 7 cannot finish until the connection from step 3 is fully established.
|
||||||
9. Good game.
|
9. Good game.
|
||||||
|
|
||||||
|
Direct connections through Freedom can have the same problem: if connecting to a DNS server requires resolving its own domain name through that same server, a circular dependency is created.
|
||||||
|
|
||||||
Possible solutions:
|
Possible solutions:
|
||||||
|
|
||||||
- Fix the traffic split of the built-in DNS server.
|
- Fix the traffic split of the built-in DNS server.
|
||||||
|
|||||||
+14
-5
@@ -4,20 +4,29 @@
|
|||||||
|
|
||||||
Встроенный модуль DNS в Xray имеет три основных назначения:
|
Встроенный модуль DNS в Xray имеет три основных назначения:
|
||||||
|
|
||||||
- На этапе маршрутизации: разрешение доменов в IP и сопоставление правил на основе полученных IP для разделения трафика.<br>
|
- На этапе маршрутизации: разрешение доменов в IP и сопоставление правил на основе полученных IP для разделения трафика.
|
||||||
Разрешение домена для маршрутизации зависит от значения `routing.domainStrategy`. Встроенный DNS-сервер используется для запросов только при следующих значениях:
|
::: details Подробное объяснение
|
||||||
- `"IPIfNonMatch"`: если цель запроса задана доменным именем без сопутствующего IP, сначала выполняется проход сопоставления по остальным условиям. Если за этот проход не совпало ни одно правило маршрутизации, домен разрешается через встроенный DNS-сервер, после чего выполняется еще один проход сопоставления правил с использованием полученных IP-адресов.
|
Разрешение доменного имени для маршрутизации по IP зависит от значения `routing.domainStrategy`. Встроенный DNS-сервер может использоваться для запросов только при следующих значениях:
|
||||||
- `"IPOnDemand"`: если цель запроса задана доменным именем без сопутствующего IP, при обнаружении правила, основанного на IP, домен сразу разрешается в IP для сопоставления.
|
- `"IPIfNonMatch"`: если в первом проходе маршрутизации не сработало ни одно правило, разрешение выполняется при условии, что цель содержит доменное имя и хотя бы одно правило содержит условие `ip`.
|
||||||
|
- `"IPOnDemand"`: разрешение выполняется, если цель содержит доменное имя и встречается правило с условием `ip`.
|
||||||
|
|
||||||
- На этапе исходящего подключения: разрешение целевых доменных имен для подключения или передачи удаленному прокси-серверу:
|
:::
|
||||||
|
|
||||||
|
- На этапе исходящего подключения: разрешение целевых доменных имен для подключения или передачи удаленному прокси-серверу.
|
||||||
|
::: details Подробное объяснение
|
||||||
- Например, если в исходящем подключении VLESS задать `targetStrategy` равным `UseIP`, целевой домен проксируемого запроса сначала разрешается локальным встроенным модулем DNS, затем полученный IP передается удаленному прокси-серверу.
|
- Например, если в исходящем подключении VLESS задать `targetStrategy` равным `UseIP`, целевой домен проксируемого запроса сначала разрешается локальным встроенным модулем DNS, затем полученный IP передается удаленному прокси-серверу.
|
||||||
- Если в исходящем подключении VLESS задать `sockopt.domainStrategy` равным `UseIP`, домен сервера VLESS разрешается встроенным модулем DNS, затем устанавливается соединение с полученным IP.
|
- Если в исходящем подключении VLESS задать `sockopt.domainStrategy` равным `UseIP`, домен сервера VLESS разрешается встроенным модулем DNS, затем устанавливается соединение с полученным IP.
|
||||||
- Если в исходящем подключении Freedom задать `sockopt.domainStrategy` равным `UseIP`, целевой домен запроса разрешается встроенным модулем DNS, затем устанавливается соединение с полученным IP.
|
- Если в исходящем подключении Freedom задать `sockopt.domainStrategy` равным `UseIP`, целевой домен запроса разрешается встроенным модулем DNS, затем устанавливается соединение с полученным IP.
|
||||||
- Протокол WireGuard не допускает передачу доменного имени в качестве цели, поэтому его исходящее подключение может использовать встроенный модуль DNS для разрешения доменов в IP.
|
- Протокол WireGuard не допускает передачу доменного имени в качестве цели, поэтому его исходящее подключение может использовать встроенный модуль DNS для разрешения доменов в IP.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
- Перехват DNS-трафика в режиме TUN/прозрачного прокси с помощью маршрутизации и исходящего подключения DNS для направления запросов в этот модуль; либо использование [Tunnel](./inbounds/tunnel.md) для открытия порта 53 и работы в качестве рекурсивного DNS-сервера.
|
- Перехват DNS-трафика в режиме TUN/прозрачного прокси с помощью маршрутизации и исходящего подключения DNS для направления запросов в этот модуль; либо использование [Tunnel](./inbounds/tunnel.md) для открытия порта 53 и работы в качестве рекурсивного DNS-сервера.
|
||||||
|
::: details Подробное объяснение
|
||||||
- Поддерживаются только базовые IP-запросы (записи A и AAAA). Записи CNAME будут запрашиваться повторно до тех пор, пока не будет возвращена запись A/AAAA. Другие типы запросов не попадают во встроенный DNS-сервер, а либо отбрасываются, либо передаются другим серверам в зависимости от вашей конфигурации исходящего подключения.
|
- Поддерживаются только базовые IP-запросы (записи A и AAAA). Записи CNAME будут запрашиваться повторно до тех пор, пока не будет возвращена запись A/AAAA. Другие типы запросов не попадают во встроенный DNS-сервер, а либо отбрасываются, либо передаются другим серверам в зависимости от вашей конфигурации исходящего подключения.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## Процесс обработки DNS
|
## Процесс обработки DNS
|
||||||
|
|
||||||
Домен сначала проходит проверку сопоставления Hosts (см. поле `hosts`). Если нужный IP не найден, для запроса используется DNS-сервер.
|
Домен сначала проходит проверку сопоставления Hosts (см. поле `hosts`). Если нужный IP не найден, для запроса используется DNS-сервер.
|
||||||
|
|||||||
@@ -24,15 +24,13 @@
|
|||||||
|
|
||||||
Стратегия разрешения доменных имен. Используются разные стратегии в зависимости от настройки.
|
Стратегия разрешения доменных имен. Используются разные стратегии в зависимости от настройки.
|
||||||
|
|
||||||
- `"AsIs"`: никаких дополнительных операций не выполняется, используется доменное имя из целевого адреса или доменное имя, полученное при sniff. Значение по умолчанию.
|
- `"AsIs"`: разрешение доменных имен через DNS не выполняется. Значение по умолчанию.
|
||||||
- `"IPIfNonMatch"`: после завершения целого раунда сопоставления, если ни одно правило не сработало, доменное имя разрешается в IP-адрес и выполняется повторное сопоставление.
|
- `"IPIfNonMatch"`: сначала доменные имена не разрешаются. Если после полного прохода не сработало ни одно правило и цель содержит доменное имя, Xray начинает второй проход. Во втором проходе при обнаружении правила с условием `ip` доменное имя разрешается в IP-адреса через встроенный DNS-сервер для сопоставления.
|
||||||
- `"IPOnDemand"`: перед началом сопоставления доменное имя сразу разрешается в IP-адрес для сопоставления.
|
- `"IPOnDemand"`: если цель содержит доменное имя, при обнаружении правила с условием `ip` Xray разрешает его в IP-адреса через встроенный DNS-сервер для сопоставления. Если разрешение завершается ошибкой, для сопоставления используется исходный IP-адрес назначения.
|
||||||
|
|
||||||
Фактическое разрешение будет отложено до момента, когда впервые встретится правило на основе IP, чтобы уменьшить задержку. Результат будет содержать одновременно IPv4 и IPv6 (вы можете дополнительно ограничить это через `queryStrategy` во встроенном DNS). Когда доменное имя разрешается в несколько IP-адресов, каждое правило по очереди пробует все IP-адреса; если хотя бы один IP соответствует требованию, правило считается сработавшим.
|
Результаты разрешения содержат одновременно адреса IPv4 и IPv6 (это можно дополнительно ограничить с помощью `queryStrategy` встроенного модуля DNS). Если доменное имя разрешается в несколько IP-адресов, каждое правило по очереди проверяет их все. Если хотя бы один IP-адрес соответствует условию, правило считается сработавшим.
|
||||||
|
|
||||||
Когда включены sniff + routeOnly, что позволяет системе маршрутизации одновременно видеть IP и доменное имя, в случае указанного выше разрешения система маршрутизации может видеть только IP, полученный из доменного имени, и не может видеть исходный целевой IP, если только разрешение не завершится неудачей.
|
Исходная цель может быть как IP-адресом, так и доменным именем. Когда включены [`sniffing`](./inbound.md#sniffingobject) и `routeOnly`, система маршрутизации помимо исходной цели видит доменное имя, полученное при анализе трафика. Поэтому даже без DNS-разрешения она может использовать для сопоставления IP-адрес, уже присутствующий в исходной цели. Если одновременно доступны доменное имя исходной цели и обнаруженное доменное имя, последнее всегда имеет приоритет как для DNS-разрешения, так и для сопоставления доменных имен.
|
||||||
|
|
||||||
Когда существуют два доменных имени (целевое доменное имя + результат sniff), приоритет результата sniff всегда выше, как при разрешении, так и при сопоставлении доменных имен.
|
|
||||||
|
|
||||||
Независимо от того, выполняется разрешение или нет, система маршрутизации не влияет на фактический целевой адрес. Целью запроса по-прежнему остается исходная цель.
|
Независимо от того, выполняется разрешение или нет, система маршрутизации не влияет на фактический целевой адрес. Целью запроса по-прежнему остается исходная цель.
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,12 @@ Sockopt используется для настройки низкоуровн
|
|||||||
|
|
||||||
Значение по умолчанию — `"AsIs"`.
|
Значение по умолчанию — `"AsIs"`.
|
||||||
|
|
||||||
Если адрес, к которому должно подключиться исходящее соединение, является доменным именем, эта настройка управляет способом его разрешения:
|
Этот параметр управляет разрешением доменного имени адресата при установлении базового сетевого соединения исходящим подключением.
|
||||||
|
|
||||||
|
- Исходящие подключения VLESS, VMess, Trojan и других прокси-протоколов: базовое сетевое соединение устанавливается с прокси-сервером, поэтому этот параметр управляет разрешением доменного имени прокси-сервера. За локальное разрешение целевого доменного имени в проксируемом запросе отвечает параметр [`targetStrategy`](../outbound.md#outboundobject) исходящего подключения.
|
||||||
|
- Исходящее подключение Freedom: базовое сетевое соединение устанавливается непосредственно с целью запроса, поэтому этот параметр управляет разрешением целевого доменного имени запроса.
|
||||||
|
|
||||||
|
Стратегии работают следующим образом:
|
||||||
|
|
||||||
- При `"AsIs"` Xray передает домен Go, который разрешает его с использованием DNS-настроек операционной системы и устанавливает соединение. Для TCP обычно сначала пробуется IPv6, а при затруднениях с подключением — IPv4; для UDP предпочтителен IPv4.
|
- При `"AsIs"` Xray передает домен Go, который разрешает его с использованием DNS-настроек операционной системы и устанавливает соединение. Для TCP обычно сначала пробуется IPv6, а при затруднениях с подключением — IPv4; для UDP предпочтителен IPv4.
|
||||||
|
|
||||||
@@ -102,7 +107,9 @@ Sockopt используется для настройки низкоуровн
|
|||||||
|
|
||||||
В сборках Xray на чистом Go адреса сортируются по упрощенным правилам RFC 6724: при прочих равных обычно предпочтителен IPv6, а `/etc/gai.conf` не читается. Большинство официальных релизных сборок Xray используют этот подход; в некоторых операционных системах или сторонних сборках поведение может немного отличаться. См. [реализацию сортировки адресов в Go](https://go.dev/src/net/addrselect.go).
|
В сборках Xray на чистом Go адреса сортируются по упрощенным правилам RFC 6724: при прочих равных обычно предпочтителен IPv6, а `/etc/gai.conf` не читается. Большинство официальных релизных сборок Xray используют этот подход; в некоторых операционных системах или сторонних сборках поведение может немного отличаться. См. [реализацию сортировки адресов в Go](https://go.dev/src/net/addrselect.go).
|
||||||
|
|
||||||
UDP предпочитает IPv4 из результатов разрешения и выбирает IPv6 только при отсутствии IPv4. Ошибка отправки не вызывает автоматического перехода на другое семейство адресов. Это поведение действует и при откате стратегии `Use` к `AsIs`. См. [реализацию выбора UDP-адреса в Go](https://go.dev/src/net/ipsock.go).
|
UDP предпочитает IPv4 из результатов разрешения и выбирает IPv6 только при отсутствии IPv4. Ошибка отправки не вызывает автоматического перехода на другое семейство адресов. См. [реализацию выбора UDP-адреса в Go](https://go.dev/src/net/ipsock.go).
|
||||||
|
|
||||||
|
Обратите внимание: стратегия `Use` может вернуться к `AsIs`, если разрешение завершилось ошибкой или результаты не соответствуют требованиям. В этом случае TCP и UDP следуют описанному выше поведению.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
- При любом другом значении используется [встроенный модуль DNS](../dns.md) Xray. Если `DNSObject` не настроен, используется системный DNS. Если подходят несколько IP-адресов, по умолчанию один выбирается случайно; при включенном `sockopt.happyEyeballs` для TCP выбор выполняется с помощью гонки подключений.
|
- При любом другом значении используется [встроенный модуль DNS](../dns.md) Xray. Если `DNSObject` не настроен, используется системный DNS. Если подходят несколько IP-адресов, по умолчанию один выбирается случайно; при включенном `sockopt.happyEyeballs` для TCP выбор выполняется с помощью гонки подключений.
|
||||||
@@ -132,6 +139,8 @@ Sockopt используется для настройки низкоуровн
|
|||||||
8. Возникает тупик: соединение из шага 3 ждет результат запроса из шага 7, а запрос из шага 7 не завершится, пока соединение из шага 3 не установится полностью.
|
8. Возникает тупик: соединение из шага 3 ждет результат запроса из шага 7, а запрос из шага 7 не завершится, пока соединение из шага 3 не установится полностью.
|
||||||
9. Game over.
|
9. Game over.
|
||||||
|
|
||||||
|
Прямое подключение через Freedom также может привести к этой проблеме: если для подключения к DNS-серверу нужно разрешить его собственное доменное имя через этот же сервер, возникает циклическая зависимость.
|
||||||
|
|
||||||
Возможные решения:
|
Возможные решения:
|
||||||
|
|
||||||
- Исправить маршрутизацию для встроенного DNS.
|
- Исправить маршрутизацию для встроенного DNS.
|
||||||
|
|||||||
Reference in New Issue
Block a user