🚀使用mosdns替代openclash默认的dns分流

Linux Mar 24, 2022

前言

自己的软路由R4S的代理工具从passwall替换到openclash之后, 定制性更好了, 但是我发现openclash它自己的DNS分流有时候可能会出现DNS污染的问题, 不知道是不是因为我配置的原因

然后我们其实可以使用其他的DNS转发工具来替代openclash的DNS转发功能, 比如smartdnsmosdns, 个人认为smartdns还是有点小小复杂, 所以选择了比较简单和上手容易的mosdns

下载和安装

IPK核心包

这里下载打包好的二进制文件(我的是ARM架构), 搜索找到对应的ipk文件, 比如我现在的文件是mosdns_3.7.2-1_aarch64_generic.ipk, 如果你是其他架构可以返回到这里找到对应你的软路由的架构, 比如x86_64或者arm_cortex-a9

下载

$ wget https://openwrt.cc/snapshots/packages/aarch64_generic/packages/mosdns_3.7.2-1_aarch64_generic.ipk

安装

$ opkg install mosdns_3.7.2-1_aarch64_generic.ipk

安装mosdns的luci支持

这里下载luci对应的包, 然后使用命令安装

首先下载

wget https://github.com/QiuSimons/openwrt-mos/releases/download/1.2.1/luci-app-mosdns_1.2_all.ipk

安装luci包

$ opkg install luci-app-mosdns_1.2_all.ipk

安装语言文件, 下载和上一步同理

$ opkg install luci-i18n-mosdns-zh-cn_unknown_all.ipk

