mosdns - docker 配置&使用

  • mosdns 配置 & 使用 & docker-compose

  • 资料来源:

    https://github.com/IrineSistiana/mosdns
    https://kb.adguard.com/en/general/dns-providers#cloudflare-dns
    https://icyleaf.com/2023/08/using-vector-transform-mosdns-logging-to-grafana-via-loki/#prometheus
    https://github.com/sbwml/luci-app-mosdns/tree/v5

  • 更新

    1
    2
    3
    4
    5
    6
    7
    2021.12.23 初始
    2022.03.17 同步更新配置,增加 dockerfile
    2022.07.27 同步 4.x 配置
    2022.10.09 更新一些配置
    2022.10.21 更新测试命令
    2023.09.14 更新一些 v4 配置,v5 尚在观望.
    2024.05.03 更新到 v5.3.1, 增加看板 (来自 @icyleaf), 修正一些错误.

导语

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

2022.03.17 mos 腹泻式更新,版本号从 v2.1.2 飙到了 v3.5.2,谢谢开发者,大家有 github 账号记得给开发者点个 start 😂

  • 同步更新配置
  • 增加自编译的 dockerfile

2022.07.27 mosdns 版本号还在飙升…4.x 配置与之前不兼容,因此花点时间重写了部分内容.

2022.10.09 目前最新版本号 v4.4.2,这次本文主要增加了域名文件定期重新加载.

2023.09.14 目前 v5 版本,已经稳定 但 功能上与 v4 相比还是有些欠缺.尤其是 缓存 ecs 结果…

  • 尝试了配置相同功能的 v5 与 v4 尚没有很多差别,暂时停留在 v4 ,直到 v5 有更好的功能.

2023.09.14 今天是更新 v4 自己常用的配置,已经 稳定运行 7 个月了.

2024.05.03 v5 版本其实前后搞了好几版, 但是其逻辑与 v4 差的太多了.. 最近才调试通过..

  • 看板来自 @icyleaf, 目前仅测试了几个小时没啥问题, 可能有隐患.

前言

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

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

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

折腾的结果还算满意.

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

  • Home
  • mosdns wiki

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

  • (24.5.2) 这个也很久没更新了

目标

目标

  • 无污染 DNS
  • 全程加密 DOT/DOH/DOQ
  • 不经过代理
    • 请注意本文的配置是不经过代理转发, mosdns 提供了代理转发功能.
  • 国内外分流,按照域名 / 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 doq + ecs 保证加密和解析准确
  • 阿里 dns 在我的网络环境中延迟个位数,主力,dnspod 备选,本地 dns 备用.

无污染上游: Cloudflare + Google 的 dot doh doq

  • 各个地区 Cloudflare/Google dot/doh 连接情况都不一样, 默认配置下是不过代理, 为了稳定 dot doh doq ,ipv4 ipv6 全部都配置了.
    • 千万不要在搭建公共 DNS 服务器时这样弄
  • AdGuard 支持 dns over quic ,作为无污染的备用.
  • 国外的能正常返回结果就好了,ecs 对我而言意义不是很大. 主要是常用网站 cdn 覆盖很好,不加 ecs 正好….
    • 需要国外结果精确的,可以手动调整配置加入 ecs.

分流

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 是广告域名.
  • 还有更多分类暂时用不上.

(2024.05.03) mosdns V4 兼容 v2ray-rules-dat 格式, 但是 v5 版本需要自行解包;

流程

overture 的处理流程已经是比较合理了,不过还有小点需要修改,这里就以 overture 流程为模板, 附加 GitHub issue 和 discuss 给出的配置:

  • 预处理
    • qtype65 与无效查询? – 丢弃;
    • qtype12 or qtype255 ? – _no_ecs 走国内上游 ttl_1h, return;
    • 其他则 替换 edns , 进入缓存,缓存未命中则进入下一步.
  • 主流程
    • ad 域名? -> 空应答
    • cn 域名? -> 附加 ecs ->国内上游
      • 返回是国内 ip ? -> 返回结果,结束.
      • 不是国内 ip 继续下一步.
    • 非 cn 域名? -> 无污染上游
      • 返回非国内 ip ? -> 返回结果,结束.
      • 返回国内 ip 继续下一步.
    • 其他所有情况,优先无污染上游结果.

结合 mosdns 其他配置

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

MOSDNS 配置

(24.5.2) 以下分别在 MOSDNS 的 v4 和 v5 两个版本,实现相同流程, 配置在各个方面肯定并非完美,有错误请留言/邮件.

