mosdns all in one 分流加自定义解析,不依赖 AdGuardHome

AdGuardHome 的主要优点是可视化,有去广告规则可用。 但是AdGuardHome自己的分流规则配置较为复杂,有第三方提供分流规则,但是实际测试因为无法使用adg的并发查询以及adg自身的性能局限所以效果并不好。所以一般都是和msdns配合使用,例如 mosdns代理两个adg分别负责国内和国外dns,或者adg作为前端后端使用modns。
但是如果你对可视化管理和dns统计没啥需求的话,完全没必要,单独mosdns即可完成。

下文以pve lxc alpine为例 openwrt或其他linux发行版同样操作

#安装

直接下载 mosdns 下载unzip解压到 /opt/mosdns运行 ./mosdns service install 即可。

#准备几个规则文件

主要是 国内ip清单 国内名站域名清单 国外名站域名清单 一个空白的hosts.txt 如果你有自选cf ip需求还需要准备 cf ip自动列表

sh
cd /opt/mosdns/
wget  https://raw.githubusercontent.com/IceCodeNew/4Share/master/geoip_china/china_ip_list.txt -O geoip_cn.txt
wget  https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/reject-list.txt -O geosite_category-ads-all.txt
wget  https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/proxy-list.txt -O geosite_geolocation-!cn.txt
wget  https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/direct-list.txt -O geosite_cn.txt
echo "localhost 127.0.0.1"> /opt/mosdns/hosts.txt #注意格式和系统的hosts文件不一样
wget https://www.cloudflare.com/ips-v4 -O cf4.txt #cf ip地址
wget https://www.cloudflare.com/ips-v6 -O cf6.txt
cat cf4.txt  <(echo)  cf6.txt >geoip_cloudflare.txt  #合并

#可选的自建doh

目的是在深度学习环境不用的情况下依旧可以正确返回域名实际ip.
https://dev.leiyanhui.com/route/safe-dns 查看 cfwork自建doh

#config.yaml

基本逻辑,国内域名geosite_cn.txt使用国内dns(dot)并发解析,国外域名geosite_geolocation-!cn.txt使用 国外dns和自建doh解析
如果非清单内的域名,并且国内dns查询的一个域名返回的是一个非国内ip,那么使用国外 国外dns和自建doh解析 重新解析一次解决被污染问题
因为去广告geosite_category-ads-all.txt 会导致一些问题,并且我这里没这个需求,所以没有添加去广告规则。你可以自己添加上

sh
cat > /opt/mosdns/config.yaml << \EOF
log:
  level: error #日志级别。可选 "debug" "info" "warn" "error"。默认 "info"
  file: "/opt/mosdns/log.log"

# API 入口设置
api:
  http: "0.0.0.0:9091"

include: []

plugins:
  # 自定义hosts 注意格式和系统hosts不同 支持泛域名domain和fulldomain
  - tag: mosdns_hosts
    type: hosts
    args:
      files:
        - "/opt/mosdns/hosts.txt"
