ClearDNS
容器化的无污染DNS服务
Install / Use
/learn @dnomd343/ClearDNSREADME
ClearDNS
-
✅ 无污染的 DNS 解析,避开运营商和防火长城的污染与劫持
-
✅ 支持多种加密协议,包括 DoH 、DoT 、DoQ 与 DNSCrypt
-
✅ 内置详细的分流规则,同时也支持自定义域名和 CIDR 策略
-
✅ DNS 请求审计,记录不同设备的查询、拦截、返回等信息
-
✅ 自定义拦截规则,可屏蔽指定应用,如 QQ 、微信、微博等
-
✅ 强制 hosts 功能,将指定域名直接解析到指定 IP 上
-
✅ IPv6 支持,拦截特定的 DNS 请求类型,修改指定域名的 TTL
-
✅ 在 DNS 层面上实现去广告与防跟踪功能,按需求配置自定义规则
由于 ClearDNS 工作在服务器一侧,因此对 APP 、网页、机顶盒、IoT 设备等均可生效;它一般部署在内网中,为局域网设备提供服务,建议运行在内网一台长期开机的设备上(主路由、树莓派、小主机、旁路由、NAS 设备等),同时 ClearDNS 也可部署在公网服务器上,面向国内网络提供无污染服务。
设计架构
AdGuardHome 用于加载拦截规则,可以自定义是否开启
graph LR
input{{Input}} -.-> adguard(AdGuardHome)
subgraph ClearDNS
adguard --> diverter(Diverter)
diverter --> domestic(Domestic)
diverter --> foreign(Foreign)
end
domestic -. Plain DNS .-> domestic_1(223.5.5.5)
domestic -. DNS over TLS .-> domestic_2(tls://dot.pub)
foreign -. DNS over QUIC .-> foreign_1(Private Server)
foreign -. DNS over HTTPS .-> foreign_2(Private Server)
DNS 请求在通过 AdGuardHome 处理后,发往分流器 Diverter ,在这里将借助路由资源、国内组 Domestic 与国外组 Foreign 的返回结果,甄别出被污染的数据,返回正确的 DNS 解析;两组请求都可拥有多个上游服务器,ClearDNS 可以逐个对服务器进行请求,亦可同时发起查询。
ClearDNS 支持多种 DNS 协议,首先是常规 DNS ,即基于 UDP 或 TCP 的明文查询,该方式无法抵抗 DNS 污染,对部分运营商有效(相当于不使用运营商分配的 DNS 服务器),仅建议用于国内无劫持的环境下使用;其次为 DNS over HTTPS 、DNS over TLS 、DNS over QUIC 与 DNSCrypt ,它们都是加密的 DNS 服务协议,可以抵抗污染与劫持行为,但可能被防火长城拦截;在出境请求中,DNS over TLS 特别是标准端口的服务已经被大规模封杀,DNSCrypt 也基本无法使用,目前建议使用 DNS over QUIC 与非标准路径的 DNS over HTTPS 服务。
对于多种 DNS 加密协议的简述,可以参考浅谈DNS协议,里面讲解了不同协议的区别与优缺点,以及 DNS 服务的分享格式。
在分流器部分,ClearDNS 需要借助三个资源文件工作:
-
gfwlist.txt:记录常见的被墙域名 -
chinalist.txt:记录服务器在国内的常见域名 -
china-ip.txt:记录国内 IP 段数据(CIDR 格式)
防火长城的 DNS 污染有一个特点,被污染的结果必为境外 IP 地址
当分流器接到请求时,若在 chinalist.txt 中有所匹配,则只请求国内组,若在 gfwlist.txt 中匹配,则仅请求国外组;两者均未未匹配的情况下,将同时请求国内组与国外组,若国内组返回结果在 china-ip.txt 中,则证明 DNS 未被污染,采纳国内组结果,若返回国外 IP 地址,则可能已经被污染,将选取国外组结果。
由于以上资源数据一直在变动,ClearDNS 内置了更新功能,用于自动获取新的资源文件;本项目提供了默认分流配置文件,从多个上游项目收集后合并,每天零点更新一次,数据处理的源码可见此处,下发地址如下:
-
gfwlist.txt:https://res.343.re/Share/cleardns/gfwlist.txt -
china-ip.txt:https://res.343.re/Share/cleardns/china-ip.txt -
chinalist.txt:https://res.343.re/Share/cleardns/chinalist.txt
国内用户直接访问下载站可能偏慢,建议使用以下镜像地址:
-
gfwlist.txt:https://cdn.dnomd343.top/cleardns/gfwlist.txt -
china-ip.txt:https://cdn.dnomd343.top/cleardns/china-ip.txt -
chinalist.txt:https://cdn.dnomd343.top/cleardns/chinalist.txt
在 ClearDNS 的默认配置文件中,使用了本项目的分流资源作为更新上游,您可以修改配置,指向自定义资源(支持多个本地或远程文件),也可禁用更新。
命令行参数
在 ClearDNS 启动时,可以指定以下命令行参数:
-
--config:指定配置文件名称,默认值为cleardns.yml -
--verbose:打印完整的日志信息 -
--debug:进入 Debug 模式 -
--version:显示版本信息 -
--help:显示帮助信息
ClearDNS 也支持通过环境变量指定参数,其优先级低于命令行参数:
-
CONFIG=my_config.yml:指定配置文件名称,默认值为cleardns.yml -
VERBOSE=TRUE:打印完整的日志信息 -
DEBUG=TRUE:进入 Debug 模式
配置格式
ClearDNS 支持 JSON 、YAML 与 TOML 格式的配置文件,默认配置如下:
port: 53
cache:
enable: true
size: 4194304
optimistic: true
diverter:
port: 5353
adguard:
enable: true
port: 80
username: admin
password: cleardns
domestic:
port: 4053
bootstrap: 223.5.5.5
primary:
- tls://dns.alidns.com
- https://doh.pub/dns-query
fallback:
- 223.6.6.6
- 119.29.29.29
foreign:
port: 6053
bootstrap: 8.8.8.8
primary:
- tls://dns.google
- https://dns.cloudflare.com/dns-query
fallback:
- 1.1.1.1
- 8.8.4.4
assets:
cron: "0 4 * * *"
update:
gfwlist.txt: https://cdn.dnomd343.top/cleardns/gfwlist.txt
china-ip.txt: https://cdn.dnomd343.top/cleardns/china-ip.txt
chinalist.txt: https://cdn.dnomd343.top/cleardns/chinalist.txt
Port
DNS 服务端口,支持常规的 TCP 与 UDP 查询,默认为 53 ;若您想开放 DNS over TLS 、DNS over HTTPS 等其他协议的服务,可以在 AdGuardHome 中进行具体配置。
Cache
DNS 缓存配置,此处与 AdGuardHome 中的缓存不相关,建议打开其中一个即可。
cache:
size: 0
enable: false
optimistic: false
-
enable:是否开启 DNS 缓存,默认为false -
size:DNS 缓存容量,单位为字节,开启时建议设置在64k到4m量级,默认为0 -
optimistic:DNS 乐观缓存,开启后当记录过期时,仍然返回上一次查询结果,但 TTL 修改为 10 ,同时立即向上游发起查询;由于绝大多数 DNS 记录在 TTL 期限内不会发生变化,这个机制可以显著减少请求平均延迟,但一旦出现变动,访问目标必须等待 10 秒后解析刷新才恢复正常。
AdGuard
AdGuardHome 配置选项,此处选项将在每次重启后覆盖 AdGuardHome 的网页端配置。
adguard:
enable: true
port: 80
username: admin
password: cleardns
-
enable:是否开启 AdGuardHome 功能,默认为false -
port:AdGuardHome 网页服务端口,默认为80 -
username:AdGuardHome 登录用户名,默认为admin -
password:AdGuardHome 登录密码,默认为cleardns
Diverter
DNS 分流器选项,指定端口与分流规则
diverter:
port: 5353
gfwlist: []
china_ip: []
chinalist: []
port:DNS 分流器端口,若 AdGuardHome 关闭,本选项将失效,默认为5353
以下选项用于添加自定义规则,将合并在资源文件上
-
gfwlist:自定义的 GFW 拦截域名列表,针对该域名的查询将屏蔽domestic组结果,默认为空 -
chinalist:自定义的国内域名列表,针对该域名的查询将屏蔽foreign组结果,默认为空 -
china-ip:自定义的国内 IP 段,domestic组返回内容若命中则采纳,否则使用foreign组结果,默认为空
Domestic
国内组 DNS 配置选项
domestic:
port: 4053
ipv6: true
verify: true
parallel: true
bootstrap: ...
primary:
- ...
- ...
fallback:
- ...
- ...
-
port:国内组 DNS 端口,默认为4053 -
ipv6:是否允许 IPv6 查询,关闭后将屏蔽AAAA请求,默认为true -
verify:是否验证证书合法性,关闭后允许无效的 TLS 证书,默认为true -
parallel:是否对多个上游进行并行查询,默认为true -
bootstrap:引导 DNS 服务器,用于primary与fallback中服务器域名的查询,仅允许常规 DNS 服务,默认为空 -
primary:主 DNS 服务器列表,用于默认情况下的查询 -
fallback:备用 DNS 服务器列表,当primary中 DNS 服务器宕机时,回落到本处再次查询
Foreign
国外组 DNS 配置选项
foreign:
port: 6053
ipv6: true
verify: true
parallel: true
bootstrap: ...
primary:
- ...
- ...
fallback:
- ...
- ...
port:国外组 DNS 端口,默认为6053
Foreign 选项意义与 Domestic 中相同,可参考上文说明
Reject
DNS 拒绝类型列表,指定屏蔽的 DNS 记录类型,不同 DNS 类型编号可参考DNS记录类型,默认为空。
reject:
- 255 # ANY
Hosts
Hosts 记录列表,指定域名对应 IP 地址,支持正则匹配,默认为空。
hosts:
- "10.0.0.1 example.com$"
- "..."
TTL
域名过期时间列表,修改指定域名返回的 TTL 数值,支持正则表达式匹配,默认为空。
ttl:
- "example.com$ 300"
- "..."
Custom
自定义脚本,将在 ClearDNS 初始化后,即将启动前执行。
本功能用于注入自定义功能,基于 Alpine 的
ash执行,可能不支持部分bash语法。
custom:
- "echo 'Hello World!'"
- "..."
Assets
资源文件升级选项,用于自动更新分流资源。
assets:
disable: false
cron: "0 4 * * *"
update:
gfwlist.txt: https://cdn.dnomd343.top/cleardns/gfwlist.txt
china-ip.txt: https://cdn.dnomd343.top/cleardns/china-ip.txt
chinalist.txt:
- https://cdn.dnomd343.top/cleardns/chinalist.txt
- /tmp/chinalist-local.txt
- demo.list # aka `${WorkDir}/assets/demo.list`
custom.txt:
- https://.../my-custom-asset.txt
-
disable:是否关闭资源文件加载,默认为false -
cron:指定触发升级的 Crontab 表达式
某一资源文件指定多个升级目标时,若其中任意一个出错,将导致该资源文件升级失败。
对于远程 URL 资源,ClearDNS 将尝试进行拉取,若发生网络错误将会重试,最多进行三次。
update:指定资源升级的上游,支持远程 URL 和本地文件,支持指定多个目标,将自动去重后合并。
部署教程
1. 网络配置
本项目基于 Docker 构建,在 Docker Hub 或 Github Package 可以查看已构建的各版本镜像。
ClearDNS 基于 Docker 网络有以下三种部署模式:
如果您对以网络知识不熟悉,或只想开箱即用,使用 Bridge 模式即可。
| | Host 模式 | Bridge 模式 | Macvlan 模式 | |:----------:|:----------------------------------------:|:------------------------:|:--------------------:| | 网络原理 | 宿主机网络 | 桥接网络 | 虚拟独立 mac 网卡 | | 服务 IP | 宿主机 IP | 宿主机 IP | 容器独立 IP | | 宿主机 IP | 静态 IP 地址 | 静态 IP 地址 | 静态/动态 IP 地址 | | 宿主机网络 | 无需改动网络配置 | Docker 自动适配 | 手动修改底层网络配置 | | 宿主机端口 | 占用宿主机 53, 80, 4053, 5353, 6053 端口 | 占用宿主机 53 与 80 端口 | 不占用端口 | | 管理完整性 | 完全 | 无法区分客户端 | 完全 | | 宿主机耦合 | 强耦合 | 一般耦合 | 链路层以上完全分离 | | 网络性能 | 相对较高 | 相对较低 | 相对适中 | | 部署难度 | 简单 | 简单 | 复杂 |
不熟悉 Linux 网络配置请勿使用 Macvlan 模式,新手建议选择 Bridge 或 Host 模式。
以下操作均于 root 用户下执行
# 检查Docker环境
$ docker --version
··· Docker 版本信息 ···
# 无Docker环境请先执行安装
$ wget -qO- https://get.docker.com/ | bash
··· Docker 安装日志 ···
下述命令中,容器路径可替换为上述其他源,国内网络可优先选择阿里云仓库
ClearDNS 同时发布在多个镜像源上:
-
Docker Hub:dnomd343/cleardns -
Github Package:ghcr.io/dnomd343/cleardns -
阿里云镜像:registry.cn-shenzhen.aliyuncs.com/dnomd343/cleardns
<details> <summary><b>Bridge 模式</b></summary> <br/>由于容器默认为 UTC-0 时区,将导致日志时间偏差 8 小时,映射
/etc/timezone与/etc/localtime文件用于同步时区信息
检查相关端口状态:
netstat -tlnpu | grep -E ":53|:80"
-
若
TCP/53或UDP/53被占用,请先关闭对应进程 -
若
TCP/80端口被占用,可以关闭对应进程,也可换用其他端口
启动 ClearDNS 容器:
docker run -dt \
--restart always \
--name cleardns --hostname cleardns \
--volume /etc/cleardns/:/cleardns/ \
--volume /etc/timezone:/etc/timezone:ro \
--volume /etc/localtime:/etc/localtime:ro \
-p 53:53/udp -p 53:53 -p 80:80 \
dnomd343/cleardns
或使用以下等效 docker-compose 配置:
version: '3'
services:
cleardns:
hostname: cleardns
container_name: cleardns
image: dnomd343/cleardns
network_mode: bridge
restart: always
tty: true
ports:
- '53:53'
- '80:80'
- '53:53/udp'
volumes:
- ./:/cleardns/
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
</details>
<details>
<summary><b>Host 模式</b></summary>
<br/>
检查相关端口状态:
netstat -tlnpu | grep -E ":53|:80|:4053|:5353|:6053"
-
若
TCP/53或UDP/53被占用,请先关闭对应进程 -
若
TCP/80端口被占用,可以关闭对应进程,也可换用其他端口 -
若
TCP/4053、UDP/4053、TCP/6053、UDP/6053、TCP/5353、UDP/5353被占用,请先关闭对应进程或换用其他空闲端口
启动 ClearDNS 容器:
docker run -dt --network host \
--restart always \
--name clea
