如何优雅地搭建无污染 DNS

本文最后更新于:2021年8月16日 凌晨

前言

国内的 DNS 污染情况越来越严重,蛋疼的是很多情况下(特别是移不动宽带)境外域名会被污染到国内 IP,导致 Clash 等代理软件的分流失效(例如无法进入到 Fallback 的 DNS 查询中)。虽然上述问题可以通过增加规则来解决,但是秉承着 来都来了 的精神,我决定搭建一个自己的无污染 DNS 一劳永逸的解决这个问题。这个无污染 DNS 也可以放在 Fallback 的 DNS 中,加快境外网站解析。

关于 DNS 的选择可以参考 Sukka 大佬的 这篇文章。DNS 的基础知识也可以在大佬的 Blog 里面翻一翻。

搭建过程

准备工作

目前无污染的 DNS 一般是以下几种:

这里为了速度考虑,推荐搭建非标准端口 DNS 即可,也不会出现污染的情况(例如中科大 5353 端口 DNS),缺点是适用性不强,很多场合无法使用,但是对于我而言足够。

DNS 的下游服务器 强烈 推荐使用国内服务器,上游服务器可用其他公共服务器,也可以自己搭建。

进行 DNS 查询时首先会向下游服务器进行查询,下游服务器通过分流,国内域名直接通过公共服务器进行查询,境外域名转发到上游服务器进行查询。所以上下游服务器的延迟越低越好,例如深圳到香港。

首先安装好 DockerDocker Compose, 这里不再赘述。

以下所有的源码可在我的项目找到:

搭建下游服务器(国内)

下游服务器采用Overture

将以下内容写入docker-compose.yaml

version: '3'

services:
  overture:
    image: ccr.ccs.tencentyun.com/dovlov/overture
    container_name: overture
    network_mode: "host"
    restart: always
    logging:
      driver: "json-file"
      options:
          max-size: "128k"

  redis:
    image: redis:alpine
    container_name: overture-redis
    ports:
      - 127.0.0.1:56379:6379
    restart: always

如果没有特殊需求直接用默认的配置文件即可,DNS 服务器会监听在 53535 端口。如果要自己修改 DNS 服务器,需要提前配置好 config.yaml 文件:

bindAddress: :53535
primaryDNS:
  - name: AliDNS
    address: 223.5.5.5:53
    protocol: udp
    socks5Address:
    timeout: 6
    ednsClientSubnet:
      policy: auto
      externalIP:
      noCookie: true
  - name: DNSPod
    address: 119.29.29.29:53
    protocol: udp
    socks5Address:
    timeout: 6
    ednsClientSubnet:
      policy: auto
      externalIP:
      noCookie: true
  - name: CNNIC
    address: 1.2.4.8:53
    protocol: udp
    socks5Address:
    timeout: 6
    ednsClientSubnet:
      policy: auto
      externalIP:
      noCookie: true
alternativeDNS:
  - name: LUG1
    address: 202.38.93.153:5353
    protocol: udp
    socks5Address:
    timeout: 6
    ednsClientSubnet:
      policy: auto
      externalIP:
      noCookie: true
  - name: LUG2
    address: 202.141.162.123:5353
    protocol: udp
    socks5Address:
    timeout: 6
    ednsClientSubnet:
      policy: auto
      externalIP:
      noCookie: true
  - name: TUNA
    address: 101.6.6.6:5353
    protocol: udp
    socks5Address:
    timeout: 6
    ednsClientSubnet:
      policy: auto
      externalIP:
      noCookie: true
onlyPrimaryDNS: false
ipv6UseAlternativeDNS: false
alternativeDNSConcurrent: true
whenPrimaryDNSAnswerNoneUse: primaryDNS
ipNetworkFile:
  primary: /overture/ip_network_primary_sample
  alternative: /overture/ip_network_alternative_sample
domainFile:
  primary: /overture/domain_primary_sample
  alternative: /overture/domain_alternative_sample
  matcher: full-map
hostsFile:
  hostsFile: /overture/hosts_sample
  finder: full-map
minimumTTL: 60
domainTTLFile: /overture/domain_ttl_sample
cacheSize: 4096
cacheRedisUrl: redis://127.0.0.1:56379/9
cacheRedisConnectionPoolSize: 50
rejectQType:
  - 255

❗注意:以上配置文件可能更新不即时,其他选项可以参考 原项目 README

修改 docker-compose.yaml 为以下内容:

version: '3'

services:
  overture:
    image: ccr.ccs.tencentyun.com/dovlov/overture
    container_name: overture
    network_mode: "host"
    volumes:
      - ./config.yaml:/overture/config.yaml # 修改为 config.yaml 所在位置
    restart: always
    logging:
      driver: "json-file"
      options:
          max-size: "128k"

然后运行下述命令,下游服务器就搭建好了:

docker-compose up -d

搭建上游服务器(境外)

上游服务器采用 SmartDNS。首先提前创建好conf 文件夹。

将以下内容写入docker-compose.yaml

version: '3'

services:
  overture:
    image: ghcr.io/apocalypsor/overture:upstream
    container_name: smartdns
    network_mode: "host"
    volumes:
      - ./conf:/smartdns
    restart: always
    logging:
      driver: "json-file"
      options:
          max-size: "128k"

无特殊要求直接用项目默认配置文件即可,DNS 会监听在 53535 端口,其他选项参考 原项目

然后运行下述命令,上游服务器就搭建好了:

docker-compose up -d

可以将上游服务器的 IP 和端口添加到下游服务器 config.yaml 文件的 AlternativeDNS 中,加快境外服务器解析。

自动更新

分流规则会随容器自动更新,所以只需要用 Watchtower 自动更新容器即可。命令如下:

docker run -d \
    --name watchtower \
    --restart always \
    -e TZ=Asia/Shanghai \
    -v /var/run/docker.sock:/var/run/docker.sock \
    containrrr/watchtower -c \
    --schedule "0 0 5 * * *"

用法

主要用法如下:

  • Clash:如果需要将无污染 DNS 用于 nameserver 中,建议 nameserver 中只用无污染 DNS,除了自己搭建的,还可用 202.38.93.153:5353(中科大)、202.141.178.13:5353(中科大)、202.141.162.123:5353(中科大)、208.67.222.222:5353(OpenDNS)、101.6.6.6:5353(清华,不推荐)。此外还能用于fallback 中也可以加快解析。
  • Surge/QuanX: 直接以 IP:PORT 的形式添加进 DNS 中即可。
  • Dnsmasq(Openwrt):以 server=IP#PORT 的形式写入配置文件中。

后记

通过搭建无污染 DNS 能够一定程序上加快境外网站的访问速度,也能够实现自定义 TTL 等功能。

最后提醒一下用国内服务器搭建 DNS 可能会有喝茶的风险。