# 测试pipeline ./mosdns probe pipeline tls://101.226.4.6
  # 阿里和360的不支持
  # 转发至本地服务器 国内解析
  - tag: forward_local
    type: forward
    args:
      concurrent: 3 #mosdns限制最大3并发
      upstreams: #因为最大3并发所以三个就够了自己选速度好的
        - addr: "tls://223.5.5.5" #阿里
          enable_pipeline: false
        - addr: "tls://1.12.12.12" #腾讯 dnspod
          enable_pipeline: true
        - addr: "tls://101.226.4.6" #360电信
          enable_pipeline: false
  # 转发至远程服务器 境外解析上游
  - tag: forward_remote
    type: forward
    args:
      concurrent: 3 #最大3并发
      upstreams:
        - addr: tls://8.8.8.8
          enable_pipeline: true
        - addr: tls://1.1.1.1
          enable_pipeline: true
        - addr: https://你的自建doh地址
          bootstrap: 223.5.5.5 #bootstrap地址负责解析doh域名 只能udp
          bootstrap_version: 4 #解析的doh域名返回ipv4还是v6
          enable_pipeline: false
          enable_http3: false #http3 udp不稳 还是强制走http2
  # 国内域名
  - tag: geosite_cn
    type: domain_set
    args:
      files:
        - "/opt/mosdns/geosite_cn.txt"

  # 国内 IP
  - tag: geoip_cn
    type: ip_set
    args:
      files:
        - "/opt/mosdns/geoip_cn.txt"

  # 国外域名
  - tag: geosite_no_cn
    type: domain_set
    args:
      files:
        - "/opt/mosdns/geosite_geolocation-!cn.txt"

  # 缓存
  - tag: lazy_cache
    type: cache
    args:
      size: 20000
      lazy_cache_ttl: 86400
      #dump_file: "/opt/mosdns/cache.dump"
      #dump_interval: 600
  # 国内解析
  - tag: local_sequence
    type: sequence
    args:
      - exec: $forward_local

  # 国外解析
  - tag: remote_sequence
    type: sequence
    args:
      - exec: prefer_ipv4
      - exec: $forward_remote

  # 有响应终止返回
  - tag: has_resp_sequence
    type: sequence
    args:
      - matches: has_resp
        exec: accept

  # fallback 用本地服务器 sequence
  # 返回非国内 ip 则 drop_resp
  - tag: query_is_local_ip
    type: sequence
    args:
      - exec: $local_sequence
      - matches: "!resp_ip $geoip_cn"
        exec: drop_resp

  # fallback 用远程服务器 sequence
  - tag: query_is_remote
    type: sequence
    args:
      - exec: $remote_sequence

  # fallback 用远程服务器 sequence
  - tag: fallback
    type: fallback
    args:
      primary: query_is_local_ip
      secondary: query_is_remote
      threshold: 500
      always_standby: true

  # 查询国内域名
  - tag: query_is_local_domain
    type: sequence
    args:
      - matches: qname $geosite_cn
        exec: $local_sequence

  # 查询国外域名
  - tag: query_is_no_local_domain
    type: sequence
    args:
      - matches: qname $geosite_no_cn
        exec: $remote_sequence

  # 主要的运行逻辑插件
  # sequence 插件中调用的插件 tag 必须在 sequence 前定义,
  # 否则 sequence 找不到对应插件。
  - tag: main_sequence
    type: sequence
    args:
      - exec: $mosdns_hosts
      - exec: query_summary entry
      - exec: $lazy_cache
      - exec: $query_is_local_domain
      - exec: jump has_resp_sequence
      - exec: $query_is_no_local_domain
      - exec: jump has_resp_sequence
      - exec: $fallback

  #### 最后配置 server........略
  - tag: server
    type: udp_server # 目前有 udp/tcp/http_server
    args:
      entry: main_sequence
      listen: 0.0.0.0:53
  - tag: server_tcp
    type: tcp_server
    args:
      entry: main_sequence
      listen: 0.0.0.0:53
  - tag: "server_http"
    type: "http_server"
    args:
      entries:                 # []extry
        - path: /dns-query     # 本路径执行   
          exec: main_sequence # 可执行插件的 tag。  
      src_ip_header: "X-Forwarded-For"  # 从 HTTP 头获取用户 IP。
      listen: 0.0.0.0:80  # 监听地址。
      cert: "" # 留空 cert 和 key 后会禁用 TLS。 这里没有配置证书,外网使用另外有acme和nginx处理https
      key: "" 
      idle_timeout: 10       # 空连接超时。单位秒。默认 30。
EOF
/etc/init.d/mosdns restart

#部署

#路由器和内网机器

因为我这里是独立部署在 pve lxc里面,ip是 10.1.1.104。
在openwrt 或者 ikuai中配置上游dns为 10.1.1.104即可,内网内其他机器的dns可以用路由器ip作为dns或者mosdns的10.1.1.104均可

#clash

clash 删除其他dns NameServer FallBack Default-NameServer 全部设置为 10.1.1.104

#外网部署

因为家宽是没有53端口的,你可以从路由器用端口映射修改一下udp tcp的端口,或者外网直接用server_http 走doh

#存在的问题

主要是自定义域名解析:
https://irine-sistiana.gitbook.io/mosdns-wiki/mosdns-v5/ru-he-pei-zhi-mosdns/yu-ming-pi-pei-gui-ze
mosdns 的hosts方法,支持domain 和 full keyword 和 正则。 可以解决多数自定义域名解析的问题。
但是修改hosts文件后 需要重启才能生效 这就搞的很烦。

评论