mosdns - docker 配置&使用

  • mosdns 配置 & 使用 & docker-compose

  • 资料来源:

    https://github.com/IrineSistiana/mosdns
    https://kb.adguard.com/en/general/dns-providers#cloudflare-dns

  • 更新

    1
    2021.12.23 初始

导语

最近终于有时间重新升级基础设施了,先从 DNS 开始.

现有的 DNS 是 overture 已经稳定运行了超过 1 年半了,但是有几个遗憾

  • 分流的 ip/域名文件更新比较麻烦
  • overture 整个的运行逻辑还是稍微有点不满意,备份线路实现稍显麻烦.

于是找到了 mosdns,简而言之可以把 mosdns 当作是乐高,提供了 dot/doh 等等插件,怎么组合,怎么定义逻辑全看需要.

折腾的结果还算满意.

mosdns 的使用/插件说明等,仓库文档已经写的非常清楚了,再介绍就班门弄斧了.

  • Home
  • Configuration
  • Plugin

如果不需要自定义,也提供了一键上手版本: mosdns-cn

目标

目标

  • 无污染 DNS
  • 全称加密 DOT/DOH/DOQ
  • 国内外分流,按照域名 / ip
  • 多线备份
  • edns 支持(可选)
  • 延迟尽量低(可选)

上游DNS

Known DNS Providers 这似乎是 adguard 提供的已知 dns 服务集合,包括 dot doh 等等,仅供参考.

dns 污染分成两种

  • gfw 的封锁污染,这一点国内的公共 dns 都一样
  • 运营商的 dns 污染,三家都不一样.基本上 dot/doh 就能避免.

因此上游 dns 分成两种,一种是国内 dns 一种是国外 dns 提供无污染dns.

国内上游: ali DNS + dnspod (腾讯)

  • 全部 dot doh + ecs 保证加密和解析准确
  • 阿里 dns 在我的网络环境中延迟个位数,主力,dnspod 备选,本地 dns 备用.

无污染上游: Cloudflare + Google + AdGuard

  • 似乎各个地区 Cloudflare/Google dot/doh 连接情况都不一样,为了稳定 dot doh ,ipv4 ipv6 我全都要.
  • AdGuard 支持 dns over quic ,作为无污染的备用.
  • 国外的能正常返回结果就好了,ecs 对我而言意义不是很大.

分流

之前 overture 的 ip 和 域名来自好几个仓库的组合,好在 mosdns 直接兼容了 v2ray-rules-dat,这就不用再自行组合了.

v2ray-rules-dat 是适配 V2Ray 的规则文件增强版.包含 geoip.dat 和 geosite.dat 两个文件,实在是省了我们很多功夫.

geoip.dat

  • 包含了大量的 ip 类别,最重要的是 cnip 数据替换成了 ipip.net 这个数据源比 MaxMind GeoLite2 的 cnip 更准确,之前 overture-docker 也是用的这个.

geosite.dat

  • 各种的域名分类,这里只关心两种 cncategory-ads-all,cn 是国内域名,ad 是广告域名.
  • 还有更多分类暂时用不上.

流程

overture 的处理流程已经是比较合理了,不过还有小点需要修改,这里就以 overture 流程为模板规划了

  • 缓存,缓存未命中则进入下一步.
  • ad 域名? -> 空应答
  • cn 域名? -> 国内上游
    • 返回是国内 ip ? -> 返回结果,结束.
    • 不是国内 ip 继续下一步.
  • 非 cn 域名? -> 无污染上游
    • 返回非国内 ip ? -> 返回结果,结束.
    • 返回国内 ip 继续下一步.
  • 其他所有情况,优先无污染上游结果,否则国内上游结果.

结合 mosdns 其他配置

  • 无论国内/无污染上游,一律 dot doh v4 v6 并发,这会带来带宽的浪费,仅个人使用还好,作为 dns 服务器最好不要这样.
  • 国内上游带上 ecs
  • 双栈优先 ipv4
  • 填充 & 调整 ttl

配置

