Skip to content

DNS — Xray-core

dns 块用于配置 Xray 的内部解析器:一份服务器列表、可选的静态 hosts,以及一组缓存 / 回落开关。DNS 引擎自身也以内部入站形式存在 (默认 tag 为 dns),因此 DNS 流量可以像普通连接一样被路由。

顶层选项

字段类型默认值允许值描述
servers[]*NameServerConfig[][NameServerConfig | <string>]解析器列表。每个条目要么是地址字符串(`8.8.8.8`、`https://dns.google/dns-query`、`tcp+local://`、`fakedns` 等),要么是完整的 NameServerConfig 对象。
hosts*HostsWrapper{}{<domain or pattern>: <IP | [IP, …]>}静态 hosts。键支持与路由规则相同的 `full:`、`domain:`、`regexp:`、`keyword:`、`geosite:` 前缀。
clientIp*Address(unset)<IP>出站查询中携带的 ECS(EDNS Client Subnet)。可让支持 CDN 调度的解析器返回地理上更近的应答。
tagstringdns<inbound tag>DNS 引擎内部入站的 tag。被路由规则用来单独识别 DNS 流量。
queryStrategystringUseIPUseIP | UseIPv4 | UseIPv6在未设定单服务器策略时使用的默认查询策略。`UseIP` 同时查询 A 与 AAAA;`UseIPv4` / `UseIPv6` 跳过另一族。
disableCacheboolfalsetrue | false禁用内存中的应答缓存。每次查询都会重新发起。
serveStaleboolfalsetrue | false后台刷新过程中先返回已过期的缓存条目,改善感知延迟。
serveExpiredTTLuint320<seconds>`serveStale` 启用时,过期条目可继续被使用的最长秒数。0 表示无上限。
disableFallbackboolfalsetrue | false当第一台服务器没有返回可用答案时,不要回落到后续服务器。
disableFallbackIfMatchboolfalsetrue | false与上一项类似,但仅当命中的服务器自身带有 `domains` 列表时才禁用回落 —— 即按域名命中的服务器永远不会触发回落。
enableParallelQueryboolfalsetrue | false并行查询所有匹配的服务器,首个有效答案获胜。
useSystemHostsboolfalsetrue | false在走网络之前也查询操作系统的 `/etc/hosts`(或平台等价文件)。

源码: infra/conf/dns.go:160-173 · 锚定版本 v26.6.1 (94ffd50)

servers[] —— NameServerConfig

每个条目要么是裸地址字符串(被解析进 address),要么是完整对象 形式:

字段类型默认值允许值描述
address*Address(required)<DNS URL>解析器地址。裸 IP(`8.8.8.8` = UDP/53)、`tcp://`、`tls://`、`https://`、`quic://`、`tcp+local://...`(本地 DNS,不走代理)、`localhost` 或 `fakedns`。
clientIp*Address(inherit)<IP>单服务器的 ECS 覆盖。
portuint1653<port>服务器端口(仅对裸 IP 地址生效)。
skipFallbackboolfalsetrue | false为 true 时,此服务器返回空答案不会触发回落链 —— 查询直接失败。
domainsStringList[]<domain pattern>该服务器应当应答的域名。语法同路由规则。非空时,此服务器仅就这些域名被询问。
expectedIPsStringList[]<IP / CIDR / geoip:>只有解析结果匹配这些模式时才接受该服务器的应答。用于过滤被审查或被劫持的响应。
expectIPsStringList(alias)(alias of expectedIPs)`expectedIPs` 的兼容别名。
queryStrategystring(inherit)UseIP | UseIPv4 | UseIPv6单服务器的策略覆盖。
tagstring(unset)<string>服务器 tag —— 被路由规则用来路由解析器自身的出站流量。
timeoutMsuint644000<ms>单次查询的超时(毫秒)。
disableCache*bool(inherit)true | false单服务器的缓存覆盖。
serveStale*bool(inherit)true | false单服务器的 serve-stale 覆盖。
serveExpiredTTL*uint32(inherit)<seconds>单服务器的过期 TTL 上限。
finalQueryboolfalsetrue | false把该服务器标记为最终回落 —— 一旦它有应答,就不再向后解析。
unexpectedIPsStringList[]<IP / CIDR / geoip:>解析结果匹配这些模式时拒绝该服务器的应答。`expectedIPs` 的反向版。

源码: infra/conf/dns.go:19-35 · 锚定版本 v26.6.1 (94ffd50)

hosts

hosts 是扁平 map。键支持与路由规则相同的前缀;值要么是单个 IP, 要么是 IP 数组。

json
{
  "dns": {
    "hosts": {
      "domain:example.com": "203.0.113.10",
      "domain:internal.corp": ["10.0.0.1", "10.0.0.2"],
      "geosite:cn": "8.8.8.8"
    }
  }
}

把 IP 值写成 "fakedns",会让 Xray 返回 FakeDNS 池 中的伪地址。

示例

标准分流解析 —— CN 域名走本地 DoH,其余走 Cloudflare DoH:

json
{
  "dns": {
    "servers": [
      {
        "address": "https://doh.pub/dns-query",
        "domains": ["geosite:cn"],
        "expectedIPs": ["geoip:cn"]
      },
      "https://1.1.1.1/dns-query",
      {
        "address": "tcp+local://223.5.5.5",
        "domains": ["geosite:cn"]
      }
    ],
    "hosts": {
      "domain:example.com": "203.0.113.10"
    },
    "queryStrategy": "UseIP",
    "disableFallbackIfMatch": true,
    "enableParallelQuery": false
  }
}

