【软路由终极 DNS】Mikrotik ROS V7 + Mosdns v5 完美分流与去广告保姆级教程

2026-05-28T23:41:00

【软路由终极 DNS】Mikrotik ROS V7 + Mosdns v5 完美分流与去广告保姆级教程

在折腾软路由的过程中,大家肯定都遇到过这些头疼的问题:DNS 总是泄漏、访问海外网站慢吞吞、国内网站还会莫名其妙绕路。今天,我们就来解决这个痛点!

我们将利用 MikroTik RouterOS (ROS) V7 强大的底层网络能力,结合 Docker 部署 Mosdns (v5版本),打造一套“双级缓存 + 精准分流 + 无感去广告”的终极 DNS 方案。

这套方案不仅解析速度极快,而且网络逻辑极其清晰,非常适合搭配专线(IPLC/IEPL)或者 任何形式的 异地组网隧道使用。


为什么选择这套方案?

很多传统的教程教你底层劫持 53 端口,这种方法虽然“无感”,但一旦网络出了问题,排错简直让人抓狂。我们这套方案采用的是更加科学的“L1 + L2 黄金双重缓存”模式:

  1. L1 极速前台 (ROS 自带的 DNS): 手机或电脑查询域名时,如果 ROS 里有缓存,0 毫秒直接返回结果,瞬间打开网页,极大节省路由器性能。
  2. L2 智能智囊团 (Mosdns): 如果 ROS 没缓存,就会去问后端的 Mosdns。Mosdns 会非常聪明地帮你分类:国内直连、广告拦截、海外域名走隧道防污染。两者配合,干活不累!

核心准备:为什么必须插个 U 盘?

在开干之前,请务必给你的 ROS 路由器插上一个外置 U 盘或者移动硬盘(记得在 ROS 的 System -> Disks 里格式化为 ext4 格式)。

MikroTik 官方强烈建议这么做!
因为 Docker 容器运行和 Mosdns 的缓存读写非常频繁。如果你直接把它们装在路由器的内置存储(NAND闪存)上,会让路由器的闪存芯片快速老化,甚至提早报废。 为了心爱的路由器多活几年,接下来的教程我们都会以 U 盘目录(比如 usb1/)来演示。


第一步:把 Mosdns 镜像拉回家 (小心架构坑)

在国内,ROS 直接去拉 Docker 镜像经常会卡死或者报错。所以,我们用最稳妥的电脑下载 -> 离线导入的方法。

找一台能正常科学上网的电脑(Windows 或 Mac 都行),装好 Docker,打开命令行准备拉取。

这里有个天坑:必须看清你路由器的 CPU 架构!
如果你用的是 M1/M2 芯片的苹果电脑,而路由器是普通的 x86 软路由,直接下载是没法用的!必须加个参数强制指定架构:

  • 如果你的软路由是普通的 x86 架构 (AMD64):

    docker pull --platform linux/amd64 irinesistiana/mosdns:latest
  • 如果你的软路由是 ARM64 架构(比如 MikroTik 的 RB5009):

    docker pull --platform linux/arm64 irinesistiana/mosdns:latest

下载完后,打包成一个 tar 文件:

docker save -o mosdns.tar irinesistiana/mosdns:latest

接着,把这个 mosdns.tar 文件传到 ROS 路由器的 U 盘里(打开 Files 拖进去就行)。最后在 ROS 的 Terminal 里执行导入命令:

/container/add file=usb1/mosdns.tar interface=veth-mosdns root-dir=usb1/mosdns-root logging=yes

第二步:准备分流规则库 (告别旧版格式)

Mosdns v5 版本大更新注意: 新版已经彻底废弃了 .dat 格式的文件!以后只能用纯文本的 .txt 格式了。

请去下面这两个官方 GitHub 仓库,下载最新的纯文本规则,然后放到 ROS 的 usb1/mosdns/etc/ 目录里:


第三步:编写 Mosdns 核心配置文件

在 usb1/mosdns/etc/ 目录下,新建一个 config.yaml 文件。把下面的代码直接复制进去:

log:
  level: info
  file: ""

# 开启 API 接口(用来监控和看缓存)
api:
  http: "0.0.0.0:8080"