官方给了两个 配置模板,这里为文件是在复杂配置基础上调整.

配置在各个方面肯定并非完美,有错误请留言/邮件.

官方也提供了 docker 镜像,这里使用 docker-compose 方便部署.

docker-compose

1
2
3
4
5
6
7
8
9
version: '3'

services:
mosdns:
image: irinesistiana/mosdns:latest
volumes:
- ./mosdns:/etc/mosdns
restart: always
network_mode: host

config.yaml

要运行起来,需要到 v2ray-rules-dat 下载 geoip.dat 和 geosite.dat.

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
log:
level: debug
file: ""

plugin:
################# 服务插件 ################

# 启动服务器的插件
- tag: main_server
type: server
args:
entry:
- mem_cache # 缓存
- main_sequence # 运行主执行序列
- modify_ttl # 修改 ttl
server:
- protocol: udp
addr: "127.0.0.1:53"
- protocol: tcp
addr: "127.0.0.1:53"
- protocol: udp
addr: "[::1]:53"
- protocol: tcp
addr: "[::1]:53"
################# 可执行插件 ################

# 缓存
- tag: "mem_cache"
type: "cache"
args:
size: 1024 # 条目数量
lazy_cache_ttl: 86400 # lazy cache 生存时间
lazy_cache_reply_ttl: 30 # 返回过期应答的 TTL

- tag: "ecs-cn"
type: "ecs"
args:
auto: false #仅适用于公网的服务器。本地运行不要启用这个功能。
ipv4: "202.120.2.101" # 预设 IPv4
ipv6: "2001:da8:8000:1:202:120:2:101" # 预设 IPv6
force_overwrite: true # 强制覆盖
mask4: 24 # 用于 ipv4 地址的掩码 默认: 24。
mask6: 48 # 用于 ipv6 地址的掩码 默认: 48。

# 修改应答 ttl
- tag: "modify_ttl"
type: "ttl"
args:
minimal_ttl: 300
maximum_ttl: 3600

################ 序列 #################

# main_sequence
- tag: main_sequence
type: sequence
args:
exec:
- if:
- query_ad # ad
exec:
- _block_with_nxdomain # 空应答
- _end

- if:
- query_cn # cn域名
- "!_query_is_common" # 不常见的请求
exec:
- ecs-cn
- _pad_query
- local # 用本地服务器
- if:
- "response_cnip" # 结果是 cnip
exec:
- _end # 结束

- if:
- query_notcn # 已知的 非cn域名
exec:
- _prefer_ipv4 # 优先 IPv4
- _pad_query
- remote # 无污染
- if:
- "!response_cnip" # 结果是 非cnip
exec:
- _end # 结束

- primary: #其他所有情况
- _prefer_ipv4
- _pad_query
- remote
secondary:
- _prefer_ipv4
- _pad_query
- local
fast_fallback: 400 # 这里建议设置成 local 服务器正常延时的 2~5 倍 单位: 毫秒
always_standby: true

# local 序列
- tag: local
type: sequence
args:
exec:
- primary:
- parallel: # 并行
- - "ali" # 执行序列 #1。
- - "dnspod" # 执行序列 #2。
secondary:
- localdns # 备用本地
fast_fallback: 600 # 这里建议设置成 primary 服务器正常延时的 2~5 倍 单位: 毫秒。
always_standby: true

# remote 序列
- tag: remote
type: sequence
args:
exec:
- primary:
- parallel: # 并行
- - "google" # 执行序列 #1。
- - "cloudflare" # 执行序列 #2。
secondary:
- adguard # 备用 adguard
fast_fallback: 600 # 这里建议设置成 primary 服务器正常延时的 2~5 倍 单位: 毫秒。
always_standby: true

################ DNS #################
# 阿里 dns
- tag: ali
type: forward
args:
upstream:
- addr: "https://dns.alidns.com/dns-query" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2400:3200:baba::1"
- "223.5.5.5"
- "2400:3200::1"
- "223.6.6.6"
trusted: true # 是否是可信服务器
- addr: "tls://dns.alidns.com" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2400:3200:baba::1"
- "223.5.5.5"
- "2400:3200::1"
- "223.6.6.6"
trusted: true # 是否是可信服务器

