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自动列表
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 会导致一些问题,并且我这里没这个需求,所以没有添加去广告规则。你可以自己添加上
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文件后 需要重启才能生效 这就搞的很烦。