docker 搭建 overture 无污染 DNS

  • 自编译overture镜像,国内DNS分流,无污染DNS等.

  • 资料来源:

    https://github.com/shawn1m/overture
    https://moe.best/tutorial/overture.html
    https://hub.docker.com/r/daxingplay/docker-overture/dockerfile

  • 更新

1
2
3
4
5
19.01.30 初始化
19.07.22 添加dockerhub相关内容
19.12.28 重构脚本,更新新版本,重写了大部分博文内容等.
20.06.09 更新一部分新内容,但未完成.
20.07.10 重新整理,未完成.

导语

  • 升级overture时候,才发现配置文件有更改,且支持了dot,索性扔进docker里面,方便维护.
  • (12.28) overture 更新到了 v1.6-rc6.这两天重构一下脚本,升级到最新版本,重新整理一下博文内容.
  • 非常多的内容参考了 [overture] 无污染的智能 DNS 折腾记 #4.
  • overture 早先就支持了 doh ,这里仅添加相关内容,但脚本未更新,还是想有时间彻底重构一遍.

需求

国内/国外 DNS 解析分流.

对CDN友好.

带有DNS缓存.

跨平台等

方案

overture 基本可以满足上面的需求.比较磨的是配置.

overture 配置

DNS: 支持tcp udp 和 dot

  • 主DNS(PrimaryDNS) : 主要用于国内解析
  • 备用DNS(AlternativeDNS) : 一般配置成无污染DNS,解析国外域名.

IPNetworkFile: 按ip地址过滤

  • Primary: 当主 DNS 返回的结果在此集合中时,不再等待备用 DNS 结果,直接返回.
  • Alternative: 当备用 DNS 返回的结果在此集合中时,不再等待主 DNS 结果,直接返回.

DomainFile: 按域名过滤

  • Primary: 只使用主 DNS 的域名
  • Alternative: 只使用备用 DNS 的域名,一般要配置成 gfwlist.
  • Matcher: 1.6版本以后,增加了域名文件的过滤方式,这里保持默认 regex-list 即可.

配置选取

DNS

DNS 查询方式

  • 标准 53 端口 udp 查询,最普通的 dns 查询
  • 非标准 udp 端口,与普通 dns 查询过程相同,只是端口区别.常见 opendns 的 udp-5353.
  • tcp 查询: 运行在 tcp-53 端口,报文等与普通 dns 查询过程相同.
  • DNSCrypt: 加密DNS查询,貌似走的是 UDP .支持此项的公共DNS很多,被干扰的也比较厉害.
  • DoT : DNS over Tls 做到了 DNS 加密查询,代价是 tls 握手的额外延迟.运行在 853 端口.
  • DoH: DNS over HTTPS 与 dot 类似,但是实现更容易.运行在 443 端口.

overture 支持 udp tcp DoT DoH

测试的命令在 overture 项目介绍的最后,需要对 bind 做个 patch 支持 ENDS.

汇总

  • DNS Privacy Public Resolvers 支持 dot doh 的服务商.
  • DNS over HTTPS 支持 doh 的服务商.
主DNS

主 DNS 要解决

  • 国内域名劫持
  • 解析速度
  • CDN友好

面对问题

  • 大部分是 ISP 提供的 DNS 本身不纯净
  • 移动/长城宽带这样无差别劫持 udp-53 端口,tcp 则直接 rst
  • 联通/电信分地区也有 dns 劫持.

选择,主 DNS 要能避免运营商劫持,支持 EDNS.综合一下可作为为 主DNS 的选择

  • tcp-dns,速度与 udp 查询几乎无异.无特殊太强

    • 推荐 114 AliDNS 那个延迟低用那个
    • DNSPOD 支持 tcp 查询,但是 edns 测试有些问题,可能是个例.
  • dot or doh

    • AliDNS 同时支持 dot 和 doh 还支持 edns,作为这里的首选了.
      • dot: dns.alidns.com:853 or dns.alidns.com:853@223.6.6.6
      • doh: https://dns.alidns.com/dns-query
    • 红鱼DNS 是印象中国内首先支持 dot 和 doh 的,公共 dns 服务在官网没找到,持续观望中.
      • doh: https://dns.rubyfish.cn/dns-query
备用DNS

备用 DNS 要解决

  • 域名污染
  • 如果可能,尽量对 cdn 友好.

面对问题

  • 国内 dns 都是被污染过的
  • 国外 dns 延迟较高
  • 著名防火墙的干扰

选择,这里各个地区的情况完全不同,仅汇总一些现在还能用的.

  • 非标准端口,目前就 opendns 了,支持 edns 如果可用,那速度可能是最好的.

  • tcp-dns,不要想了, tcp 明文,直接 rst.

  • DNSCrypt,早就半死不活了.

  • dot or doh

    • Cloudflare:
      • dot: one.one.one.one:853@1.0.0.1 目前可用,对隐私极其友好,所以不支持 edns.
      • doh: https://cloudflare-dns.com/dns-query 基本同 dot 可用,但是不支持 edns.
    • Google:
      • dot: dns.google:853@8.8.4.4 目前居然可用,支持 edns,解析国内域名也很准确.这里选择其作为 备用dns.
      • doh: https://dns.google/dns-query 被干扰很厉害.解析结果准确.
    • Quad9:
      • dot: dns.quad9.net:853@149.112.112.112 走 v4 可用,v6 几乎连不上,应该是不支持 edns.
      • doh: https://dns11.quad9.net/dns-query 其实有 3 个 doh 的地址,但只有这一个提供 edns 支持.v6 地址几乎连不上,更倾向于用 Quad9 的 dot.

