mosdns 国内外 DNS 查询分流

Posted by 风舞山湖博客 on Wednesday, March 17, 2021

前几天无聊之时登录到 R1S 软路由上看看系统状态,意外发现用于 DNS 分流无服务的 mos-chinadns 居然占用了 35% 的 RAM,R1S 总共 512MB RAM,这么高的占用率有点不太正常。这个软件自当初配置完毕后也没有进行升级,趁这个机会就更新下吧。但打开软件发布的 github 站点后,得到了坏消息是作者已经停止更新,好消息提供替代方案 mosdns。原本想同一个作者,类似的功能,应该可以很快甚至无缝迁移过去。看了 mosdns 的介绍后,我还是太简单了。

虽然同是 DNS 分流/转发器,mosdns 完全做了重构,用插件实现各种功能,插件本身的配置也非常灵活,还支持自定义的插件。软件也借用了 v2ray-core 的代码。花了一些时间研究和测试,在 R1S 上实现国内外 DNS 分流。别问我为什么要做分流。

下载 Arm64 版本 mosdns,这里需要感谢作者提供各种 CPU 的二进制文件。运行 mosdns -s install 命令,生成开机启动脚本,适用于 Windows XP+, Linux/(systemd | Upstart | SysV), 和 OSX/Launchd 系统。OpenWrt 上是 SysV,运行成功后可以发现 /etc/init.d/mosdns 文件。我的 OpenWrt 是自己编译的, ps 命令不支持 pid 参数,所以 /etc/init.d/mosdns 中判断 mosdns 是否运运行的函数

is_running() {
    [ -f "$pid_file" ] && ps $(get_pid) > /dev/null 2>&1
}

是无法正确执行的,即便 mosdns 已经正常启动。所以我将其修改为:

is_running() {
    pgrep -x /root/mosdns/mosdns > /dev/null
}

配置文件主要也是参考了作者提供的模板,自己添加用于解析国外 DNS 的 upstream server。我的 upstream server 都是自己搭建,有的加了中转,保证高峰时期的访问。另外同时用 UDP 和 TCP upstream server,避免 UDP 包在传输的时候被优化掉。在一开始仅用 UDP 的时候,经常出现 upstream server 查询超时。加入 TCP 节点后有很大的改善。 config.yaml 修改部分配置,其余可以使用作者的模板

  - tag: forward_local                # 转发至本地服务器的插件
    type: forward
    args:
      upstream:
        - addr: 223.5.5.5:53

  - tag: forward_remote               # 转发至远程服务器的插件
    type: forward
    args:
      upstream:
        - addr: ip:port
          trusted: true
        - addr: domain:port
        - addr: tcp://domain:port
      bootstrap:
        - https://223.5.5.5/dns-query
        - tls://1.1.1.1

完成后运行 /etc/init.d/mosdns start 。用下来查询速度很快,最重要的是内存占用直接下降到 7~8%。mosdns 的配置对于基本功能其实不算难,命令序列的多样组合可以实现很多高级功能。