容器化的无污染DNS服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Dnomd343 a856854055 update: remove legacy init script 2 years ago
asset fix: standlone ip without cidr 3 years ago
include update: server exit process 2 years ago
src docs: update README.md 2 years ago
toJSON update: parser read from file 2 years ago
.gitignore chore: update `.gitignore` 2 years ago
CMakeLists.txt feat: subprocess manage demo 3 years ago
Dockerfile update: process manager module 2 years ago
LICENSE docs: it's 2022 now 3 years ago
README.md docs: add principle of ClearDNS 2 years ago

README.md

ClearDNS

  • 无污染的 DNS 解析,避开运营商和防火长城的污染与劫持

  • 支持多种加密协议,包括 DoH 、DoT 、DoQ 与 DNSCrypt

  • 部署后更改 DHCP 选项即可生效,无需配置内网设备

  • DNS 请求审计,记录不同设备的查询日志

  • 自定义拦截规则,可屏蔽指定应用,如 QQ 、微信、微博等

  • IPv6支持,拦截特定的 DNS 请求类型,修改指定域名的 TTL

  • 在 DNS 层面上实现去广告与防跟踪功能,按需求配置自定义的拦截规则

  • 无论 APP 、网页还是机顶盒、IoT 设备等均可拦截

同时兼具强制 hosts 功能,将指定域名直接解析到指定 IP 上

ClearDNS 可部署在主路由器上,但需要路由器刷入支持 Docker 的固件;对于性能较低或不支持刷机的路由器,建议部署在内网一台长期开机的设备上(树莓派、小主机、旁路由等)。

设计架构

ClearDNS 运行架构:

  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)

请求在通过 AdGuardHome 处理后(可选),发往分流器 Diverter ,在这里将对请求,通过国内组 Domestic 与国外组 Foreign 的请求,甄别出被污染的数据,返回正确的 DNS 。两组请求都可拥有多个上游服务器,ClearDNS 可以逐个查询,亦可同时发起请求。

ClearDNS 支持多种协议,首先是常规 DNS ,即基于 UDP 或 TCP 的明文查询,该方式无法抵抗 DNS 污染,对部分运营商有效,仅建议用于国内无劫持的环境下使用;其次为 DNS over HTTPSDNS over TLSDNS over QUICDNSCrypt ,它们都是加密的 DNS 服务协议,格式为 ... ,在出境请求中,DNS over TLS 特别是标准端口的服务已经被大规模封杀,DNSCrypt 也基本无法使用,目前建议使用 DNS over QUIC 与非标准子路径的 DNS over HTTPS

对于多种 DNS 加密协议的简述,可以参考 ...

在分流器部分,ClearDNS 需要借助三个资源文件工作:

  • gfwlist.txt :记录被墙的常见域名

  • chinalist.txt :记录服务器在国内的创建域名

  • china-ip.txt :记录国内 IP 列表(CIDR 格式)

分流器接到请求时,如果在 chinalist.txt 中匹配,则只请求国内组,若与 gfwlist.txt 匹配,则请求国外组;未匹配的情况下,将同时请求两组查询,若国内组返回结果在 china-ip.txt 中,则证明 DNS 未被污染,采纳国内组结果,若返回非国内 IP ,则可能已经被污染,将返回国外组结果。

由于这方面记录一直在变动,ClearDNS 内置了更新功能,可自动这些资源文件;数据从多个上游项目收集,每天进行一次合并整理,整合数据的源码为 ... ,您可以自由配置更新服务器,或者禁用更新。

TODO: add update disable option

配置格式

ClearDNS 使用 YAML 作为默认配置格式,默认配置文件如下:

ClearDNS 兼容 JSON 与 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://res.dnomd343.top/Share/gfwlist/gfwlist.txt
    china-ip.txt: https://res.dnomd343.top/Share/chinalist/china-ip.txt
    chinalist.txt: https://res.dnomd343.top/Share/chinalist/chinalist.txt

Port

DNS 服务端口,支持 TCP 与 UDP 查询,默认为 53

Cache

DNS 缓存配置,此处与 AdGuardHome 中的缓存不相关,建议打开一个即可

cache:
  size: 0
  enable: false
  optimistic: false
  • enable :是否开启 DNS 缓存,默认为 false

  • size :DNS 缓存容量,单位为字节,开启时建议设置在 64k4m 量级,默认为 0

  • optimistic :DNS 乐观缓存,开启后在记录超过 TTL 后,仍然返回原数据(TTL 修改为 10),同时立即发起查询(绝大多数 DNS 记录在 TTL 期限内未发生变化)

AdGuard

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 :...

  • china-ip :...

Domestic

国内 DNS 配置选项

