mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-10-06 13:58:12 +03:00
DNS outbound: Add rules (matches qtype, domain, then action)
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@ Xray 内置的 DNS 模块,主要有三大用途:
|
||||
- 如 在 `freedom` 出站中,将 `domainStrategy` 设置为 `UseIP`, 由此出站发出的请求, 会先将域名通过内置服务器解析成 IP, 然后进行连接。
|
||||
- 如 在 `sockopt` 中,将 `domainStrategy` 设置为 `UseIP`, 此出站发起的系统连接,将先由内置服务器解析为 IP, 然后进行连接。
|
||||
|
||||
- 透明代理时劫持 DNS 流量;或直接对外暴露 53 端口充当递归 DNS 服务器。
|
||||
- TUN/透明代理时通过路由和 DNS 出站组合,以劫持 DNS 流量到此模块;或直接对外暴露 53 端口充当递归 DNS 服务器。
|
||||
|
||||
::: tip TIP 1
|
||||
DNS 服务器默认进入路由系统进行匹配,除非其包含 `+local` 在其中使用域名时,注意可能的回环问题,`hosts` 可能有帮助。
|
||||
|
||||
+146
-17
@@ -1,27 +1,38 @@
|
||||
# DNS
|
||||
|
||||
DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。
|
||||
DNS 是一个出站协议,用于接收由 routing 送入的 DNS 查询,并按规则转发或处理。
|
||||
|
||||
此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。
|
||||
此出站只支持传统明文 DNS,即基于 UDP 和 TCP 的查询;DoH、DoT、DoQ 等非传统明文 DNS 不适用于此出站。常见场景是 TUN、透明代理或 `dokodemo-door` 接收到 DNS 流量后,再由 routing 将其分流到此出站。
|
||||
|
||||
在处理 DNS 查询时,此出站协议会将 IP 查询(即 A 和 AAAA)转发给内置的 [DNS 服务器](../dns.md)。其它类型的查询流量见下的 `nonIPQuery`。
|
||||
它可以按规则将查询放行到目标 DNS 服务器、`hijack` 到内置的 [DNS 服务器](../dns.md) 进一步处理、直接丢弃或显式拒绝,也可以改写目标地址、端口和传输协议。
|
||||
|
||||
## OutboundConfigurationObject
|
||||
|
||||
```json
|
||||
{
|
||||
"network": "tcp",
|
||||
"network": "udp",
|
||||
"address": "1.1.1.1",
|
||||
"port": 53,
|
||||
"userLevel": 0,
|
||||
"nonIPQuery": "drop",
|
||||
"blockTypes": []
|
||||
"rules": [
|
||||
{
|
||||
"action": "reject",
|
||||
"domain": ["domain:example.com"]
|
||||
},
|
||||
{
|
||||
"action": "direct",
|
||||
"qtype": 65,
|
||||
"domain": ["geosite:geolocation-!cn"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> `network`: "tcp" | "udp"
|
||||
上例仅示意各字段写法,完整配置见下方示例。
|
||||
|
||||
修改 DNS 流量的传输层协议,可选的值有 `"tcp"` 和 `"udp"`。当不指定时,保持来源的传输方式不变。
|
||||
> `network`: [ "tcp" | "udp" ]
|
||||
|
||||
修改 DNS 流量的传输层协议,可选值为 `"tcp"` 和 `"udp"`。当不指定时,保持来源的传输方式不变。
|
||||
|
||||
> `address`: address
|
||||
|
||||
@@ -35,20 +46,138 @@ DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。
|
||||
|
||||
用户等级,连接会使用这个用户等级对应的 [本地策略](../policy.md#levelpolicyobject)。
|
||||
|
||||
userLevel 的值,对应 [policy](../policy.md#policyobject) 中 `level` 的值。如不指定,默认为 0。
|
||||
`userLevel` 的值,对应 [policy](../policy.md#policyobject) 中 `level` 的值。如不指定,默认为 `0`。
|
||||
|
||||
> `nonIPQuery`: string
|
||||
> `rules`: \[[RuleObject](#ruleobject)\]
|
||||
|
||||
控制非 IP 查询(非 A 和 AAAA),`"drop"` 丢弃; `"skip"` 不由内置 DNS 服务器处理,将转发给目标; `"reject"` 返回一个 DNS reject 响应,直接显式拒绝请求,相比 `"drop"` 可以避免应用程序消耗过长时间等待 DNS 响应到超时。
|
||||
按顺序匹配 DNS 查询规则,并支持按 `qtype` 和 `domain` 进行细粒度控制。
|
||||
|
||||
默认值为 `"reject"`。
|
||||
若未命中任何规则,则使用内置兜底规则:A 和 AAAA 查询会被导入内置 DNS 模块,其它类型会被显式拒绝。
|
||||
|
||||
> `blockTypes`: array
|
||||
## RuleObject
|
||||
|
||||
为一个 int 数组,屏蔽数组中的查询类型,如 `"blockTypes": [65,28]` 表示屏蔽 type 65(HTTPS) 和 28(AAAA). 常见用途包括屏蔽 type 65 以阻止浏览器发起 ECH.
|
||||
```json
|
||||
{
|
||||
"action": "hijack",
|
||||
"qtype": 1,
|
||||
"domain": ["geosite:cn"]
|
||||
}
|
||||
```
|
||||
|
||||
由于 `nonIPQuery` 默认 drop 所有非 A 和 AAAA 查询, 所以需要将其设置为 skip 本选项才能进一步发挥作用。当然也可以不修改,单纯用来屏蔽 A 或者 AAAA 来屏蔽 IPv4/IPv6 查询,但非常不推荐那么做,建议在内置 DNS 的 `queryStrategy` 对相关内容进行设置。
|
||||
规则中的各匹配条件为与关系;省略某个条件时,表示对此条件不作限制。
|
||||
|
||||
注意:当只使用 `blockTypes` 屏蔽 A 或 AAAA 时, 如果 `nonIPQuery` 设置为了 `reject` 那么屏蔽方式也会是返回 DNS reject 而不是丢弃。
|
||||
> `action`: [ "direct" | "hijack" | "drop" | "reject" ]
|
||||
|
||||
## DNS 配置实例 <Badge text="WIP" type="warning"/>
|
||||
定义规则命中后的动作。
|
||||
|
||||
- `direct`: 直接放行到目标 DNS 服务器;若同时配置了出站级别的 `network`、`address` 或 `port`,则按改写后的目标继续转发。
|
||||
- `hijack`: 将查询导入内置的 [DNS 服务器](../dns.md) 继续处理,可用于按照内置 DNS 的配置进一步分流;目前仅支持 A 和 AAAA 记录。
|
||||
- `drop`: 直接丢弃请求,不返回响应。
|
||||
- `reject`: 返回显式拒绝响应,相比 `drop` 可以避免应用长时间等待 DNS 超时。
|
||||
|
||||
> `qtype`: number | string
|
||||
|
||||
匹配 DNS 查询类型,有三种形式:
|
||||
|
||||
- `"a-b"`:`a` 和 `b` 均为整数。这个范围是一个前后闭合区间,当查询类型落在此范围内时,此规则生效。
|
||||
- `a`:`a` 为整数。当查询类型为 `a` 时,此规则生效。
|
||||
- 以上两种形式的混合,以逗号 `,` 分隔。形如:`"1,3,23-24"`。
|
||||
|
||||
常见类型编号可参考 [DNS 记录类型列表](https://zh.wikipedia.org/zh-cn/DNS%E8%AE%B0%E5%BD%95%E7%B1%BB%E5%9E%8B%E5%88%97%E8%A1%A8)。
|
||||
|
||||
省略时表示匹配所有查询类型。
|
||||
|
||||
> `domain`: [string]
|
||||
|
||||
匹配域名列表,写法与 [路由规则中的 `domain`](../routing.md#ruleobject) 一致,例如 `domain:example.com`、`full:example.com`、`geosite:cn`。省略时表示不限制域名。
|
||||
|
||||
## DNS 配置实例
|
||||
|
||||
下面的示例演示一个实际场景:透明代理环境中,入站开启 `sniffing` 做域名 / SNI 分流,国外域名走代理,其余 IP 流量直连;同时通过 `dns-out` 拒绝国外域名的 HTTPS 记录,以减少客户端获取 ECH 配置后影响明文 SNI 分流的情况,并将常见的 MX、TXT、SRV 等查询转发到指定上游;代理服务器没有 IPv6 环境因此还需要屏蔽 AAAA 查询。
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "all-in",
|
||||
"port": 12345,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"network": "tcp,udp",
|
||||
"followRedirect": true
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls", "quic"],
|
||||
"routeOnly": true
|
||||
},
|
||||
"streamSettings": {
|
||||
"sockopt": {
|
||||
"tproxy": "tproxy"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"dns": {
|
||||
"servers": ["https+local://1.1.1.1/dns-query"]
|
||||
},
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "direct",
|
||||
"protocol": "freedom"
|
||||
},
|
||||
{
|
||||
"tag": "proxy",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
// 忽略...
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "dns-out",
|
||||
"protocol": "dns",
|
||||
"settings": {
|
||||
"network": "tcp",
|
||||
"address": "1.1.1.1",
|
||||
"port": 53,
|
||||
"rules": [
|
||||
{
|
||||
"action": "reject",
|
||||
"qtype": "28,65",
|
||||
"domain": ["geosite:geolocation-!cn"]
|
||||
},
|
||||
{
|
||||
"action": "direct",
|
||||
"qtype": "15-16,33"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": ["all-in"],
|
||||
"network": "tcp,udp",
|
||||
"port": "53",
|
||||
"outboundTag": "dns-out"
|
||||
},
|
||||
{
|
||||
"domain": ["geosite:geolocation-!cn"],
|
||||
"outboundTag": "proxy"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
上例的行为如下:
|
||||
|
||||
- `all-in` 开启了 `sniffing`,并使用 `routeOnly: true` 让 routing 能基于嗅探出的 HTTP、TLS、QUIC 目标域名进行分流,同时保留原始目标地址。
|
||||
- 来自 `all-in`、发往 53 端口的 UDP/TCP 明文 DNS 查询,会被 routing 规则分流到 `dns-out`。
|
||||
- 普通流量中,`geosite:geolocation-!cn` 走 `proxy`,未命中该域名规则的流量自动默认走第一个出站 `direct`。
|
||||
- `geosite:geolocation-!cn` 中域名的 `qtype` 为 `65` 的 HTTPS 记录会被显式拒绝,可用于配合基于明文 SNI 的分流。
|
||||
- `geosite:geolocation-!cn` 中域名的 `qtype` 为 `28` 的 AAAA 查询会被显式拒绝,可用于屏蔽国外域名的 IPv6 解析。
|
||||
- `qtype` 为 `15-16,33` 的查询会被直接放行,并按出站配置转发到 `1.1.1.1:53`,传输方式改为 TCP。
|
||||
- 其余未命中的查询会进入默认兜底逻辑:A 和 AAAA 查询被导入内置 DNS 模块,其它类型被显式拒绝;内置 DNS 再通过 `https+local://1.1.1.1/dns-query` 向上游发起查询,避免形成回环。
|
||||
|
||||
Reference in New Issue
Block a user