软路由与 DNS 折腾笔记
Fanx / 2023-04-08 / Linux / 阅读量 7006

前言

在几年前玩过软路由,配置是 J4125,当时觉得 OpenWrt 过于难配置、很多 Package 必须在编译的时候加上,当时是直接装了 Ubuntu 拨号,iptables 做 NAT 转发,再用 Docker 起一些服务,也够用,但是后来换了 AX3600 以后,就不想折腾送给朋友了。
随着使用 NAS、Xbox、Apple TV 等对网络需求的日益提高,以及 ShellClash 的内存泄露和 AX3600 连开个源都要耍猴等诸多问题,去年中旬购入了一台畅网 N5105,从 OpenWrt 到 ESXI 到 PVE、再到编译固件、云编译、折腾 DNS,过程很有意思,也很久没写博客了,就记录一下。

0x00 初见

和大多数初次接触软路由的小白一样,用 U 盘安装 PE 以 img 写盘的方式写恩山上的镜像,问题在于:

  • 硬件 OpenWrt 太浪费,另外很多小众功能在这种嵌入式系统中支持不友好。
  • 要什么软件包只能看作者有没有编译好,没有的话自己装有很多编译时就要加上的内核级依赖,安装时必出错。
  • 一大堆功能自己用不上。
  • 折腾完后再做改动可能出问题,一出问题又要重装重新配置。

那有没有一种方案可以解决这些问题,还能什么都能跑,又能随时恢复呢?

0x01 虚拟化

ESXI

中间学习编译固件和配置直通等基础操作也没什么讲的,网络上太多相关资料了,这里就不多说了。
ESXI 解决了我几大问题:

  • OpenWrt 系统只要 1 核 1G 内存就够用了,不浪费硬件,甚至对于不在 OpenWrt 上跑 Docker 的来说,1G 内存都是奢侈。资源得到了极大的节省。
  • 虚拟机可以随时备份,不用担心出问题了重装,还可以随时恢复。
  • OpenWrt 跑不了的,或者不想破环 OpenWrt 系统环境,可以创建另外的虚拟机。

已经很理想了对吧,直到家里断了一次电,ESXI 老牛拉破车般的启动速度也就不说了,甚至还把 OpenWrt 的虚拟磁盘搞挂了,顺便再记录一下修复命令吧:

# 检查磁盘
vmkfstools -x check openwrt.vmdk
# 以下结果表示磁盘需要修复
Disk needs repair.
# 修复磁盘
vmkfstools -x repair openwrt.vmdk 
# 以下结果表示此盘修复成功
Disk was successfully repaired.

很幸运,这次只是小问题,但是在找解决方法的过程中,发现了还有人甚至 vmdk 都消失了。
另外在 ESXI 中再启动其它虚拟机,如果运行时间比较长还有几率出现虚拟机内磁盘消失的情况,可能 N5105 对于企业级的平台来说还是太弱了,所以也就放弃了 ESXI。

PVE

直到遇见了 PVE,底层 Debian、LXC 模板一键部署虚拟机、惊人的启动速度、热修改虚拟机硬件配置,确实很强大
目前来说 PVE 使用上方便、稳定,暂时没有出现任何问题,最主要的就是不要什么东西都在 PVE 上跑,用 LXC 快速部署一台 Linux,用完就删,稳定性也非常好,温度表现上也比 ESXI 好太多。
PVE 主界面
至此,PVE 成为了我的主力虚拟化平台,接下来就是 OpenWrt 上令人头疼的 DNS 了。

0x02 DNS

OpenClash 内置分流

OpenClash 写好规则可以达到较为理想的分流效果,但是如果要加入去广告等功能,规则可能达到几万条,这在 PC 平台可能没什么问题,但是我一向习惯于统一管理,手机、路由器等设备都用同一份规则,不仅仅是路由器平台的处理效率低下,而且 iOS 对于 APP 的内存限制非常严格,并且 iOS 平台 stash 的处理性能也十分有限,于是使用了 AdGuardHome

AdGuardHome

流程图:
AdGuardHome 流程图