V4 版本依旧能满足日常使用, 升级 v5 的动力不是很大.

  • 官方给了两个 配置模板,这里为文件是在复杂配置基础上调整.
  • 官方也提供了 docker 镜像,这里使用 docker-compose 方便部署.

V4 LOG

  • (2022.03.17) 增加一个自编译 dockerfile 文件,添加 geoip.datgeosite.dat,方便更新.
  • (2022.07.27) dockerfile 适配 4.x 版本
  • (2022.10.09) 域名文件重加载,每天 2 点. GitHub 被干扰越来越厉害,定期更新没有意义了.
  • (2023.09.14) 删减无效配置.
  • (24.5.2) 修正无效配置,感谢 @dansean 评论反馈.

V5 目前 (24.5.2) 停留在 5.3.1 版本, 已经很稳定了.

V5 LOG

  • (24.5.2) @icyleaf 的 vector + loki 实现 mosdns 数据看板 偷了不少配置 的看板 整理成了 docker-compose 部署.
    • 另外因为 v5 解包不方便, 提供了新的 docker 和 dockerfile 文件.

V4

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FROM irinesistiana/mosdns:v4.5.3
LABEL maintainer="JH"

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 \
&& apk del curl

VOLUME /etc/mosdns
EXPOSE 53/udp 53/tcp
# CMD /usr/bin/mosdns start --dir /etc/mosdns

ENTRYPOINT [ "/entrypoint.sh" ]

entrypoint.sh

1
2
3
4
#!/bin/sh
# crond
/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

配置文件见 mosdns v4 配置

如果使用官方 docker image 运行需要用到 v2ray-rules-dat 下载 geoip.dat 和 geosite.dat,挂载到根目录.

V5

完整配置见 mosdns_v5

Dockerfile

在官方 docker 基础上增加了 v2ray-rules-dat 的解包, 在 /dat 目录下

  • 解包工具是 urlesistiana/v2dat
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
FROM golang:1.19.2-alpine as unpack
WORKDIR /

RUN set -xe \
&& apk add --no-cache curl \
&& go install github.com/urlesistiana/v2dat@latest \
&& 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 \
&& mkdir dat \
&& v2dat unpack geoip -o dat -f "private" geoip.dat \
&& v2dat unpack geoip -o dat -f "cn" geoip.dat \
&& v2dat unpack geosite -o dat -f "cn" geosite.dat \
&& v2dat unpack geosite -o dat -f "gfw" geosite.dat \
&& v2dat unpack geosite -o dat -f "category-ads-all" geosite.dat \
&& v2dat unpack geosite -o dat -f "geolocation-!cn" geosite.dat


FROM irinesistiana/mosdns:latest
LABEL maintainer="None"

COPY ./config.yaml /etc/mosdns/config.yaml
COPY ./dat_exec.yaml /etc/mosdns/dat_exec.yaml
COPY ./dns.yaml /etc/mosdns/dns.yaml
COPY ./entrypoint.sh /entrypoint.sh
COPY --from=unpack /dat /dat
RUN chmod a+x /entrypoint.sh

VOLUME /etc/mosdns
EXPOSE 53/udp 53/tcp
# CMD /usr/bin/mosdns start --dir /etc/mosdns

ENTRYPOINT [ "/entrypoint.sh" ]

Entrypoint

1
2
3
4
5
6
#!/bin/sh

# crond
/usr/sbin/crond -b -l 8

/usr/bin/mosdns start --dir /etc/mosdns

Config

详情见 mosdns v5 配置

这里写一点调试 v5 配置的总结,不完整,别当经验看.

  • 流程经过 cache 后必须执行到 accept; 否则 cache 不生效
1
2
- matches: has_resp
exec: accept
  • 现在 v5 的 level: debug 信息非常之少, 没有命中的路径信息, 这些信息输出需要手动调用 query_summary 才能看到.

Dashboard

vector + loki 实现 mosdns 数据看板 整合为了 docker-compose, 基本实现了相同效果, 有 bug 请留言.

详情见 mosdns_docker/dashboard

备注: 上文提到,默认配置不过代理,为了稳定配置了尽量多的 dns 服务器, 因为 gfw 干扰, dashboard 会有大量 upstream error exchange failed 是正常现象.

测试

q 是目前找到的支持 UDP TCP DoT DoH DoQ 且支持 EDNS 的 DNS 客户端

  • kdig dog doggo 似乎都有个别协议不支持
1
q --subnet="202.120.35.133/24" +stats A www.bilibili.com  @tls://dot.pub

尾巴

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

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

(23.09.14) 有一天或许无污染 DNS 也会终结吧, 是时候进入更深的层次了.

(24.05.03) 墙是没有上限的.