domestic:
  port: 4053
  verify: true
  parallel: true
  bootstrap: "..."
  primary:
    - ...
    - ...
  fallback:
    - ...
    - ...
  • port :国内组 DNS 端口,默认为 4053

  • verify :是否验证证书合法性,关闭后允许无效的 TLS 证书,默认为 true

  • parallel :是否对多个上游进行并行查询,默认为 true

  • bootstrap :引导 DNS 服务器,用于 primaryfallback 中 DNS 服务器域名的查询,必须为 Plain DNS ,此处可为一个字符串或字符串数组

  • primary :主 DNS 列表,用于默认情况下的查询

  • fallback :备用 DNS 服务器,当 primary 中 DNS 服务器无效时回落到此处再次查询

Foreign

domestic:
  port: 6053
  verify: true
  parallel: true
  bootstrap: "..."
  primary:
    - ...
    - ...
  fallback:
    - ...
    - ...
  • port :国外组 DNS 端口,默认为 6053

其余选项同上

Reject

DNS 拒绝类型,指定屏蔽的 DNS 记录类型

TODO: add dns record type (wiki)

reject:
  - 255

Hosts

Hosts 记录,指定域名对应 IP 地址

hosts:
  - "..."
  - "..."

TTL

配置特定域名的 ttl 时长,支持正则表达式匹配

ttl:
  - "..."
  - "..."

Custom

自定义脚本,在启动前执行

use ash of alpine

custom:
  - "..."

Assets

分流资源升级配置,用于自动更新资源文件

assets:
  cron: "..."
  url:
    gfwlist.txt: https://res.dnomd343.top/Share/...
    ...
  • cron :指定触发升级的 Crontab 表达式

  • url :指定资源升级的 URL 链接

部署教程

1. 网络配置

本项目基于 Docker 构建,在 Docker HubGithub Package 可以查看已构建的各版本镜像。

ClearDNS基于Docker网络有以下三种部署模式:

host模式 bridge模式 macvlan模式
网络原理 宿主机网络 桥接网络 虚拟独立mac网卡
服务IP 宿主机IP 宿主机IP 容器独立IP
宿主机IP 静态IP地址 静态IP地址 静态/动态IP地址
宿主机网络 无需改动网络配置 Docker自动适配 手动修改底层网络配置
宿主机端口 占用宿主机53,80,4053,5353,6053端口 占用宿主机53与80端口 不占用端口
管理完整性 完全 无法区分客户端 完全
宿主机耦合 强耦合 一般耦合 链路层以上完全分离
网络性能 相对较高 相对较低 相对适中
部署难度 简单 简单 复杂

不熟悉Linux网络配置请勿使用macvlan模式,新手建议首选host模式。

以下操作均于root用户下执行

# 检查Docker环境
shell> docker --version
Docker version ···, build ···

# 无Docker环境请先执行安装
shell> wget -qO- https://get.docker.com/ | bash

XProxy 同时发布在多个镜像源上:

  • Docker Hubdnomd343/cleardns

  • Github Packageghcr.io/dnomd343/cleardns

  • 阿里云镜像registry.cn-shenzhen.aliyuncs.com/dnomd343/cleardns

下述命令中,容器路径可替换为上述其他源,国内网络建议首选阿里云仓库

bridge模式
# 检查端口占用
shell> netstat -tlnpu | grep -E ":53|:80"
# 如果TCP/53或UDP/53已被占用,请先关闭对应进程
# 如果TCP/80端口被占用,可以关闭对应进程,也可使用其他端口
# 运行ClearDNS容器
# 映射系统时间文件以同步容器内部时区
shell> docker run --restart always \
--name cleardns -d \
-v /etc/cleardns/:/cleardns/ \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
-p 53:53/udp -p 53:53 -p 80:80 \
dnomd343/cleardns
# 此处为DockerHub镜像源,可按上文链接替换为其他源
host模式
# 检查端口占用
shell> netstat -tlnpu | grep -E ":53|:80|:4053|:5353|:6053"
# 如果UDP/53、UDP/4053、UDP/5353、UDP/6053、TCP/53、TCP/80、TCP/4053、TCP/5353、TCP/6053已被占用,请先关闭对应进程
# 运行ClearDNS容器
docker run --restart always \
--name cleardns -d \
--network host \
-v /etc/cleardns/:/cleardns/ \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
dnomd343/cleardns
# 此处为DockerHub镜像源,可按上文链接替换为其他源
macvlan模式

启动容器前需要创建一个macvlan网络

# 开启网卡混杂模式
shell> ip link set eth0 promisc on

# 创建macvlan网络,按实际情况指定网络信息
shell> docker network create -d macvlan \
--subnet=192.168.2.0/24 \
--gateway=192.168.2.1 \
-o parent=eth0 macvlan

宿主机网络更改配置

# Debian系示例
shell> vim /etc/network/interfaces

# 添加以下内容,按实际情况指定网络信息
auto eth0
iface eth0 inet manual

auto macvlan
iface macvlan inet static
  address 192.168.2.34
  netmask 255.255.255.0
  gateway 192.168.2.2
  dns-nameservers 192.168.2.3
  pre-up ip link add macvlan link eth0 type macvlan mode bridge
  post-down ip link del macvlan link eth0 type macvlan mode bridge

# 重启宿主机
shell> reboot

运行容器

