由于运营商默认提供的DNS有很多的污染,许多域名直接0.0.0.0或者127.0.0.1伺候,导致上网体验并不是很好,故想到自建加密DNS来抵御污染。
一开始使用的是AdGuardHome,然而在我看到了CloudflareSpeedTest这个项目后,就萌生了ip重定向这个需求,为此我又套了一层mosdns(经典为醋包饺子)。既然上了mosdns,就干脆做配上分流吧,于是现在的这套方案就形成了。虽然我的这些需求一个mosdns就可以解决,但AdGuardHome的前端ui、更方便的广告过滤、数据统计这些功能是mosdns所没有的。
#
23.2.8新方案
由于CloudFlare的优选IP在不同设备上速度都不同,所以在设备本地搭建更优。于是,我现在将mosdns从服务器上移到了本地。当然,在路由器上部署要更好,但我家的路由器性能太弱了,就算了。同时,去广告就交给mosdns,这样就无需使用两个软件进行套娃了。
mosdns在这段时间也更新了V5版本,原先的配置文件也无法使用了,正好做出V5可用的配置。
在该配置文件中,需要用上以下项目提供的域名/IP文件:
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# Powered by luoboQAQ
log:
level: info
plugins:
# 缓存插件
- tag: cache
type: cache
args:
size: 10240
lazy_cache_ttl: 86400
# 将缓存保存在磁盘
dump_file: ./cache.dump
# 转发至本地服务器的插件
- tag: forward_local
type: forward
args:
upstreams:
- tag: alidns_doh
addr: "https://223.5.5.5/dns-query"
- tag: dnspod_doh
addr: "https://120.53.53.53/dns-query"
# 转发至远程服务器的插件
- tag: forward_remote
type: forward
args:
upstreams:
- tag: easymosdns
addr: "https://doh.apad.pro/dns-query"
bootstrap: "223.5.5.5"
- tag: dns_sb
addr: "https://45.11.45.11/dns-query"
# fallback 用本地服务器 sequence
# 返回不包含本地 ip 则 reject
- tag: local_ip_sequence
type: sequence
args:
- exec: $forward_local
- matches: resp_ip &./data/CN-ip-cidr.txt
exec: accept
- exec: drop_resp # v5.1.2 以后不能用 reject
# fallback 用远程服务器 sequence
- tag: remote_sequence
type: sequence
args:
- exec: $forward_remote
# CloudFlare劫持到优选IP
- matches:
- resp_ip &./data/cloudflare.txt
exec: black_hole 172.67.210.33
- exec: accept
# fallback插件
- tag: fallback
type: fallback
args:
primary: local_ip_sequence
secondary: remote_sequence
threshold: 500
always_standby: true
# 主要运行逻辑插件
- tag: main
type: sequence
args:
- matches: qtype 65
exec: reject 3
# 去广告
- matches: qname &./data/reject-list.txt
exec: reject 3
- matches: qname &./data/ad-domains.txt
exec: reject 3
- exec: prefer_ipv4
- exec: $cache
- matches: has_resp
exec: accept
- matches: qname &./data/direct-list.txt
exec: $forward_local
- matches: has_resp
exec: accept
- exec: $fallback
# 启动 udp服务器
- type: udp_server
args:
entry: main
listen: 127.0.0.1:53
|
此配置文件参考了该回答
#
方案设计
首先由AdGuardHome接受请求,判断是否为广告域名:
判断是否为国内域名:
判断是否为CloudFlare的IP:
#
系统搭建
#
搭建mosdns
如何安装和配置mosdns,官方文档已经写的非常详细了,直接看文档就好了。
配置文件主要参考了pmkol/easymosdns
这里主要分享一下我的配置:
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# Powered by luoboQAQ
log:
file: "./mosdns.log"
level: error
# 数据源设置
data_providers:
- tag: CloudFlareIP
file: "./rules/cloudflare.txt"
auto_reload: true
- tag: chinalist
file: "./rules/geosite_cn.txt"
auto_reload: true
plugins:
# 缓存的插件
- tag: cache
type: cache
args:
size: 10240
lazy_cache_ttl: 86400
cache_everything: true
# 匹配PTR类型请求的插件
- tag: query_is_ptr
type: query_matcher
args:
qtype: [12]
# 匹配TYPE65类型请求的插件
- tag: qtype65
type: query_matcher
args:
qtype: [65]
# 屏蔽请求的插件
- tag: black_hole
type: blackhole
args:
rcode: 0
ipv4: "127.0.0.1"
ipv6: "::1"
# 匹配本地域名的插件
- tag: query_is_cn_domain
type: query_matcher
args:
domain:
- "provider:chinalist"
# 转发至本地服务器的插件
# [local|alidns]
- tag: forward_local
type: fast_forward
args:
upstream:
- addr: "udp://100.100.2.138"
- tag: forward_alidns
type: fast_forward
args:
upstream:
- addr: "https://dns.alidns.com:443/dns-query"
dial_addr: "223.5.5.5"
# CloudFlare劫持的插件
- tag: response_is_cloudflare_ip
type: response_matcher
args:
ip:
- "provider:CloudFlareIP"
- tag: hijack_cloudflare_ip
type: blackhole
args:
ipv4: 104.16.111.240
# 转发至远端服务器的插件
- tag: forward_easymosdns
type: fast_forward
args:
upstream:
- addr: "https://doh.apad.pro/dns-query"
bootstrap: "223.5.5.5"
# 主要的运行逻辑插件
- tag: main_sequence
type: sequence
args:
exec:
# 缓存
- cache
# 屏蔽TYPE65类型请求
- if: qtype65
exec:
- black_hole
- _return
# 分流
- if: "(query_is_cn_domain) || (query_is_ptr)"
exec:
- forward_alidns
else_exec:
- forward_easymosdns
# CloudFlare劫持到优选IP
- if: response_is_cloudflare_ip
exec:
- hijack_cloudflare_ip
- _return
servers:
- exec: main_sequence
timeout: 5
listeners:
- addr: 127.0.0.1:5533
protocol: udp
|
其中,cloudflare.txt
来自于上面的CloudflareSpeedTest项目,是包含ipv4和ipv6的CloudflareIP段。
geosite_cn.txt
是国内域名的集合,来自Loyalsoldier/v2ray-rules-dat,将geosite.dat
使用mosdns v2dat unpack-domain
解包得到。
这里我没有启用mosdns的缓存,因为我在AdGuardHome里启用,就不重复缓存了。如果你是直接使用mosdns,那么就可以启用缓存。
事实上,还是要开启mosdns的缓存,以此来减小DNS查询的延时。
#
搭建AdGuardHome
这里我为了方便,就直接使用了docker,其实可以不用的说
1
2
3
4
5
6
|
docker run --name adguardhome\
--restart unless-stopped\
-v /root/adguardhome/work:/opt/adguardhome/work\
-v /root/adguardhome/conf:/opt/adguardhome/conf\
--net=host\
-d adguard/adguardhome
|
我比较懒,就直接让容器使用了host
模式,这样就不用配置端口了。
设置方面
-
上游DNS服务器填入127.0.0.1:5533
,即mosdns的端口。
-
启用启用 EDNS 客户端子网
,使DNS查询附上用户的ip,使解析的ip地址靠近本地位置。
-
开启乐观缓存
,设置覆盖最小TTL值
为600,覆盖最大TTL值
为3600,避免每次都要查询
-
开启启用加密(HTTPS、DNS-over-HTTPS、DNS-over-TLS)
,启用DoH
-
根据自己的喜好添加过滤规则
我推荐启用CHN: anti-AD
,这个列表还是很不错的
#
Nginx反代配置
这里为了避免DoH被滥用,我修改了默认的路径,同时将默认路径返回444(中断连接)。
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
|
server {
listen 80;
listen 443 ssl http2;
server_name you.domain;
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
ssl_certificate ./cert/xxx.pem;
ssl_certificate_key ./cert/xxxx.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
#表示使用的加密套件的类型。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
ssl_prefer_server_ciphers on;
location /set/ {
proxy_pass http://127.0.0.1:11451/;
proxy_redirect / /set/;
proxy_cookie_path / /set/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /query {
proxy_http_version 1.1;
proxy_pass https://127.0.0.1:11450/dns-query;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
return 444;
}
}
|
#
客户端配置
#
Windows
在win11 22H2中,在 设置——网络和Internet中 就可以设置加密DNS,输入服务器ip地址后选择手动模板就可以输入DoH地址了。
如果还没有升级到这个版本,可以用管理员模式运行powershell执行下面的命令
1
|
Add-DnsClientDohServerAddress -ServerAddress '123.xx.xx.xx' -DohTemplate 'https://your.domain/dns-query' -AllowFallbackToUdp $False -AutoUpgrade $True
|
随后直接将你服务器的ip设置成DNS服务器就可以了,系统会自动使用DoH进行请求。
#
Android
安卓系统从9开始支持DoT,只要在连接与共享——私人DNS填入服务器的域名即可。
根据谷歌的公告,从13开始,安卓开始支持DoH。在此之前,想要使用DoH就只能依靠第三方软件了。
#
后记
单独使用AdGuardHome的情况下,开启缓存平均处理时间是5ms;AdGuardHome+mosdns目前是11ms。
折腾了两层解析,只是为了实现CloudFlare的IP优选,速度果然不出所料的慢了一点(当然也可能是缓存还没完全)。就当是学习了,正常使用留其一即可。_(:з)∠)_
通过这次折腾,对DNS的认识更加深了一步,也水了一篇博客。