似乎也很完美,但是不管是只使用 OpenClash 还是搭配 AdGuardHome,在使用过程中发现了两个问题:

1. 国际厂商 DNS 分流

例如 Apple、Microsoft,这两大厂商在大陆有 CDN 但是部分服务只有国外 IP,由于运营商优化了这一点使得不同地区解析到的 IP 虽然是国外的,但基本上是最优的(排除某些地区或某些运营商的垃圾 DNS 和线路)
那就出现了一个问题:
通常 Apple、Microsoft 服务是选直连,但是会触发 FallBack,使得请求变得非常慢,例如:

  • 外区 APP Store/Apple Music 中,部分国区没有的 APP/音乐,大陆的 CDN 中没有此资源,会导致请求变得非常慢,甚至下载失败。
  • iOS 网络检测域名:captive.apple.com,大陆的 CDN 中没有此资源,被 Fallback 到直连很差的 IP,导致网络检测失败,弹窗提示无法连接到互联网,Windows 网络检测域名:www.msftncsi.com 也偶现此问题,但 Azure 线路比较好,出现的概率比 iOS 小很多。

2. 猝不及防的 iOS 16 DNS 安全更新

如果说 OpenClash 启用 绕过中国大陆 IP,再让 Microsoft、Apple 的域名走代理,那么有大陆 CDN 有资源的会直接直连,否则走代理,这样似乎又完美解决了,直到 iOS 16 的正式版发布,Apple 宣布了 DNS 安全更新:

如果您的网络支持发现指定解析器(也称为 DDR ),则 DNS 查询将自动使用 TLS 或 HTTPS。要使用加密的 DNS,您的设备需要知道解析器支持 TLS 或 HTTPS,并且可能还需要学习端口或 URL 路径。诸如 DHCP 或路由器播发等常见机制仅提供普通 IP 地址。DDR 是 Apple 与其他行业合作伙伴在 IETF 中开发的一种新协议。

截止至写本文时(2023-04-09),AdGuardHome 对此支持仍不完善,导致 iOS 16 设备解析缓慢,甚至无法解析,日志中也有一大堆 SERVFAIL,Github 中也有人提出了这个问题,但是官方给出的解决方案与版本更新仍然不完美,即使使用了上面说的 绕过中国大陆 IP & MicrosoftApple 走代理,也会出现 DNS 解析缓慢的问题,并且还带来一个问题,如果节点不稳定或直接挂了,那 iOS 设备直接判断无网,导致频繁弹窗,或触发无线局域网助理功能,这样虽然 Wi-Fi 是已连接的状态,但是实际走的是蜂窝网络。

MosDNS

综上所述,目前看来需要一个这样的 DNS 服务器:

  • 支持国际厂商 DNS 分流
  • 支持 iOS 16 安全 DNS
  • 支持去广告
  • 支持 DNS 缓存

于是找到了 MosDNS,目前来看是最完美的解决方案,它支持 DNS 缓存、DNSSEC、DOH/DOT 等功能,iOS 16 也完美支持,而且还支持域名分流。

微软某些服务会验证返回 IP 真实性(Xbox 居多,例如微软模拟飞行),如果你出现了某些服务无法访问,除了真的可能是连接问题,还有可能是 DNS 验证失败,这时候你可以尝试检查一下你的 DNS 服务器是否支持 EDNS 和 DNSSEC。

流程图:
MosDNS 流程图

对于我来说 MosDNS 内置的配置文件已经非常完善,只需要手动勾选 TCP/DoT 连接复用启用 EDNS 客户端子网 完成功能性问题即可,并且内置了去广告规则,但是目前来看去广告需求不是那么大了,DNS 层只能去广告域名,还有很大一部分网站还是会通过 URL 的方式加载,所以我还是使用了浏览器插件的方式去广告

MosDNS 设置远程 DNS 必须使用 DoT,如果你使用的是 DoH,那么 Bootstrap 最好也使用国外的,因为如果是大陆的 DNS 服务作为 Bootstrap,那么对于节点来说可能并不是最快的 IP,这样会影响本就不快的 Fallback 速度,如果使用的是 DoT,由于不需要被 Bootstrap 解析,所以可以被节点连接查询 IP,在 Clash 控制面板中也能看到 Process 为 MosDNS,对节点来说能拿到最快的 IP。

