如何优雅地搭建无污染 DNS
本文最后更新于:2023年2月20日 中午
前言
国内的 DNS 污染情况越来越严重,蛋疼的是很多情况下(特别是移不动宽带)境外域名会被污染到国内 IP,导致 Clash 等代理软件的分流失效(例如无法进入到 Fallback
的 DNS 查询中)。虽然上述问题可以通过增加规则来解决,但是秉承着 来都来了 的精神,我决定搭建一个自己的无污染 DNS 一劳永逸的解决这个问题。这个无污染 DNS 也可以放在 Fallback
的 DNS 中,加快境外网站解析。
关于 DNS 的选择可以参考 Sukka 大佬的 这篇文章。DNS 的基础知识也可以在大佬的 Blog 里面翻一翻。
搭建过程
准备工作
目前无污染的 DNS 一般是以下几种:
这里为了速度考虑,推荐搭建非标准端口 DNS 即可,也不会出现污染的情况(例如中科大 5353
端口 DNS),缺点是适用性不强,很多场合无法使用,但是对于我而言足够。
DNS 的下游服务器 强烈 推荐使用国内服务器,上游服务器可用其他公共服务器,也可以自己搭建。
进行 DNS 查询时首先会向下游服务器进行查询,下游服务器通过分流,国内域名直接通过公共服务器进行查询,境外域名转发到上游服务器进行查询。所以上下游服务器的延迟越低越好,例如深圳到香港。
首先安装好 Docker
和Docker 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 可能会有喝茶的风险。