mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-09-28 18:08:01 +03:00
DNS Outbound: Clear desc
This commit is contained in:
@@ -73,111 +73,17 @@ DNS 是一个出站协议,用于接收由 routing 送入的 DNS 查询,并
|
||||
- `direct`: 直接放行到目标 DNS 服务器;若同时配置了出站级别的 `network`、`address` 或 `port`,则按改写后的目标继续转发。
|
||||
- `hijack`: 将查询导入内置的 [DNS 服务器](../dns.md) 继续处理,可用于按照内置 DNS 的配置进一步分流;目前仅支持 A 和 AAAA 记录。
|
||||
- `drop`: 直接丢弃请求,不返回响应。
|
||||
- `reject`: 返回显式拒绝响应,相比 `drop` 可以避免应用长时间等待 DNS 超时。
|
||||
- `reject`: 返回显式拒绝响应,相比 `drop` 可以避免部分应用长时间等待 DNS 超时或反复重试。
|
||||
|
||||
> `qtype`: number | string
|
||||
|
||||
匹配 DNS 查询类型,有三种形式:
|
||||
匹配 DNS 查询类型,形式如下:
|
||||
|
||||
- `"a-b"`:`a` 和 `b` 均为整数。这个范围是一个前后闭合区间,当查询类型落在此范围内时,此规则生效。
|
||||
- `a`:`a` 为整数。当查询类型为 `a` 时,此规则生效。
|
||||
- 以上两种形式的混合,以逗号 `,` 分隔。形如:`"1,3,23-24"`。
|
||||
- 整型数值 具体的查询类型,如 `"qtype": 1` 代表 A 查询,`"qtype": 28` 代表 AAAA 查询。
|
||||
- 字符串:可以是一个只有数字的字符串,如 `"qtype": "28"`;或者一个数值范围,如 `"qtype": "5-10"` 表示type 5 到 type 10,这 6 个类型。可以使用逗号进行分段,如 `11,13,15-17` 表示type 11、type 13、type 15 到 type 17 这 5 个类型。
|
||||
|
||||
常见类型编号可参考 [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)。
|
||||
|
||||
省略时表示匹配所有查询类型。
|
||||
具体数字编号可参考 [IANA 文档](https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml)。
|
||||
|
||||
> `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` 向上游发起查询,避免形成回环。
|
||||
匹配域名列表,写法与 [路由规则中的 `domain`](../routing.md#ruleobject) 一致。
|
||||
|
||||
@@ -73,111 +73,17 @@ Defines the action to take when the rule matches.
|
||||
- `direct`: Allows the query directly to the target DNS server. If outbound-level `network`, `address`, or `port` is also configured, the query is forwarded to the rewritten target.
|
||||
- `hijack`: Imports the query into the built-in [DNS server](../dns.md) for further processing. This can be used for additional routing based on the built-in DNS configuration. Currently, only A and AAAA records are supported.
|
||||
- `drop`: Drops the request directly without returning a response.
|
||||
- `reject`: Returns an explicit refusal response. Compared with `drop`, this can prevent applications from waiting too long for a DNS timeout.
|
||||
- `reject`: Returns an explicit refusal response. Compared with `drop`, this can prevent some applications from waiting too long for a DNS timeout or repeatedly retrying.
|
||||
|
||||
> `qtype`: number | string
|
||||
|
||||
Matches DNS query types. It has three forms:
|
||||
Matches DNS query types. The forms are as follows:
|
||||
|
||||
- `"a-b"`: `a` and `b` are both integers. This is a closed interval; the rule takes effect when the query type falls within this range.
|
||||
- `a`: `a` is an integer. The rule takes effect when the query type is `a`.
|
||||
- A comma-separated mix of the two forms above. For example: `"1,3,23-24"`.
|
||||
- Integer value: a specific query type, such as `"qtype": 1` for an A query, or `"qtype": 28` for an AAAA query.
|
||||
- String: can be a digits-only string such as `"qtype": "28"`, or a numeric range such as `"qtype": "5-10"`, which represents the 6 types from type 5 to type 10. Commas can be used for segmentation, such as `11,13,15-17`, which represents the 5 types: type 11, type 13, and type 15 to type 17.
|
||||
|
||||
Common type numbers can be found in the [List of DNS record types](https://en.wikipedia.org/wiki/List_of_DNS_record_types).
|
||||
|
||||
If omitted, all query types are matched.
|
||||
For specific type numbers, refer to the [IANA documentation](https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml).
|
||||
|
||||
> `domain`: [string]
|
||||
|
||||
Matches a list of domains. The syntax is the same as [`domain` in routing rules](../routing.md#ruleobject), such as `domain:example.com`, `full:example.com`, and `geosite:cn`. If omitted, domains are not restricted.
|
||||
|
||||
## DNS Configuration Example
|
||||
|
||||
The following example demonstrates a practical scenario: in a transparent proxy environment, the inbound enables `sniffing` for domain / SNI routing, foreign domains go through the proxy, and other IP traffic goes directly. At the same time, `dns-out` refuses HTTPS records for foreign domains to reduce cases where clients obtain ECH configuration and affect plaintext SNI routing, forwards common MX, TXT, SRV, and similar queries to a specified upstream, and refuses AAAA queries because the proxy server has no IPv6 environment.
|
||||
|
||||
```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": {
|
||||
// Omitted...
|
||||
}
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The example behaves as follows:
|
||||
|
||||
- `all-in` enables `sniffing` and uses `routeOnly: true`, allowing routing to split traffic based on sniffed HTTP, TLS, and QUIC target domains while preserving the original target address.
|
||||
- UDP/TCP plaintext DNS queries from `all-in` to port 53 are routed to `dns-out`.
|
||||
- For regular traffic, `geosite:geolocation-!cn` goes through `proxy`; traffic that does not match this domain rule automatically uses the first outbound, `direct`.
|
||||
- HTTPS records with `qtype` `65` for domains in `geosite:geolocation-!cn` are explicitly refused, which can help with plaintext SNI-based routing.
|
||||
- AAAA queries with `qtype` `28` for domains in `geosite:geolocation-!cn` are explicitly refused, which can be used to block IPv6 resolution for foreign domains.
|
||||
- Queries with `qtype` `15-16,33` are allowed directly and forwarded to `1.1.1.1:53` according to the outbound configuration, using TCP as the transport.
|
||||
- Queries that do not match any rule enter the built-in fallback logic: A and AAAA queries are imported into the built-in DNS module, while other query types are explicitly refused. The built-in DNS then queries upstream through `https+local://1.1.1.1/dns-query`, avoiding a loop.
|
||||
Matches a list of domains. The syntax is the same as [`domain` in routing rules](../routing.md#ruleobject).
|
||||
|
||||
@@ -73,111 +73,17 @@ DNS-запросы сопоставляются с правилами по по
|
||||
- `direct`: напрямую пропускает запрос к целевому DNS-серверу. Если на уровне outbound также настроены `network`, `address` или `port`, запрос пересылается к измененной цели.
|
||||
- `hijack`: направляет запрос во встроенный [DNS-сервер](../dns.md) для дальнейшей обработки. Это можно использовать для дополнительного разделения трафика через конфигурацию встроенного DNS. В настоящее время поддерживаются только записи A и AAAA.
|
||||
- `drop`: напрямую отбрасывает запрос и не возвращает ответ.
|
||||
- `reject`: возвращает явный отказ. По сравнению с `drop`, это может предотвратить слишком долгое ожидание DNS timeout приложениями.
|
||||
- `reject`: возвращает явный отказ. По сравнению с `drop`, это может предотвратить долгое ожидание DNS timeout или повторные попытки у некоторых приложений.
|
||||
|
||||
> `qtype`: number | string
|
||||
|
||||
Сопоставляет типы DNS-запросов. Есть три формы:
|
||||
Сопоставляет типы DNS-запросов. Формы записи:
|
||||
|
||||
- `"a-b"`: `a` и `b` — целые числа. Это закрытый интервал; правило срабатывает, когда тип запроса попадает в этот диапазон.
|
||||
- `a`: `a` — целое число. Правило срабатывает, когда тип запроса равен `a`.
|
||||
- Комбинация двух форм выше через запятую. Например: `"1,3,23-24"`.
|
||||
- Целое число: конкретный тип запроса, например `"qtype": 1` соответствует запросу A, `"qtype": 28` — запросу AAAA.
|
||||
- Строка: может быть строкой только из цифр, например `"qtype": "28"`; или диапазоном значений, например `"qtype": "5-10"` — это типы с 5 по 10, всего 6 типов. Можно использовать запятую для разделения, например `11,13,15-17` — это 5 типов: тип 11, тип 13 и типы с 15 по 17.
|
||||
|
||||
Распространенные номера типов можно посмотреть в [List of DNS record types](https://en.wikipedia.org/wiki/List_of_DNS_record_types).
|
||||
|
||||
Если не указано, сопоставляются все типы запросов.
|
||||
Конкретные номера типов смотрите в [документации IANA](https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml).
|
||||
|
||||
> `domain`: [string]
|
||||
|
||||
Сопоставляет список доменов. Синтаксис такой же, как у [`domain` в правилах routing](../routing.md#ruleobject), например `domain:example.com`, `full:example.com`, `geosite:cn`. Если не указано, домены не ограничиваются.
|
||||
|
||||
## Пример конфигурации DNS
|
||||
|
||||
Следующий пример показывает практический сценарий: в прозрачном прокси inbound включает `sniffing` для разделения по домену / SNI, зарубежные домены идут через proxy, а остальной IP-трафик идет напрямую. При этом `dns-out` отклоняет HTTPS-записи для зарубежных доменов, чтобы уменьшить случаи, когда клиент получает ECH-конфигурацию и это влияет на разделение по открытому SNI; распространенные запросы вроде MX, TXT и SRV пересылаются указанному upstream, а запросы AAAA блокируются, потому что у proxy-сервера нет IPv6-среды.
|
||||
|
||||
```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, сохраняя исходный целевой адрес.
|
||||
- Открытые DNS-запросы UDP/TCP от `all-in` к порту 53 направляются правилом routing в `dns-out`.
|
||||
- Для обычного трафика `geosite:geolocation-!cn` идет через `proxy`; трафик, который не совпал с этим доменным правилом, автоматически использует первый outbound — `direct`.
|
||||
- HTTPS-записи с `qtype` `65` для доменов из `geosite:geolocation-!cn` явно отклоняются, что может помочь при разделении по открытому SNI.
|
||||
- AAAA-запросы с `qtype` `28` для доменов из `geosite:geolocation-!cn` явно отклоняются; это можно использовать для блокировки IPv6-резолвинга зарубежных доменов.
|
||||
- Запросы с `qtype` `15-16,33` напрямую разрешаются и пересылаются на `1.1.1.1:53` согласно конфигурации outbound, используя TCP в качестве транспорта.
|
||||
- Запросы, которые не совпали ни с одним правилом, попадают во встроенную fallback-логику: запросы A и AAAA направляются во встроенный DNS-модуль, а другие типы запросов явно отклоняются. Затем встроенный DNS обращается к upstream через `https+local://1.1.1.1/dns-query`, избегая зацикливания.
|
||||
Сопоставляет список доменов. Синтаксис такой же, как у [`domain` в правилах routing](../routing.md#ruleobject).
|
||||
|
||||
Reference in New Issue
Block a user