分享 mosdns V5 FakeIP 分流方案

chenbin36255 · 2024-9-24 09:21:16 · 152 次点击
可用来代替 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
```
举报· 152 次点击
登录 注册 站外分享
3 条回复  
YGBlvcAK 小成 2024-9-24 10:51:34
感谢分享,你这个逻辑好复杂,有没有测试解析延迟呢?首次解析延迟?静默 5 分钟后的延迟?国内国外域名分别的延迟?
mohumohu 小成 2024-9-24 14:13:04
按我理解,国外解析 dns 只是为了 dns 防泄漏然后分流吧,fakeip 实际上不使用国外 dns 的解析结果,都是落地机直接出去的
yyysuo 小成 2024-9-24 16:47:49
最新的 5.3.3 的 mosdns 用 h3 会炸,223 不支持 pipeline ,8888 也别开 pipeline ,有问题的,有一定的失败机率。
感谢分享,fakeip 网关模式的用户越来越壮大了,确实是体验最好的方案了。
最后看我的方案喽  https://github.com/IrineSistiana/mosdns/discussions/837
返回顶部