bootstrap:
- "tls://1.1.1.1"
- "https://223.5.5.5/dns-query"
fastest_ip: false # 优选最快 ip 对返回 ip 测速,可能会非常慢
timeout: 5 # 请求超时时间秒

# dnspod
- tag: dnspod
type: forward
args:
upstream:
- addr: "https://doh.pub/dns-query" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2402:4e00::"
- "119.29.29.29"
trusted: true # 是否是可信服务器
- addr: "tls://dot.pub" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2402:4e00::"
- "119.29.29.29"
trusted: true # 是否是可信服务器

bootstrap:
- "tls://1.1.1.1"
- "https://223.5.5.5/dns-query"
fastest_ip: false # 优选最快 ip 对返回 ip 测速,可能会非常慢
timeout: 5 # 请求超时时间秒

# 本地 dns 备用
- tag: localdns
type: forward
args:
upstream:
- addr: "192.168.0.1:53"

# google dns
- tag: google
type: forward
args:
upstream:
- addr: "https://dns.google/dns-query" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2001:4860:4860::8844"
- "8.8.4.4"
- "2001:4860:4860::8888"
- "8.8.8.8"
trusted: true # 是否是可信服务器
- addr: "tls://dns.google" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2001:4860:4860::8844"
- "8.8.4.4"
- "2001:4860:4860::8888"
- "8.8.8.8"
trusted: true # 是否是可信服务器
bootstrap:
- "tls://1.1.1.1"
- "https://223.5.5.5/dns-query"
fastest_ip: false # 优选最快 ip 对返回 ip 测速,可能会非常慢
timeout: 5 # 请求超时时间秒

# cloudflare
- tag: cloudflare
type: forward
args:
upstream:
- addr: "https://cloudflare-dns.com/dns-query" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2606:4700:4700::1001"
- "1.0.0.1"
- "2606:4700:4700::1111"
- "1.1.1.1"
trusted: true # 是否是可信服务器
- addr: "tls://cloudflare-dns.com" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2606:4700:4700::1001"
- "1.0.0.1"
- "2606:4700:4700::1111"
- "1.1.1.1"
trusted: true # 是否是可信服务器

bootstrap:
- "tls://1.1.1.1"
- "https://223.5.5.5/dns-query"
fastest_ip: false # 优选最快 ip 对返回 ip 测速,可能会非常慢
timeout: 5 # 请求超时时间秒

# doq 备用
- tag: adguard
type: forward
args:
upstream:
- addr: "quic://dns-unfiltered.adguard" # 服务器地址
ip_addr: # 手动指定服务器的 IP 地址 可以配置多个
- "2a10:50c0::1:ff"
- "94.140.14.140"
- "2a10:50c0::2:ff"
- "94.140.14.141"
trusted: true # 是否是可信服务器

################ 匹配器 #################

# 查询 - cn 域名
- tag: query_cn
type: query_matcher
args:
domain:
- "ext:./geosite.dat:cn"

# 查询 - gfw
- tag: query_gfw
type: query_matcher
args:
domain:
- "ext:./geosite.dat:gfw"

# 查询 - 非 cn 域名
- tag: query_notcn
type: query_matcher
args:
domain:
- "ext:./geosite.dat:geolocation-!cn"

# 查询 - ad
- tag: query_ad
type: query_matcher
args:
domain:
- "ext:./geosite.dat:category-ads-all"

# 返回 - cn IP
- tag: response_cnip
type: response_matcher
args:
ip:
- "ext:./geoip.dat:cn"

尾巴

mosdns 算是跑起来能用了,看仓库的 issue 似乎是 ecs 的结果无法进入缓存..好在国内上游延迟基本上都是个位数,没有缓存也没关系.

之后就轮到 openwrt 了,需要彻底重构现在的局域网了.