shell> docker run --restart always \
--name cleardns \
--network macvlan \
--privileged -d \
-v /etc/cleardns/:/cleardns/ \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
dnomd343/cleardns
# 此处为DockerHub镜像源,可按上文链接替换为其他源

编辑macvlan网路的IP地址

# 编辑自定义初始化脚本
shell> vim /etc/cleardns/custom.sh

# 写入以下内容,修改容器的IP与网关,按实际网络情况指定
ip addr flush dev eth0
ip addr add 192.168.2.3/24 brd 192.168.2.255 dev eth0
ip route add default via 192.168.2.2

# 重启容器生效
shell> docker restart cleardns

# ClearDNS会将数据持久化,以在重启Docker或宿主机后保留配置及日志
# 使用以下命令清除之前的ClearDNS配置及数据
shell> rm -rf /etc/cleardns

2. 指定上游DNS服务器

上游DNS信息位于 /etc/cleardns/upstream.json,分为国内外两组,国内组可指定阿里DNS、DNSPod、114DNS等国内公共DNS服务,国外组需要指定可用的加密DNS服务,建议自行搭建DoH或DoT服务器。

ClearDNS支持多种DNS服务协议,包括常规DNS、DNS-over-TLS、DNS-over-HTTPS、DNS-over-QUIC、DNSCrypt。

DNSCrypt使用DNS Stamp封装,可以在这里在线解析或生成链接内容。

各协议格式示例如下:

# Plain DNS
1.1.1.1
8.8.8.8

# DNS-over-TLS
tls://223.5.5.5
tls://dns.alidns.com

# DNS-over-HTTPS
https://dns.pub/dns-query
https://223.5.5.5/dns-query

# DNS-over-QUIC
quic://dns.adguard.com

# DNSCrypt
sdns://AQIAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20

ClearDNS默认配置了以下DNS服务器

# 此处指定的国外组服务器可能已被GFW屏蔽,强烈建议使用私有加密DNS服务器
# bootstrap指定DNS服务器IP地址,用于解析加密DNS服务器域名,省略时使用系统DNS
# 若指定多台服务器,DNS请求时将并发查询,因此不宜指定过多服务器
# 当primary中DNS均不可用时,将自动尝试fallback中的DNS地址
{
  "domestic": {
    "bootstrap": "223.5.5.5",
    "primary": [
      "tls://dns.alidns.com",
      "https://doh.pub/dns-query"
    ],
    "fallback": [
      "223.5.5.5",
      "119.29.29.29"
    ]
  },
  "foreign": {
    "bootstrap": "8.8.8.8",
    "primary": [
      "tls://dns.google",
      "https://dns.cloudflare.com/dns-query"
    ],
    "fallback": [
      "1.1.1.1",
      "8.8.8.8"
    ]
  }
}

重启Docker容器生效

shell> docker restart cleardns

3. 配置域名分流规则

ClearDNS依据规则列表分流解析,使用以下规则文件,位于文件夹 /etc/cleardns/asset

以上文件将在每天凌晨4点自动更新,如果不想启用该功能,创建 /etc/cleardns/asset/no-update 文件即可。

规则文件默认从 res.dnomd343.top 拉取,若该域名被污染或屏蔽,你可以使用本项目 asset/gfwlist/buildasset/chinalist/build 下的构建脚本自行生成规则列表。

构建脚本需要访问Github获取资源,手动构建时请注意网络连通性。

4. 配置AdGuardHome

浏览器打开ClearDNS服务,host与bridge模式输入宿主机IP地址,macvlan模式输入容器IP,进入AdGuardHome配置界面,设置账号和密码,登录进入AdGuardHome管理界面。

进入 设置 - DNS设置,修改上游DNS为 127.0.0.1:5353,其他选项保持默认。此外,下方其他设置中建议启用DNSSEC,内存允许的情况下适当拉大缓存大小,并开启乐观缓存。

DNS封锁清单中,可配置以下规则:

  • AdGuardhttps://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt

  • Anti-ADhttps://anti-ad.net/easylist.txt

  • AdAwayhttps://adaway.org/hosts.txt

  • 乘风规则https://res.343.re/Share/Adblock-Rules/xinggsf.txt

配置过多的规则会导致设备负载变大,请酌情添加。

5. 配置DHCP信息

为了使ClearDNS生效,需要在路由器DHCP服务中指定DNS服务器,host与bridge模式指定为宿主机IP,macvlan模式指定为容器IP。

对于内网中一些固定IP信息的设备,需要手动更改其DNS为上述IP地址。

手动编译

本地构建

# 克隆仓库
shell> git clone https://github.com/dnomd343/ClearDNS.git
shell> cd ClearDNS
# 构建镜像
shell> docker build -t cleardns .

交叉构建

# 构建并推送至Docker Hub
shell> docker buildx build -t dnomd343/cleardns --platform="linux/amd64,linux/arm64,linux/386,linux/arm/v7" https://github.com/dnomd343/ClearDNS.git --push

许可证

MIT ©2022 @dnomd343