可用来代替 paopaodns 分流 配合 paopaogateway 或者 singbox 等 fakeip 网关实现分流科学上网
实测体验比 paopaodns 丝滑(不知道为什么 paopaodns 的国外解析 dns 全世界飞)
也许不是所有人都需要一个递归服务器 国内的 ISP 的 DNS 速度更快
打包产物:
[dns.zip]( https://github.com/user-attachments/files/17106443/dns.zip)
包含 mosdns+adg+compose 文件 修改配置后一键启动
核心思路:
Mosdns:负责 DNS 分流查询,国内转发 ISP+阿里
国外通过 sock5 代理转发 cf+google (国内国外均有 2*2 组 dns 并行查询)
AdGuard Home(ADG):负责 DNS 去广告+控制面板(不需要可以去除,仅使用 mosdns 也可以)
DNS 泄漏:
所谓的 DNS 泄露国内节点,只是在 IP 分流时,查询了国内 DNS 引起,仅在理论上有安全问题。当然这个 DoH 使用境外服务器进行 IP 分流,完美解决泄漏问题 [[DNS 分流与泄露分析 31]( https://apad.pro/dns-leak/)]
DNS 检测:
境内检测:[https://nstool.netease.com 123]( https://nstool.netease.com/)
境外检测:[DNS Leak Test - BrowserLeaks 99]( https://browserleaks.com/dns)
[DNS 泄露检测]( https://ipleak.net/)
这个可以查询 DNS 泄露情况 理想状态打开都是实际代理落地区域的 DNS
效果:
adg 配置去广告和去 pcdn 黑名单
adg 不开启缓存( fakeip 需要 TTL 尽量短),如有需要在 mosdns 的 localdns 中设置
0 缓存实现 dns 查询 10s ,所有网站秒开
![image]( https://github.com/user-attachments/assets/0095ac22-72ad-478a-9aab-da65c25977ef)
![image]( https://github.com/user-attachments/assets/3e8df003-2a99-4526-92bc-eeec8f85f2d6)
配置文件
下载分流所需文件
使用以下脚本,修改变量 v2dat_dir 为你的保存路径 (保存为 .sh 文件后, 记得 chmod +x xxx.sh 赋权):
```
#!/bin/sh
set -e # Exit if any command fails
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT # Ensure temporary directory is removed on script exit
v2dat_dir=<自定义路径>/mosdns
geodat_update() {
curl --connect-timeout 5 -m 60 -kfSL -o "$TMPDIR/geoip.dat" "https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-only-cn-private.dat"
curl --connect-timeout 5 -m 60 -kfSL -o "$TMPDIR/geosite.dat" "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
\cp -a "$TMPDIR"/geoip.dat "$TMPDIR"/geosite.dat $v2dat_dir
}
# Unpack and process the data
v2dat_dump() {
mkdir -p "$v2dat_dir/rules/"
curl -fSL -o "$v2dat_dir/v2dat" "https://raw.githubusercontent.com/xukecheng/scripts/main/v2dat"
chmod +x "$v2dat_dir/v2dat"
rm -f "$v2dat_dir/rules/geo"*.txt
"$v2dat_dir/v2dat" unpack geoip -o "$v2dat_dir/rules/" -f cn "$v2dat_dir/geoip.dat"
"$v2dat_dir/v2dat" unpack geosite -o "$v2dat_dir/rules/" -f apple -f cn -f 'geolocation-!cn' "$v2dat_dir/geosite.dat"
rm -rf "$v2dat_dir/v2dat"
}
update_local_ptr() {
curl --connect-timeout 5 -m 60 -kfSL -o "$v2dat_dir/rules/local-ptr.txt" "https://raw.githubusercontent.com/sbwml/luci-app-mosdns/v5/luci-app-mosdns/root/etc/mosdns/rule/local-ptr.txt"
}
geodat_update
v2dat_dump
update_local_ptr
touch $v2dat_dir/rules/force-nocn.txt
touch $v2dat_dir/rules/force-cn.txt
# force-cn 是强制本地解析域名,force-nocn 是强制非本地解析域名
echo "localhost 127.0.0.1" >> $v2dat_dir/rules/hosts.txt
```
说明( hosts 可以自定义域名解析,force-cn.txt 为强制转发国内 dns ,force-nocn.txt 为强制转发国外 DNS ,请自行修改,格式为 mosdns 标准格式)
```
chmod +x xxx.sh
./xxx.sh
# 检查文件
tree -f <变量 v2dat_dir 定义的路径>
<变量 v2dat_dir 定义的路径>
├── <变量 v2dat_dir 定义的路径>/geoip.dat
├── <变量 v2dat_dir 定义的路径>/geosite.dat
└── <变量 v2dat_dir 定义的路径>/rules
├── <变量 v2dat_dir 定义的路径>/rules/force-cn.txt
├── <变量 v2dat_dir 定义的路径>/rules/force-nocn.txt
├── <变量 v2dat_dir 定义的路径>/rules/geoip_cn.txt
├── <变量 v2dat_dir 定义的路径>/rules/geosite_apple.txt
├── <变量 v2dat_dir 定义的路径>/rules/geosite_cn.txt
├── <变量 v2dat_dir 定义的路径>/rules/geosite_geolocation-!cn.txt
├── <变量 v2dat_dir 定义的路径>/rules/hosts.txt
└── <变量 v2dat_dir 定义的路径>/rules/local-ptr.txt
```
DNS 配置文件 dns.yaml 请自行修改 ISP 的 DNS 和 socks5 代理地址(用来转发查询国外域名,避免 dns 泄露)
```
################ DNS Plugins #################
plugins:
- tag: google
type: forward
args:
concurrent: 2
upstreams:
- addr: "https://dns.google/dns-query"
dial_addr: "8.8.8.8"
enable_pipeline: true
enable_http3: true
socks5: "10.10.11.253:1080"
- addr: https://dns.google/dns-query
dial_addr: "8.8.4.4"
enable_pipeline: true
enable_http3: true
socks5: "10.10.11.253:1080"
- tag: cloudflare
type: forward
args:
concurrent: 2
upstreams:
- addr: "https://cloudflare-dns.com/dns-query"
dial_addr: "1.1.1.1"
enable_pipeline: true
enable_http3: true
socks5: "10.10.11.253:1080"
- addr: "https://cloudflare-dns.com/dns-query"
dial_addr: "1.0.0.1"
enable_pipeline: true
enable_http3: true
socks5: "10.10.11.253:1080"
- tag: ali
type: forward
args:
concurrent: 2
upstreams:
- addr: "https://dns.alidns.com/dns-query"
dial_addr: "223.5.5.5"
enable_pipeline: true
enable_http3: true
- addr: "https://dns.alidns.com/dns-query"
dial_addr: "223.6.6.6"
enable_pipeline: true
enable_http3: true
#ISP 提供的 DNS ,请自行修改
- tag: local
type: forward
args:
concurrent: 2
upstreams:
- addr: "udp://221.12.1.227:53"
- addr: "udp://221.12.33.227:53"
#上游 fakeip 代理网关
- tag: proxy
type: forward
args:
concurrent: 1
upstreams:
- addr: "udp://10.10.11.253:53"
# serfer 失败
- tag: reject_2
type: sequence
args:
- exec: reject 2
# 拒绝响应
- tag: reject_3
type: sequence
args:
- exec: reject 3
# 不支持的操作
- tag: reject_5
type: sequence
args:
- exec: reject 5
```
config.yaml 请自行修改 ecs IP 否则除了杭州联通外会减速
```
log:
level: info
file: "/etc/mosdns/mosdns.log"
api:
http: "0.0.0.0:5534"
include: ['/etc/mosdns/dns.yaml']
plugins:
# 国内域名
- tag: geosite_cn
type: domain_set
args:
files:
- "/etc/mosdns/rules/geosite_cn.txt"
- "/etc/mosdns/rules/force-cn.txt"
# 国内 IP
- tag: geoip_cn
type: ip_set
args:
files:
- "/etc/mosdns/rules/geoip_cn.txt"
# 苹果域名
- tag: geosite_apple
type: domain_set
args:
files:
- "/etc/mosdns/rules/geosite_apple.txt"
# 国外域名
- tag: geosite_no_cn
type: domain_set
args:
files:
- "/etc/mosdns/rules/geosite_geolocation-!cn.txt"
- "/etc/mosdns/rules/force-nocn.txt"
- tag: hosts
type: hosts
args:
files:
- "/etc/mosdns/rules/hosts.txt"
- tag: local_ptr
type: domain_set
args:
files:
- "/etc/mosdns/rules/local-ptr.txt"
- tag: forward_local
type: fallback
args:
primary: local # 主 dns
secondary: ali # 备用 dns
threshold: 500
always_standby: true
- tag: forward_remote
type: fallback
args:
primary: cloudflare # 主 dns
secondary: google # 备用 dns
threshold: 500
always_standby: true
- tag: forward_proxy
type: fallback
args:
primary: proxy # 主 dns
secondary: proxy # 备用 dns
threshold: 500
always_standby: true
# ECS
- tag: ecs_cn
type: "ecs_handler"
args:
forward: false # 是否转发来自下游的 ecs
preset: 101.71.1.1 # 发送预设 ecs
send: false # 是否发送 ecs
mask4: 24 # ipv4 掩码。默认 24 | 12
mask6: 48 # ipv6 掩码。默认 48 | 32
- tag: no_ecs
type: "ecs_handler"
args:
forward: false # 是否转发来自下游的 ecs
preset: "" # 发送预设 ecs
send: false # 是否发送 ecs
mask4: 24
mask6: 48
# 国外解析
- tag: forward_remote_upstream
type: sequence
args:
- exec: $no_ecs
- exec: prefer_ipv4
- exec: query_summary forward_remote
- exec: $forward_proxy
# 响应操作
- tag: has_resp_sequence
type: sequence
args:
- matches: has_resp
exec: accept
# 查询国内域名
# 返回非国内 IP 则 drop_resp
- tag: query_is_non_local_ip
type: sequence
args:
- exec: $ecs_cn
- exec: prefer_ipv4
- exec: $forward_local
- matches: "!resp_ip $geoip_cn"
exec: drop_resp
# fallback: 失败时回滚
# 回滚机制: 如果 primary 抛出错误,或返回但没有应答,或在 threshold 毫秒内无响应,则执行 secondary 。因无响应触发 fallback 时,如果 primary 比 secondary 先返回了应答,则依旧会采用 primary 的应答。
# 错误处理: 如果 primary 和 secondary 都无应答 (抛出了错误,无响应直到超时,返回了但无应答),则抛出错误。
## 此处做了防止 DNS 泄露的处理: 强制转发到远程 DNS (摘自 Github: sbwml/luci-app-mosdns)
- tag: fallback
type: fallback
args:
primary: forward_remote_upstream
secondary: forward_remote_upstream
threshold: 500
always_standby: true
- tag: apple_domain_fallback
type: fallback
args:
primary: query_is_non_local_ip
secondary: forward_local
threshold: 100
always_standby: true
# 匹配苹果域名的插件
- tag: query_is_apple_domain
type: sequence
args:
- matches: qname $geosite_apple
exec: $apple_domain_fallback
- exec: query_summary apple_domain_fallback
# 匹配本地域名的插件
- tag: query_is_local_domain
type: sequence
args:
- exec: $ecs_cn
- exec: prefer_ipv4
- matches: qname $geosite_cn
exec: $forward_local
- exec: query_summary forward_local
# 查询国外域名
- tag: query_is_no_local_domain
type: sequence
args:
- matches: qname $geosite_no_cn
exec: $forward_remote_upstream
- tag: query_is_reject_domain
type: sequence
args:
- matches:
- qtype 12
- qname $local_ptr
exec: reject 3
- matches: qtype 65
exec: reject 3
# 主要的运行逻辑插件
# sequence 插件中调用的插件 tag 必须在 sequence 前定义,
# 否则 sequence 找不到对应插件。
- tag: main_sequence
type: sequence
args:
- exec: $hosts
- exec: jump has_resp_sequence
- exec: forward_edns0opt 8
- exec: $query_is_apple_domain
- exec: jump has_resp_sequence
- exec: $query_is_reject_domain
- exec: jump has_resp_sequence
- exec: $query_is_local_domain
- exec: jump has_resp_sequence
- exec: $query_is_no_local_domain
- exec: jump has_resp_sequence
- exec: $fallback
- exec: jump has_resp_sequence
# 启动 udp 服务器
- tag: udp_serfer
type: udp_serfer
args:
entry: main_sequence
listen: ":53"
```
docker-compose.yaml(可以不使用 macvlan ,自行修改网卡名和局域网网段及 IP ,目前发现 mosdns 作为 adg 上游在测试时会报错不可用,实际解析正常可忽略)
```
fersion: '3'
networks:
macvlan_network:
drifer: macvlan
drifer_opts:
parent: eth0
ipam:
config:
- subnet: 10.10.11.0/24
gateway: 10.10.11.254
ip_range: 10.10.11.0/24
services:
mosdns:
image: irinesistiana/mosdns:latest
container_name: mosdns
networks:
macvlan_network:
ipv4_address: 10.10.11.251
volumes:
- ./mosdns:/etc/mosdns
restart: unless-stopped
adguardhome:
image: adguard/adguardhome:latest
container_name: adguardhome
networks:
macvlan_network:
ipv4_address: 10.10.11.252
volumes:
- ./adg/work:/opt/adguardhome/work
- ./adg/conf:/opt/adguardhome/conf
restart: unless-stopped
``` |
|