由于个人高度强迫症, 平时上网避免一些奇奇怪怪的DNS污染以及方便自己多平台网络调试工具使用过程中的hosts绑定, 习惯性会为自己部署一个AdGuardHome作为递归DNS. 但是AdGuardHome虽然支持携带ECS查询, 但是官方并未支持基于GeoSite/GeoIP进行分流, 而自建DNS在面对拥有全球CDN的目标因错误的分流解析导致无法获得良好的访问速度就显得有些顾此失彼了, 得到群友的安利可以使用他自己写过的一个支持DNS代理分流的小工具, 在此记录特性及食用方法(本文依然配合AdGuardHome)

软件信息及特性

工具GitHub: DNS_automatic_traffic_splitting

核心亮点

全协议覆盖: UDP / TCP / DoT / DoQ / DoH (HTTP/2 + HTTP/3) 一站式支持

智能分流引擎: GeoSite 域名匹配 → GeoIP 结果验证 → 双路并发兜底,三级策略确保准确

并发竞速: 多上游同时查询,最快成功者胜出,SERVFAIL 不会抢占正确结果

Bootstrap解析: 内置独立引导解析器,带缓存和多服务器重试,避免循环依赖

ECS 优化: 自动附加 EDNS Client Subnet,让 CDN 返回最近节点

连接复用: TCP/DoT 支持 Pipelining (RFC 7766),DoH 支持 HTTP/3 (QUIC)

自动证书: 集成 Let's Encrypt,配置域名即可自动申请和续期 TLS 证书

Web管理面板: Liquid Glass 拟态风格,深色/浅色模式,完美适配移动端

自动更新: 启动时自动拉取最新 GeoIP.dat / GeoSite.dat

分流策略详解

┌─────────────────────────────────────────────────────────┐
│  1. Hosts 匹配        → 直接返回自定义 IP                  │
│  2. Rule 精确匹配     → 按规则走 CN / Overseas             │
│  3. Rule 正则匹配     → 按规则走 CN / Overseas             │
│  4. GeoSite 匹配      → CN 域名走国内,其他走海外           │
│  5. 双路并发查询       → 同时查国内+海外 DNS                │
│     ├─ 海外成功 + IP 是国内 → 采用国内 DNS 结果             │
│     ├─ 海外成功 + IP 是海外 → 采用海外 DNS 结果             │
│     ├─ 海外失败           → 自动使用国内 DNS 结果           │
│     └─ 全部失败           → 返回错误                       │
└─────────────────────────────────────────────────────────┘

安装部署

下载最新二进制版本至系统 /opt/sanite-dns 目录, 并赋予可执行权限

mkdir -p /opt/sanite-dns
curl -Lo /opt/sanite-dns/doh-autoproxy "https://github.com/Hamster-Prime/DNS_automatic_traffic_splitting/releases/download/latest/doh-autoproxy-linux-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/;s/i[3-6]86/386/')"
chmod +x /opt/sanite-dns/doh-autoproxy

准备好域名的SSL证书在 /opt/sanite-dns 目录创建一个config.yaml文件, 以下是配置模版, 由于我打算继续使用AdGuardHome, 所以我监听的127.0.0.1以及非标端口, 注意替换以下内容中 # 号注释部分为自己的内容

listen:
    dns_udp: 127.0.0.1:22253
    dns_tcp: 127.0.0.1:11153
    doh: 127.0.0.1:11443
    doh_path: /dns-query
    dot: 127.0.0.1:11853
    doq: 127.0.0.1:22853
bootstrap_dns:
    - tcp://8.8.8.8:53
    - tcp://9.9.9.11:53
    - tcp://1.1.1.1:53
upstreams:
    cn:
        - address: 223.5.5.5
          protocol: doh
          ecs_ip: ""
          pipeline: true
          http3: true
          insecure_skip_verify: false
        - address: 223.5.5.5
          protocol: dot
          ecs_ip: ""
          pipeline: true
          http3: false
          insecure_skip_verify: false
        - address: 223.5.5.5
          protocol: udp
          ecs_ip: ""
          pipeline: false
          http3: false
          insecure_skip_verify: false
        - address: 223.6.6.6
          protocol: tcp
          ecs_ip: ""
          pipeline: true
          http3: false
          insecure_skip_verify: false
    overseas:
        - address: 8.8.8.8
          protocol: dot
          ecs_ip: ""
          pipeline: true
          http3: false
          insecure_skip_verify: false
        - address: 8.8.8.8
          protocol: doh
          ecs_ip: ""
          pipeline: false
          http3: true
          insecure_skip_verify: false
        - address: dns.adguard-dns.com
          protocol: dot
          ecs_ip: ""
          pipeline: true
          http3: false
          insecure_skip_verify: false
        - address: dns11.quad9.net
          protocol: dot
          ecs_ip: ""
          pipeline: true
          http3: false
          insecure_skip_verify: false
geo_data:
    geoip_dat: GeoIP-Lite.dat
    geosite_dat: GeoSite-Lite.dat
    geoip_download_url: https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip-lite.db
    geosite_download_url: https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite-lite.dat
    auto_update: "05:00"
auto_cert:
    enabled: false
    email: your-email@example.com
    domains:
        - dns.example.com
    cert_dir: certs
tls_certificates:
    - cert_file: ## 填写证书文件路径
      key_file: ## 填写证书私钥路径
web_ui:
    enabled: true
    address: :8990
    username: ## web控制台用户名
    password: ## web控制台蜜吗
    cert_file: ""
    key_file: ""
    guest_mode: false
query_log:
    enabled: true
    file: query.log
    max_size_mb: 1
    save_to_file: true

执行以下bash命令将其添加到systemd服务

cat > /etc/systemd/system/sanite-dns.service << 'EOF'
[Unit]
Description=Sanite DNS Service
Before=shutdown.target
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/sanite-dns
ExecStart=/opt/sanite-dns/doh-autoproxy
Restart=always
RestartSec=1s
[Install]
WantedBy=multi-user.target
EOF

启动进程并加入开机自启

systemctl daemon-reload
systemctl enable sanite-dns.service --now

安装 AdGuardHome 使用GitHub主页中的一键脚本部署即可

在上游DNS服务器中填入 sanite-dns 的UDP协议和TCP协议的DNS

并且切记勾选 启用EDNS客户端子网

同时建议开启DNS缓存

AdGuardHome其它选项酌情设置

AdGuardHome前置设置

AdGuardHome就是用于网络工具连接的加密DNS, 一般使用DoH最佳, 国内环境不建议直接使用UDP协议和DoT, 避免UDP53被人使用导致IP被阻断, 需关闭无加密DNS

最后

为什么还要加个AdGuardHome, 不加可以吗?

不加可以, 由于DNS_automatic_traffic_splitting自身不会缓存DNS结果, 每次请求都会向上游查询, 如果只是个人使用通常问题不大, 如果多个客户端使用, 高峰期可能DNS出站请求相对密集, 部分服务器提供商可能会误判该服务器正在对外进行攻击, 所以前置一个AdGuardHome开启缓存可以相对缓解高并发的出站查询