文档 配置 解析流程

解析流程

DNS 相关的字段有点多,容易搞不清谁的优先级更高。这里用一个例子把整条解析链路串起来讲一遍。

示例配置

config.yaml YAML
dns:
  nameserver:
    - https://doh.pub/dns-query
  fallback:
    - https://8.8.8.8/dns-query
  direct-nameserver:
    - system
  nameserver-policy:
    "geosite:cn,private":
      - https://doh.pub/dns-query
      - https://dns.alidns.com/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    geosite:
      - gfw
    ipcidr:
      - 240.0.0.0/4
    domain:
      - '+.google.com'

rules:
  - DOMAIN-SUFFIX,google.com,PROXY
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

完整流程

只讨论 dns 模块本身的处理过程,按流量类型分两条路径:

  1. 先看规则命中的是域名规则还是目标 IP 规则。如果是 DOMAIN-SUFFIX/GEOSITE 这类域名规则,直接进入解析环节;如果是 IP-CIDR/GEOIP 这类目标 IP 规则,需要先解析域名得到 IP 才能继续判断,也会进入解析环节。
  2. 域名规则命中直连,且配置了 direct-nameserver直接用 direct-nameserver 解析,不走下面的 nameserver-policy/nameserver 流程。
  3. 其余情况先看有没有配置 nameserver-policy域名命中某条策略(比如上例里 geosite:cn,private)就用该策略指定的服务器解析;没匹配到策略、或者压根没配置 nameserver-policy,则落到下一步用 nameserver
  4. 使用 nameserver 查询:如果同时配置了 fallback,会用 nameserverfallback 并发查询,再拿两边结果去匹配 fallback-filter(比如查到的 IP 命中 geoip-code: CN 但域名又不在白名单 domain 里,说明结果可能被污染),符合条件就采用 fallback 的结果,否则用 nameserver 的结果;没配置 fallback 则直接使用 nameserver 的结果。
  5. 得到 IP 之后再走一遍规则判断:如果域名规则已经命中代理,就把域名连同解析结果一起发给代理(代理服务器可能会自己重新解析);如果是目标 IP 规则命中直连,且配置了 direct-nameserver,还会用它重新解析一次再直连;否则直接用已经得到的 IP 连接。

direct-nameserver 重新解析目前仅限 TCP 连接;较新版本内核里也已应用到 UDP 连接(仅限 TUN 入站的 fake-ip 模式)。