IPNetworkFile

只需要配置 Primary 为国内 ip 列表,这样主 DNS 的解析结果是国内 ip 时,直接采用.

国内 ip 列表.推荐 IPIP 维护的 chnrouter. 已足够使用.

DomainFile

主要是区分国内外域名,如果域名是国内域名直接交给 主DNS,国外域名直接交给 备用DNS.

匹配方式这里选择 suffix-tree 即域名后缀匹配.

Primary

Primary 配置成常见国内域名.信息来自 fancyssdnsmasq-china-list

1
2
3
4
curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf  | sed 's/server=\///g;s/\/114.114.114.114//g' > china_list1.txt
curl https://raw.githubusercontent.com/hq450/fancyss/master/rules/WhiteList_new.txt | sed 's/Server=\///g;s/\///g' > china_list2.txt
cat china_list1.txt china_list2.txt | sort -u > china_list.txt
rm china_list1.txt china_list2.txt
Alternative

基本上 gfwlist 就够了,但是已经半年没有更新了.(哎😔)

这里选择了另一个 gfwlist-by-loukky 并综合下 fancyss 项目的白名单.

1
2
3
4
curl https://raw.githubusercontent.com/Loukky/gfwlist-by-loukky/master/gfwlist.txt | base64 -d | sort -u | sed '/^$\|@@/d'| sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' | sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /qq\.com/d' | sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' | grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u > gfwlist.txt
curl https://raw.githubusercontent.com/hq450/fancyss/master/rules/gfwlist.conf | sed 's/ipset=\/\.//g; s/\/gfwlist//g; /^server/d' > koolshare.txt
cat gfwlist.txt koolshare.txt | sort -u > gfw_list.txt
rm gfwlist.txt koolshare.txt

config.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
"BindAddress": ":53",
"DebugHTTPAddress": "127.0.0.1:5558",
"PrimaryDNS": [
{
"Name": "Ali",
"Address": "https://dns.alidns.com/dns-query",
"Protocol": "https",
"SOCKS5Address": "",
"Timeout": 6,
"EDNSClientSubnet": {
"Policy": "auto",
"ExternalIP": "",
"NoCookie": true
}
}
],
"AlternativeDNS": [
{
"Name": "Google",
"Address": "dns.google:853@8.8.4.4",
"Protocol": "tcp-tls",
"SOCKS5Address": "",
"Timeout": 6,
"EDNSClientSubnet": {
"Policy": "auto",
"ExternalIP": "",
"NoCookie": true
}
}
],
"OnlyPrimaryDNS": false,
"IPv6UseAlternativeDNS": false,
"AlternativeDNSConcurrent": false,
"PoolIdleTimeout": 15,
"PoolMaxCapacity": 15,
"WhenPrimaryDNSAnswerNoneUse": "AlternativeDNS",
"IPNetworkFile": {
"Primary": "./data/china_ip_list.txt",
"Alternative": "./ip_network_alternative_sample"
},
"DomainFile": {
"Primary": "./data/china_list.txt",
"Alternative": "./data/gfw_list.txt",
"Matcher": "suffix-tree"
},
"HostsFile": {
"HostsFile": "./hosts_sample",
"Finder": "full-map"
},
"MinimumTTL": 0,
"DomainTTLFile" : "./domain_ttl_sample",
"CacheSize" : 1000,
"RejectQType": [255]
}

docker镜像

  • 项目地址 overture

  • 镜像简介

    • 基于alpine:latest
    • 每天 2:00 定时更新 分流 和 ip 文件.(此处有尾巴,见后)
    • 整体大小在 6M 作用.(配合定时任务 需要 curl )
  • 容器已经上传了dockerhub 可以直接 docker pull jasperhale/overture.

docker-compose

  • 对应的 docker-compose

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    version: '2.1'

    services:
    overture:
    image: jasperhale/overture
    container_name: overture
    restart: always
    ports:
    - "127.0.0.1:53:53/tcp"
    - "127.0.0.1:53:53/udp"
    volumes:
    - ./overture/config.json:/home/overture/config.json
  • 关联 udp53 和 tcp53 .

尾巴

  • 原本想自动更新分流文件,如果分流文件有变化时,自动重启 overture .
  • 但是一个 docker 本质是就是一个进程对应一个容器.中止了 overture 相当于直接结束了容器.
  • 还有另外的解决办法是,不把 overture 当作容器对应的进程.启动一个无关的进程.这样就可以随便重启 overture.但是这样完全违反了容器的最佳实践.
  • 应该还是有别的解决办法,等待把 shell 脚本复习一遍..
  • (20.06.09) 一复习就半年了…最近会重写一遍…