至此,DNS 的问题已经完美解决

为什么不用 fake-ip?

fake-ip 的优点是可以解决 DNS 污染,但是缺点也很明显,无法解决国际厂商 DNS 分流,导致国际厂商的服务无法直连,而且也无法解决 iOS 16 的 DNS 问题、DNS 不能缓存、BT 下载无法使用、部分游戏无法连接、加速器的节点全是 1ms 等一大堆兼容性问题,当然这些问题都可以通过 fake-ip-filter 解决,但是这样就失去了 fake-ip 的优点,而且维护起来也很麻烦,所以我还是选择了 redir-host 方案。
虽然 Clash 内核移除了 redir-host,但是 OpenClash 作者在 v0.45.87-beta 版本中解决了这个问题:

除 Meta 内核,其他内核的 redir-host 模式均改为使用 fake-ip 进行模拟 (上游内核已移除 redir-host)

所以 OpenClash 还是可以正常使用 redir-host 模式的。

1 + 2 =
10 评论
    FengXLEdge Chromium 114Windows 10 / 11
    2023年07月22日 回复

    大佬,你的这种方案是,openclash作为dnsmasq的上游,然后openclasd的name和fallback设置为mosdns的ip:5335,对么
    我在其他地方有看到,用mosdns作为dnsmasq的上游,然后openclasd的name和fallback设置为mosdns的ip:5335,‘
    这两种方案,到底哪个是最正确的,有点晕了

      FanxSafari 16Mac OS X
      2023年07月24日 回复

      @FengXL 都正确,看你怎么选,mosdns 也有 fallback 判断,我更喜欢让 openclash 判断 fallback 而已

    dayuanpanChrome 113Windows 10 / 11
    2023年05月16日 回复

    大佬请问下,流程图里运营商dns到大陆白名单这一过程是在哪设置,可以实现复核白名单的绕过clash直连,不符合白名单的再通过clash核心,这一块设置是在mosdns还是clash里面,能不能讲下具体设置

      FanxSafari 16Mac OS X
      2023年05月17日 回复

      @dayuanpan 流量控制里:实验性:绕过中国大陆 IP
      IPv6设置里:实验性:绕过中国大陆 IPv6

    hotwillChrome 112Android
    2023年05月02日 回复

    这里:通常 Apple、Microsoft 服务是选直连,但是会触发 FallBack,使得请求变得非常慢
    可以设置Fallback-Filter规则,让Apple、Microsoft不走FallBack,这样是不是就解决了这个问题

      FanxSafari 16iPhone
      2023年05月04日 回复

      @hotwill 这样是可以,但是我懒得去维护一个单独的列表了,对我来说mosdns的匹配方式更灵活 维护更简单方便

    jerryChrome 112Mac OS X
    2023年04月25日 回复

    感谢您的分享,已经按照您的方案设置差不多了,但是OpenClash这块设置太复杂了,您能分享一下您的设置截图打包发给我吗?】
    谢谢!

      FanxSafari 16iPhone
      2023年05月10日 回复

      @jerry ip绕过规则和dns不冲突,Meta内核相关看个人喜好了,我文章里的流程图展示了mosdns与绕过大陆ip和openclash的工作流程

      FanxSafari 16Mac OS X
      2023年04月26日 回复

      @jerry 把 OpenClash 的三个 DNS 只设置为 MosDNS 就好,另外 MosDNS 不启用 DNS 转发,OpenClash 只启用自定义上游 DNS 服务器,追加上游 DNS 和追加默认 DNS 关闭,其它的设置按自己喜好来就好

        jerryChrome 112Mac OS X
        2023年05月01日 回复

        @Fanx 谢谢您!
        openclash是否需要开通Meta 内核?绕过中国大陆 IP(会不会与mosdns冲突)?是否需要开通Fallback-Filter?meta设置中的启用 TCP 并发等?