配合 FakeDNS 的路由:

json
{
  "dns": {
    "servers": ["fakedns", "1.1.1.1"]
  },
  "fakeDns": { "ipPool": "198.18.0.0/15", "poolSize": 32768 },
  "inbounds": [{
    "port": 1080,
    "protocol": "socks",
    "sniffing": {
      "enabled": true,
      "destOverride": ["http", "tls", "fakedns"]
    }
  }]
}

说明

  • servers[] 中裸 8.8.8.8 字符串是 {"address": "8.8.8.8"} 的简写 —— NameServerConfigUnmarshalJSONinfra/conf/dns.go:36-43)接受两种形态。
  • address: "localhost" 使用操作系统解析器(在带 stub 解析器的平台 如 systemd-resolved 上很方便)。
  • address: "tcp+local://..." 通过 TCP 查询并 绕过 路由引擎 —— 适合作为整个 DNS 体系所依赖的引导解析器。
  • domains 模式:裸字符串默认按后缀匹配;带 full: 为精确匹配、 regexp: 为正则、keyword: 为子串、geosite: 为 GeoSite 类目。
  • expectedIPs / unexpectedIPs 联用实现「拒绝中毒应答」模式 —— 在国内解析器上设 expectedIPs: ["geoip:cn"],在公网解析器上设 unexpectedIPs: ["geoip:cn"]
  • clientIp(含按服务器的 clientIp)设置 EDNS Client Subnet 选项。设置成真实值(例如你的某个公网 IP)可获得 CDN 调度的答案。
  • finalQuery: true 将服务器标记为终端 —— 一旦它有应答,就不再 跑回落。

dns 出站

与上面的 dns 块不同,Xray 还提供一个 dns 出站"protocol": "dns")。把 DNS 流量路由给它,它要么把每条查询转发 到固定解析器,要么按规则列表来应答。近期 Xray 新增了目的地 改写 字段与 rules 引擎(旧的 nonIPQuery / blockTypes 旋钮现已 归为旧式)。

字段类型默认值允许值描述
rewriteNetworkNetwork(unset)tcp | udp | tcp,udp查询改写到的传输。旧式 `network` 的规范名。
rewriteAddress*Address(unset)<host>被拦截的 DNS 查询改写到的解析器。旧式 `address` 的规范名。
rewritePortuint160<port>查询改写到的端口。旧式 `port` 的规范名。
networkNetwork(alias)(alias of rewriteNetwork)`rewriteNetwork` 的旧式别名。
address*Address(alias)(alias of rewriteAddress)`rewriteAddress` 的旧式别名。
portuint16(alias)(alias of rewritePort)`rewritePort` 的旧式别名。
userLeveluint320<uint32>应用于该出站连接的策略等级。
rules[]*DNSOutboundRuleConfig(unset)[DNSOutboundRuleConfig]按查询的规则,按顺序求值;第一条命中决定查询的处理方式。
nonIPQuery*string(legacy)reject | drop | skip旧式的非 IP 查询处理。已弃用,改用 `rules`,且不能与之同时使用。
blockTypes*[]int32(legacy)[<qType number>]旧式的要拦截的 DNS 查询类型编号列表。已弃用,改用 `rules`。

源码: infra/conf/dns_proxy.go:60-71 · 锚定版本 v26.6.1 (94ffd50)

rules[]

字段类型默认值允许值描述
actionstring(required)direct | drop | return | hijack对匹配查询的处理方式。`direct` 原样转发;`drop` 丢弃;`return` 用 `rCode` 本地应答;`hijack` 将其重定向到改写服务器。
qType*PortList(any)<DNS type number / range>按编号匹配这些 DNS 查询类型(1 = A,28 = AAAA,65 = HTTPS 等)。接受逗号 / 范围列表。
domain*StringList(any)<domain pattern>匹配这些域名(默认按子串;与路由规则相同的模式前缀)。
rCodeuint3200-65535当 `action` 为 `return` 时返回的响应码(例如 5 = REFUSED,3 = NXDOMAIN)。

源码: infra/conf/dns_proxy.go:13-18 · 锚定版本 v26.6.1 (94ffd50)

把 A/AAAA 劫持到固定解析器,丢弃 HTTPS 记录(类型 65)查询,其余一律 拒绝:

json
{
  "outbounds": [
    {
      "tag": "dns-out",
      "protocol": "dns",
      "settings": {
        "rewriteAddress": "1.1.1.1",
        "rewritePort": 53,
        "rewriteNetwork": "udp",
        "rules": [
          { "action": "hijack", "qType": "1,28" },
          { "action": "drop",   "qType": "65" },
          { "action": "return", "rCode": 5 }
        ]
      }
    }
  ]
}

nonIPQueryblockTypes 不能与 rules 混用 —— 这么做会触发 启动错误。请把旧式配置迁移到 rules

跨内核说明

  • sing-box 使用按 type 多态的服务器 schema(type: "https"type: "tls"type: "fakeip" 等),并配合带 action: "route"|"reject"|"predefined" 的结构化 DNS 规则。参见 DNS — sing-box
  • mihomo 用扁平 dns: 块,含独立的 nameserver / fallback 列表,再加强大的 nameserver-policy 映射做按域路由。参见 DNS — mihomo

源码: infra/conf/dns.go:19-173 · v26.6.1 (94ffd50)

由 Argsment 出品的 Core Tutorial