安装指南

  • 提示mosdns依赖不存在问题, 说明没有安装核心文件, 回到上一步安装好mosdns核心就可以了

  • 提示v2ray-geoipv2ray-geosite依赖问题, 是因为luci-mosdns依赖这两个包, 可以去这里搜索这两个包进行安装

  • 提示v2ray-core不存在的问题, 说明你的固件还没有v2ray-core依赖, 直接在依赖仓库搜索v2ray-core核心安装即可

  • 提示`Package luci-app-mosdns wants to install file /etc/init.d/mosdns

    But that file is already provided by package`说明核心已经把这个启动文件安装好了, 我们删除它, 然后重新安装`luci-app-mosdns_1.2_all.ipk`和`luci-i18n-mosdns-zh-cn_unknown_all.ipk`, 安装好了之后检查`/etc/init.d/mosdns`文件是否存在, 不存在的话, 去[openwrt-mos](https://github.com/QiuSimons/openwrt-mos/tree/master/luci-app-mosdns/root/etc/init.d)拷贝一下对应的文件放回原位, 使用`chmod +x mosdns`增加执行权限
    

配置

安装好luci包之后, 可以直接在路由器web界面进行控制和配置, 我们直接使用自定义配置

在下边的自定义配置粘贴配置, 记得别忘了更新mosdns的数据, 会下载相关的geoip.datgeosite.dat文件等, 如果更新失败可以去这里下载对应的文件
如果需要cn.dat文件可以到这里下载
下载回来的两个文件放入到/etc/mosdns目录下, 你也可以使用我提供的文件

log:
  level: warn
  file: "/tmp/mosdns.log"
plugin:
  - tag: main_server
    type: server
    args:
      entry:
        - main_sequence
      server:
        - protocol: udp
          addr: "[::1]:5335"
        - protocol: tcp
          addr: "[::1]:5335"
        - protocol: udp
          addr: "127.0.0.1:5335"
        - protocol: tcp
          addr: "127.0.0.1:5335"
  - tag: main_sequence
    type: sequence
    args:
      exec:
        # ad block
        # - if:
        #     - query_is_ad_domain
        #   exec:
        #     - _block_with_nxdomain
        #     - _return
        - mem_cache
        - if:
            - query_is_local_domain
            - "!_query_is_common"
          exec:
            - forward_local
            - _return
        - if:
            - query_is_non_local_domain
          exec:
            - _prefer_ipv4
            - forward_remote
            - _return
        - primary:
            - forward_local
            - if:
                - "!response_has_local_ip"
              exec:
                - _drop_response
          secondary:
            - _prefer_ipv4
            - forward_remote
          fast_fallback: 600
          always_standby: true
  - tag: mem_cache
    type: cache
    args:
      size: 1024
      # use redis as the backend cache
      # redis: 'redis://localhost:6379/0'
      # redis_timeout: 50
      lazy_cache_ttl: 86400
      lazy_cache_reply_ttl: 30
  - tag: forward_local
    type: fast_forward
    args:
      upstream:
        - addr: "udp://114.114.114.114"
        - addr: "udp://223.5.5.5"
        - addr: "https://dns.alidns.com/dns-query"
          idle_timeout: 30
          trusted: true
        - addr: "https://doh.pub/dns-query"
          idle_timeout: 30
          trusted: true
  - tag: forward_remote
    type: fast_forward
    args:
      upstream:
        - addr: "udp://8.8.8.8"
        - addr: "https://dns.google/dns-query"
          dial_addr: "8.8.8.8:443"
          idle_timeout: 30
          trusted: true
        - addr: "https://cloudflare-dns.com/dns-query"
          dial_addr: "1.1.1.1:443"
          idle_timeout: 30
          trusted: true
  - tag: query_is_local_domain
    type: query_matcher
    args:
      domain:
        - "ext:./geosite.dat:cn"
        - "ext:./geosite.dat:apple-cn"
        - "ext:./geosite.dat:steam@cn"
  - tag: query_is_non_local_domain
    type: query_matcher
    args:
      domain:
        - "ext:./geosite.dat:geolocation-!cn"
  - tag: query_is_ad_domain
    type: query_matcher
    args:
      domain:
        - "ext:./geosite.dat:category-ads-all"
  - tag: response_has_local_ip
    type: response_matcher
    args:
      ip:
        # 使用默认geoip.dat文件
        # - "ext:./geoip.dat:cn"
        # 使用高性能cn.dat文件, 需要下载对应的文件
        - "ext:./cn.dat:cn"

然后点击右下角的保存并应用, mosdns会reload并重启, 如果提示正在运行, 表明运行成功, 你也可以使用命令进行手动操作

$ /etc/init.d/mosdns enable
$ /etc/init.d/mosdns reload
$ /etc/init.d/mosdns restart

检查是否启动成功, 如果有端口监听说明mosdns已经在正常工作了

$ netstat -a | grep 5335
tcp        0      0 localhost:5335          0.0.0.0:*               LISTEN
tcp        0      0 localhost:5335          :::*                    LISTEN
udp        0      0 localhost:5335          0.0.0.0:*
udp        0      0 localhost:5335          :::*

配置说明请参看官方的wiki文档

配合openclash

找到openclash的全局设置页面, 找到DNS设置选项, 增加两个DNS服务器, 分别是NameServer和FallBack, 都得填mosdns的地址, 既本地地址127.0.0.1和对应监听的端口5335, 协议是UDP并✅上这两个DNS服务器

openclash DNS其他部分这么设置

保存并应用配置, 等待openclash重启, 就可以使用mosdns分流啦

V4版本配置

卸载luci-app-mosdns并更新到最新的1.4.2版本, 然后更新mosdns内核到最新V4版本以上, 接着可以使用以下的配置文件, 在这之前记得下载geosite.dat和cn.dat文件哦, 配置文件由@gdyan2001提供, 特别感谢👍

log:
  level: info
  file: "/tmp/mosdns.log"
data_providers:
  - tag: geosite
    file: /etc/mosdns/geosite.dat
    auto_reload: true
  - tag: cn
    file: /etc/mosdns/cn.dat
    auto_reload: true

plugins:
  # 缓存
  - tag: mem_cache
    type: cache
    args:
      size: 1024
      lazy_cache_ttl: 17200
      # redis
      # redis: "redis://localhost:6379/0"
      # redis_timeout: 1000
  # 修改应答 ttl
  - tag: "modify_ttl"
    type: "ttl"
    args:
      minimal_ttl: 300
      maximum_ttl: 3600

  # 阿里 dns
  - tag: ali
    type: fast_forward
    args:
      upstream:
        - addr: "223.5.5.5"
        - addr: "https://dns.alidns.com/dns-query"
          dial_addr: "223.5.5.5"
          trusted: true
        - addr: "tls://dns.alidns.com"
          dial_addr: "223.5.5.5"
          trusted: true

  # dnspod
  - tag: dnspod
    type: fast_forward
    args:
      upstream:
        - addr: "119.29.29.29"
        - addr: "https://doh.pub/dns-query"
          dial_addr: "1.12.12.12"
          trusted: true
        - addr: "tls://dot.pub"
          dial_addr: "1.12.12.12"
          trusted: true

  # 本地 dns 备用
  - tag: localdns
    type: fast_forward
    args:
      upstream:
        - addr: "udp://114.114.114.114"

  # google dns
  - tag: google
    type: fast_forward
    args:
      upstream:
        - addr: "https://dns.google/dns-query"
          dial_addr: "8.8.4.4"
          trusted: true
        - addr: "tls://dns.google"
          dial_addr: "8.8.4.4"
          trusted: true

  # cloudflare
  - tag: cloudflare
    type: fast_forward
    args:
      upstream:
        - addr: "https://cloudflare-dns.com/dns-query"
          dial_addr: "1.0.0.1"
          trusted: true
        - addr: "tls://cloudflare-dns.com"
          dial_addr: "1.0.0.1"
          trusted: true

  # doq 备用
  - tag: adguard
    type: forward
    args:
      upstream:
        - addr: "quic://dns-unfiltered.adguard"
          ip_addr:
            - "94.140.14.140"
            - "94.140.14.141"
          trusted: true

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

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

  ################ 匹配器插件 #################

  # 匹配本地域名的插件
  - tag: query_is_local_domain
    type: query_matcher
    args:
      domain:
        - "provider:geosite:cn,apple-cn,steam@cn"

  # 匹配非本地域名的插件
  - tag: query_is_non_local_domain
    type: query_matcher
    args:
      domain:
        - "provider:geosite:geolocation-!cn"

  # 匹配广告域名的插件
  - tag: query_is_ad_domain
    type: query_matcher
    args:
      domain:
        - "provider:geosite:category-ads-all"

  # 匹配本地 IP 的插件
  - tag: response_has_local_ip
    type: response_matcher
    args:
      ip:
        - "provider:cn:cn"

  - tag: main_sequence
    type: sequence
    args:
      exec:
        # - hosts
        - mem_cache
        - _no_ecs

        - if: query_is_ad_domain
          exec:
            - _new_nxdomain_response
            - _return

        - if: query_is_local_domain
          exec:
            - forward_local
            - if: response_has_local_ip
              exec:
                - _return

        - if: query_is_non_local_domain
          exec:
            - _prefer_ipv4 # 优先 IPv4
            - forward_remote # 用远程服务器获取应答
            - if: "! response_has_local_ip"
              exec:
                - _return
        - primary:
            - forward_local # 本地服务器获取应答。
            - if: "(! response_has_local_ip) && [_response_valid_answer]"
              exec:
                - _drop_response # 丢掉。
          secondary:
            - _prefer_ipv4
            - forward_remote
          fast_fallback: 300
          always_standby: true
        - modify_ttl

servers:
  - exec: main_sequence
    listeners:
      # - protocol: udp
      #   addr: "[::1]:5335"
      # - protocol: tcp
      #   addr: "[::1]:5335"
      - protocol: udp
        addr: "0.0.0.0:5335"
      - protocol: tcp
        addr: "0.0.0.0:5335"

小提示

  • 注意, mosdns本身是支持IPv6的, 现在这里的配置不支持IPv6, 所以需要把openwrt的相关的IPv6设置都关掉, openclash禁止代理IPv6和禁止允许IPv6类型DNS解析. IPv6相关如果你有更好的配置和建议, 欢迎留言

  • 如果打不开对应的网站, 检查一下本地的DNS, 使用命令刷新DNS或者重启电脑试试

  • mosdns除了当做openclash的上级, mosdns也可以直接跳过openclash当做dnsmasq的上级

  • 使用mosdns, 建议关闭浏览器的安全DNS(DoH DNS), 如果需要使用的话, 就把安全DNS设置成google或者cloudflare的

Credits

更新日志

  • 更新至V4版本的配置文件 2022/10/16

  • 删除hosts映射, 配置不兼容新版本 2022/06/10

  • 替换geoip文件 2022/05/04

  • 简化配置文件 2022/04/25

Tags

壳壳

一个想法不一定对