导语
最近终于有时间重新升级基础设施了,先从 DNS 开始.
2022.03.17 mos腹泻式更新,版本号从 v2.1.2 飙到了 v3.5.2,谢谢开发者,大家有 github 账号记得给开发者点个 start 😂
2022.07.27 mosdns 版本号还在飙升…4.x 配置与之前不兼容,因此花点时间重写了部分内容.
2022.10.09 目前最新版本号 v4.4.2,这次本文主要增加了域名文件定期重新加载.
前言
现有的 DNS 是 overture 已经稳定运行了超过 1 年半了,但是有几个遗憾
- 分流的 ip/域名文件更新比较麻烦
- overture 整个的运行逻辑还是稍微有点不满意,备份线路实现稍显麻烦.
于是找到了 mosdns,简而言之可以把 mosdns 当作是乐高,提供了 dot/doh 等等插件,怎么组合,怎么定义逻辑全看需要.
折腾的结果还算满意.
mosdns 的使用/插件说明等,仓库文档已经写的非常清楚了,再介绍就班门弄斧了.
如果不需要自定义,也提供了一键上手版本: 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 我全都要.千万不要在搭建公共 DNS 服务器时这样弄
- 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
- 各种的域名分类,这里只关心两种
cn
和 category-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 方便部署.
(2022.03.17)增加一个自编译 dockerfile 文件,添加 geoip.dat
与 geosite.dat
,方便更新.
(2022.07.27) dockerfile 适配 4.x 版本
(2202.10.09) 域名文件重加载,每天 2 点.
dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| FROM irinesistiana/mosdns:latest LABEL maintainer="None"
COPY ./config.yaml /etc/mosdns/config.yaml COPY ./entrypoint.sh /entrypoint.sh RUN chmod a+x /entrypoint.sh
RUN set -xe \ && apk add --no-cache curl \ && cd / \ && curl -LJO https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat \ && curl -LJO https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat \ && echo '0 2 * * * wget -O /geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat'>>/var/spool/cron/crontabs/root \ && echo '0 2 * * * wget -O /geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat'>>/var/spool/cron/crontabs/root \ && apk del curl
VOLUME /etc/mosdns EXPOSE 53/udp 53/tcp
ENTRYPOINT [ "/entrypoint.sh" ]
|
entrypoint.sh
1 2 3 4
| #!/bin/sh
/usr/sbin/crond -b -l 8 /usr/bin/mosdns start --dir /etc/mosdns
|
docker-compose
dockerfile 和 entrypoint.sh 放在 mosdns
文件夹下
1 2 3 4 5 6 7 8 9 10 11
| version: '3'
services: mosdns: build: context: ./mosdns image: mosdns:latest volumes: - ./mosdns:/etc/mosdns restart: always network_mode: host
|
config.yaml
如果使用官方 docker image 运行需要用到 v2ray-rules-dat 下载 geoip.dat 和 geosite.dat,挂载到根目录.
2022.03.17 更新
- 删除一些已经失效配置
- 因为国内的 dns 查询使用了 edns,因此 cache 启用了
cache_everything
,如果不是有大量 edns 查询,简易关闭. 通过脚本获取公网ip 4.x 已不支持运行 shell 命令.使用 curl -s https://v4.myip.la
和 curl -s https://v6.myip.la
- 如果你有国内的分流,只能手动指定.
mosdns 现在有 dot/doh 的 http3
支持,但是在我本地的环境测试效果不佳,因此暂不加入相关配置.还有类似的 UDPME
支持,个人处于观望态度.
(2022.07.27) 适配 4.x 版本配置
- 启用 doh 的 http3,测试效果不错,请因地制宜修改.
- 替换一些
forward
-> fast_forward
- 修正一些地址错误.
- ecs ip 目前只能手动配置
- 启动前通过脚本替换配置文件
- 等待 远程动态数据更新 完成
(2022.10.09) 规则文件的重加载
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 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
| log: level: warn file: ""
data_providers: - tag: geoip file: /geoip.dat auto_reload: true - tag: geosite file: /geosite.dat auto_reload: true
plugins: - tag: "mem_cache" type: "cache" args: size: 1024 lazy_cache_ttl: 86400 lazy_cache_reply_ttl: 30 cache_everything: true
- tag: "ecs-cn" type: "ecs" args: auto: false ipv4: "202.120.35.132" ipv6: "2001:da8:8000:1:202:120:2:101" force_overwrite: true mask4: 24 mask6: 48
- tag: "modify_ttl" type: "ttl" args: minimal_ttl: 300 maximum_ttl: 3600
- tag: ali type: forward args: upstream: - addr: "https://dns.alidns.com/dns-query" ip_addr: - "2400:3200:baba::1" - "223.5.5.5" - "2400:3200::1" - "223.6.6.6" trusted: true - addr: "tls://dns.alidns.com" ip_addr: - "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" timeout: 5
- tag: dnspod type: forward args: upstream: - addr: "https://doh.pub/dns-query" ip_addr: - "2402:4e00::" - "119.29.29.29" trusted: true - addr: "tls://dot.pub" ip_addr: - "2402:4e00::" - "119.29.29.29" trusted: true
bootstrap: - "tls://1.1.1.1" - "https://223.5.5.5/dns-query" timeout: 5
- tag: localdns type: forward args: upstream: - addr: "192.168.0.1:53"
- tag: google type: forward args: upstream: - addr: "https://dns.google/dns-query" ip_addr: - "2001:4860:4860::8844" - "8.8.4.4" - "2001:4860:4860::8888" - "8.8.8.8" trusted: true
- tag: cloudflare type: forward args: upstream: - addr: "https://cloudflare-dns.com/dns-query" ip_addr: - "2606:4700:4700::1001" - "1.0.0.1" - "2606:4700:4700::1111" - "1.1.1.1" trusted: true
- tag: google_dot type: fast_forward args: upstream: - addr: "tls://dns.google" dial_addr: "8.8.4.4" trusted: true enable_pipeline: true - addr: "tls://dns.google" dial_addr: "2001:4860:4860::8888" trusted: true enable_pipeline: true - addr: "tls://dns.google" dial_addr: "8.8.8.8" trusted: true enable_pipeline: true
- tag: cloudflare_dot type: fast_forward args: upstream: - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" dial_addr: "2606:4700:4700::1001" trusted: true enable_pipeline: true - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" dial_addr: "1.0.0.1" trusted: true enable_pipeline: true - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" dial_addr: "2606:4700:4700::1111" trusted: true enable_pipeline: true - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" dial_addr: "1.0.0.1" trusted: true enable_pipeline: true
- tag: google_h3 type: "fast_forward" args: upstream: - addr: "https://dns.google/dns-query" dial_addr: "2001:4860:4860::8844" trusted: true enable_http3: true - addr: "https://dns.google/dns-query" dial_addr: "8.8.4.4" trusted: true enable_http3: true - addr: "https://dns.google/dns-query" dial_addr: "2001:4860:4860::8888" trusted: true enable_http3: true - addr: "https://dns.google/dns-query" dial_addr: "8.8.8.8" trusted: true enable_http3: true
- tag: cloudflare_h3 type: "fast_forward" args: upstream: - addr: "https://cloudflare-dns.com/dns-query" dial_addr: "2606:4700:4700::1001" trusted: true enable_http3: true - addr: "https://cloudflare-dns.com/dns-query" dial_addr: "1.0.0.1" trusted: true enable_http3: true - addr: "https://cloudflare-dns.com/dns-query" dial_addr: "2606:4700:4700::1111" trusted: true enable_http3: true - addr: "https://cloudflare-dns.com/dns-query" dial_addr: "1.1.1.1" trusted: true enable_http3: true
- tag: adguard type: forward args: upstream: - addr: "quic://dns-unfiltered.adguard.com" ip_addr: - "2a10:50c0::1:ff" - "94.140.14.140" - "2a10:50c0::2:ff" - "94.140.14.141" trusted: true
- tag: query_cn type: query_matcher args: domain: - "provider:geosite:cn"
- tag: query_gfw type: query_matcher args: domain: - "provider:geosite:gfw"
- tag: query_notcn type: query_matcher args: domain: - "provider:geosite:geolocation-!cn"
- tag: query_ad type: query_matcher args: domain: - "provider:geosite:category-ads-all"
- tag: response_cnip type: response_matcher args: ip: - "provider:geoip:cn"
- tag: local type: sequence args: exec: - parallel: - - "ali" - - "dnspod"
- tag: remote type: sequence args: exec: - parallel: - - google - - cloudflare - - google_dot - - cloudflare_dot - - adguard - - google_h3 - - cloudflare_h3
- tag: main_sequence type: sequence args: exec: - if: query_ad exec: - _new_nxdomain_response - _return
- if: "query_cn" exec: - ecs-cn - _pad_query - local - if: "response_cnip" exec: - _return
- if: query_notcn exec: - _prefer_ipv4 - _pad_query - remote - if: "!response_cnip" exec: - _return
- primary: - _prefer_ipv4 - _pad_query - remote secondary: - _prefer_ipv4 - _pad_query - local fast_fallback: 400 always_standby: true
- tag: sequence type: sequence args: exec: - mem_cache - main_sequence - modify_ttl
servers: - exec: sequence listeners: - protocol: udp addr: ":53" - protocol: tcp addr: ":53"
|
测试
q 是目前找到的支持 UDP TCP DoT DoH DoQ 且支持 EDNS 的 DNS 客户端
- kdig dog doggo 似乎都有个别协议不支持
1
| q --subnet=202.120.35.133 +stats A www.bilibili.com @tls://dot.pub
|
尾巴
mosdns 算是跑起来能用了,看仓库的 issue 似乎是 ecs 的结果无法进入缓存..好在国内上游延迟基本上都是个位数,没有缓存也没关系.
之后就轮到 openwrt 了,需要彻底重构现在的局域网了.