plugins:
  # 1. 核心缓存设置
  - tag: local_cache
    type: cache
    args:
      size: 10240
      lazy_cache_ttl: 86400
      dump_file: "/etc/mosdns/cache.dump"
      dump_interval: 600

  # 2. 国内怎么查
  - tag: forward_local
    type: forward
    args:
      concurrent: 2
      upstreams:
        - addr: "223.5.5.5"
        - addr: "119.29.29.29"

  # 3. 海外怎么查 (我们直接用 8.8.8.8,配合 ROS 路由走隧道,速度最快!)
  - tag: forward_remote
    type: forward
    args:
      concurrent: 1
      upstreams:
        - addr: "8.8.8.8"

  # 4. 把刚刚下载的规则加载进来
  - tag: geosite_cn
    type: domain_set
    args:
      files:
        - "/etc/mosdns/direct-list.txt"
  - tag: geosite_no_cn
    type: domain_set
    args:
      files:
        - "/etc/mosdns/proxy-list.txt"
  - tag: geosite_ad
    type: domain_set
    args:
      files:
        - "/etc/mosdns/reject-list.txt"
  - tag: geoip_cn
    type: ip_set
    args:
      files:
        - "/etc/mosdns/cn.txt"

  # 5. 核心干活的流程
  - tag: main_sequence
    type: sequence
    args:
      - matches: qname in-addr.arpa local lan
        exec: reject 3
      - exec: $local_cache
      - matches: has_resp
        exec: accept
      - matches: qname $geosite_ad
        exec: reject 3
      - matches: qname $geosite_no_cn
        exec: $forward_remote
      - matches: has_resp
        exec: $local_cache
      - matches: has_resp
        exec: accept
      - matches: qname $geosite_cn
        exec: $forward_local
      - matches: has_resp
        exec: $local_cache
      - matches: has_resp
        exec: accept
      # 兜底:如果不认识这域名,先按国内查。如果查出来的 IP 不是国内的,扔掉结果,重新去海外查
      - exec: $forward_local
      - matches: "!resp_ip $geoip_cn"
        exec: drop_resp
      - exec: $forward_remote
      - matches: has_resp
        exec: $local_cache
      - matches: has_resp
        exec: accept

  # 6. 监听端口
  - tag: udp_server
    type: udp_server
    args:
      entry: main_sequence
      listen: ":53"
  - tag: tcp_server
    type: tcp_server
    args:
      entry: main_sequence
      listen: ":53"

附:Mosdns 常用 API 接口(高阶玩法)

在上面的配置里,我们开了 8080 端口的 API。你可以直接在浏览器里访问这些地址(假设你给 Mosdns 设置的 IP 是 172.17.0.3),日常维护非常方便:

  • http://172.17.0.3:8080/metrics:查看各种统计数据,高玩可以把它接到 Grafana 里做个炫酷的大屏。
  • http://172.17.0.3:8080/plugins/local_cache/dump:把内存里的缓存立刻保存到文件里(这样重启路由就不怕缓存丢了)。
  • http://172.17.0.3:8080/plugins/local_cache/flush:一键清空所有的 DNS 缓存(平时折腾规则、排错的时候必用)。
  • POST /plugins/local_cache/load_dump:从文件里重新加载缓存。
  • /debug/pprof/*:这是给开发者用来分析性能的,咱们普通玩家可以无视。

第四步:给 Docker 建个独立的“小房间”

这里很容易踩坑:很多人会把 Docker 的网桥和家里的局域网网桥桥接在一起,千万别这么干! 它们应该互相独立,靠路由器的“路由表”来通讯。

  1. 建个专门给 Docker 用的网桥(比如叫 docker-bridge),IP 设置为 172.17.0.1/24。
  2. 建个虚拟网卡(VETH,比如叫 veth-mosdns),IP 设置为 172.17.0.3/24,网关填 172.17.0.1。
  3. 把这个 veth-mosdns 加到 docker-bridge 网桥里。

(因为 ROS 路由器很聪明,它会自动做路由,所以你电脑直接 ping 172.17.0.3 就能通)


第五步:启动容器 (Winbox 报错解决办法)

如果你用的是 ROS v7 的 Winbox 图形界面,在设置容器内存(Shm Size)的时候,经常会弹个报错“Error in Shm Size - expected!”,怎么填都不对。

解决办法很简单:别用图形界面了! 另外,为了防止路由器停电重启后断网,我们必须设置开机自启;为了防止内存爆满卡死,还要设置内存上限(比如 256M)。

打开 ROS 的 Terminal,用命令直接搞定(假设你的容器编号是 0):

# 绕过报错,限制最大内存 256M,开启开机自启
/container set 0 shm-size=64M memory-high=256M start-on-boot=yes

# 启动!
/container start 0

启动后,输入 /container print 看看。如果内存占用跑到 60MB 以上,状态显示 R - RUNNING,恭喜你,几十万条规则已经成功加载进内存了!


第六步:让 8.8.8.8 强行钻隧道

既然咱们有 IPLC 专线或者 ZeroTier 隧道,那还折腾什么复杂的 DNS 加密呢?直接走物理隧道最简单粗暴。

去 ROS 的 Routing -> Rules 里加一条规则:

  • Dst. Address (目标地址): 8.8.8.8/32
  • Action (动作): lookup only in table
  • Table (路由表): 选择你的专线隧道(比如 To-IPLC)。

设置好后,Mosdns 只要去问 8.8.8.8,这个请求就会直接被塞进隧道送到海外,国内的污染根本碰不到它。


第七步:接管全网,大功告成!

最后一步,让家里的设备都用上这套神仙系统,而且要做最规范的配置,拒绝隐式劫持:

  1. 在 ROS 的 IP -> DHCP Server -> Networks 里,把你局域网(比如 192.168.99.0/24)的 DNS Server 设置成路由器的 IP(192.168.99.1)。
  2. 在 IP -> DNS 里,勾选 Allow Remote Requests,允许别人来查 DNS。
  3. 把 Servers 填上刚才 Mosdns 的 IP:172.17.0.3。
  4. 建议把下面那个 Cache Size 调大一点(比如填 163840 KiB),让 ROS 的前置缓存威力全开。

最终验收:
在电脑命令行里敲:
nslookup www.baidu.com
nslookup www.google.com
国内出本地 CDN,海外出真实纯净 IP。搞定收工!


本文由疯狂的猿猴博客原创提供
官方网站:https://www.592850.com/
当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »