OpenWrt使用Docker搭建国内外分流DNS服务器

2023-09-27 11:43:32 42点赞 369收藏 22评论

为什么要国内外DNS分流

由于不可描述的原因,使用国内DNS服务器解析国外域名时,可能会返回错误的IP地址。

目前有很多种解决方法。

  1. 使用国外DNS服务器

    这个还是会被污染

  2. 使用国外DoH、DoT技术

    基本上无法访问

  3. 通过代理使用国外DNS服务器

    可行,但是

那么,能不能国内域名使用国内的DNS服务器,国外域名使用国外的DNS服务器呢?

答案是可以的,其实网上有多种解决方案,我这里介绍其中一种。


DNS服务器

TechnitiumSoftware的DnsServer是一个由C#编写的开源DNS服务器,支持Windows、Linux系统,有Docker镜像。

你问我为什么选它,我的答案是,因为我会C#OpenWrt使用Docker搭建国内外分流DNS服务器

这个DNS服务器本身是没有分流功能的,但是其支持插件,我为其编写了一个分流插件OpenWrt使用Docker搭建国内外分流DNS服务器

  1. 当检测到域名是的国外的时候(配置的列表),直接用国外的DNS服务器解析

  2. 先使用默认DNS服务器(一般配置国内的几个DNS服务器)解析

  3. 解析出来后,判断IP地址是不是非法的(配置的列表,里面一般是内网网段以及GFW喜欢设置的网络黑洞网段)

  4. 不是非法的,再通过GEO数据库,判断IP地址是不是国内的

  5. 如果是非法的或者不是国内的,再使用国外的DNS服务器解析一遍

可以配置使用代理访问国外DNS服务器,一般都要使用代理OpenWrt使用Docker搭建国内外分流DNS服务器

源码地址:TechnitiumSoftware/DnsServer: Technitium DNS Server (github.com)

插件源码地址:Kation/DnsServer: Technitium DNS Server (github.com)


前置条件

废话不多说,以我家里的网络环境为例,搞它

由于我还不会制作OpenWrt的插件,所以先用Docker来运行DNS服务器

OpenWrt需满足

  1. OpenWrt安装了Docker插件

  2. 安装了内核模块kmod-macvlan


Docker网络配置

如果你的网络启用了IPv6,那么请先到这里,把“IPv6 ULA”前缀记下,一般是OpenWrt自动生成的

OpenWrt使用Docker搭建国内外分流DNS服务器

然后我们进入Docker的网络管理界面,点击“新建

OpenWrt使用Docker搭建国内外分流DNS服务器

网络名称不能重复

驱动器选择“MAC VLAN

基设备选择OpenWrt本地网桥,一般为“br-lan

模式默认保持桥接

子网输入一个新的网段,不能与现有网段重复

网关输入该网段内的一个IP,为本OpenWrt设备的IP地址

IP范围与子网相同即可

如果使用了IPv6网络,则勾选“启用IPv6

IPv6子网,我的IPv6 ULA地址是“fdbf:6008:a32f::/48”,在a32f后,添加一个不重复网段,例如我的239,48掩码改为64,我的例子为“fdbf:6008:a32f:239::/64”,注意冒号不能少也不能多

IPv6网关将/64改为1即可,我的例子为“fdbf:6008:a32f:239::/1

OpenWrt使用Docker搭建国内外分流DNS服务器

OpenWrt网络配置

点击菜单里的接口时,会弹出一个对话框,点击“继续”,此时会看到新增了一个网络“DOCKER_你的Docker网络名称

OpenWrt使用Docker搭建国内外分流DNS服务器

如果没有使用IPv6,则不需要更多配置,跳到下一步骤。

点击编辑新的网络,在IPv6地址栏里填入创建Docker网络时填入的网关地址,点击保存。

OpenWrt使用Docker搭建国内外分流DNS服务器

然后在路由管理界面静态IPv6路由选项卡点击“添加”。

OpenWrt使用Docker搭建国内外分流DNS服务器

接口选择对应生成的Docker接口

目标填入创建Docker网络时的IPv6子网

网关填入创建Docker网络时的IPv6网关

OpenWrt使用Docker搭建国内外分流DNS服务器

保存后,OpenWrt的网络就配置好了


部署DNS服务器

创建数据存储文件夹

在开始部署前,先确定你的OpenWrt数据存储位置

如果你的OpenWrt装有Diskman插件,进入Disk man管理界面,查看挂载点

OpenWrt使用Docker搭建国内外分流DNS服务器

可以看到,我的OpenWrt内有一块nvme固态硬盘,其中有个118G的分区,挂载在路径/mnt/storage

没有Diskman的话,通过ssh或在线终端功能连入OpenWrt,执行lsblk命令

OpenWrt使用Docker搭建国内外分流DNS服务器

同样能看到一个118G的分区,挂载在路径/mnt/storage

通过ssh或在线终端功能连入OpenWrt,执行命令

执行cd /mnt/storage进入挂载点

执行mkdir dnsserver创建数据文件夹

OpenWrt使用Docker搭建国内外分流DNS服务器

使用OpenWrt界面部署,不支持IPV6

在Docker的容器管理界面点击新增

OpenWrt使用Docker搭建国内外分流DNS服务器

容器名称填入不重复的名称,例如dnsserver

Docker镜像填入technitium/dns-server:latest

重启策略选择Always

网络选择上文中新创建的macvlan网络

IPv4地址填写的IP地址必须属于网络子网

环境变量填入TZ=Asia/Shanghai

绑定挂载填入上文创建的数据文件夹路径,加上“:/etc/dns”,我这里为“/mnt/storage/dnsserver:/etc/dns

OpenWrt使用Docker搭建国内外分流DNS服务器

点击提交即可拉取镜像并创建出DNS服务器容器

使用控制台命令部署,支持IPv6

由于OpenWrt的Docker管理界面添加容器时不能指定IPv6地址,所以只能通过ssh或在线终端功能连入OpenWrt,使用命令行执行命令添加容器

--name参数为容器名称

--net参数改为上文新创建的macvlan网络名称

--ip参数改为你的网络子网IP地址

--ip6参数改为你的网络IPv6子网IP地址,不能为网关地址

-v参数中的“/mnt/storage/dnsserver”替换为上文创建的数据文件夹路径

docker run
-d
--name='dnsserver'
--net='app'
-e TZ="Asia/Shanghai"
--restart=always
--ip 192.168.239.1
--ip6 fdbf:6008:a32f:239::2
-v '/mnt/storage/dnsserver':'/etc/dns':'rw'
technitium/dns-server

执行命令即可拉取镜像并创建出DNS服务器容器

容器启动完毕后,你应该能在电脑上ping通IP地址

OpenWrt使用Docker搭建国内外分流DNS服务器

配置DNS服务器

在浏览器内输入容器IP地址,加上端口号5380进入DNS服务器管理界面

OpenWrt使用Docker搭建国内外分流DNS服务器

关闭DNS校验

由于不可描述的原因,取消勾选Enable DNSSEC Validation

OpenWrt使用Docker搭建国内外分流DNS服务器

修改默认DNS服务器

填入几个国内常用的DNS服务器

例如119.28.28.28119.29.29.29223.5.5.5

OpenWrt使用Docker搭建国内外分流DNS服务器

如果你填写了多于2个的DNS服务器地址,那么改一下并发查询数

OpenWrt使用Docker搭建国内外分流DNS服务器

安装分流插件

先到https://github.com/Kation/DnsServer/releases下载最新的插件压缩包

然后到App选项卡点击Install按钮

OpenWrt使用Docker搭建国内外分流DNS服务器

App Name随便填

App Zip File选择刚才下载的压缩包

点击Install进行安装

OpenWrt使用Docker搭建国内外分流DNS服务器

安装好后在列表页点击Config按钮进行配置

OpenWrt使用Docker搭建国内外分流DNS服务器

将内容替换为自己的配置,点击Save保存

OpenWrt使用Docker搭建国内外分流DNS服务器

配置说明

这里可能不是最新的配置说明,最新配置说明请看下载页

重点关注nameServers配置,如果你的代理服务器仅支持常规端口,请只配置Https类型的DNS服务器

proxy配置改为你的代理服务器

什么值得买的JSON展示太丑了,大家去看下载页的示例

测试DNS

配置完毕后,可以在电脑上使用nslookup命令测试DNS服务器工作是否正常

OpenWrt使用Docker搭建国内外分流DNS服务器

可以看到,已经正常返回结果OpenWrt使用Docker搭建国内外分流DNS服务器

使用国内DNS服务器的结果OpenWrt使用Docker搭建国内外分流DNS服务器

OpenWrt使用Docker搭建国内外分流DNS服务器

修改下发的DNS服务器地址

最后一步,修改OpenWrt的接口下发的DNS服务器地址为容器IP地址

如果你不是使用OpenWrt作为DHCP服务器,请自行设置,你应该会的OpenWrt使用Docker搭建国内外分流DNS服务器

在OpenWrt接口修改界面,DHCP选项填入“6,你的容器IP地址

OpenWrt使用Docker搭建国内外分流DNS服务器

如果使用了IPv6,还需要修改IPv6的DNS服务器地址

通告的IPv6 DNS服务器填入容器的IPv6地址

OpenWrt使用Docker搭建国内外分流DNS服务器

好了,到此全部配置完毕,家里的设备都能正常解析DNS地址了OpenWrt使用Docker搭建国内外分流DNS服务器

结语

有人可能要问,既然都有代理了,为什么不用代理提供的DNS服务?比如OpenClash

我这么做当然是有原因的OpenWrt使用Docker搭建国内外分流DNS服务器

OpenClash提供的DNS服务会有点问题,无法指定使用国内的DNS服务器来解析代理服务器地址

指定国外DNS服务器的话,解析代理服务器地址需要连上代理,然而代理服务器地址还没解析出来,就……

而且用OpenClash的DNS解析,国内某些手机APP的DNS解析有时候好慢,非常影响体验,收到来自老婆的“关爱”OpenWrt使用Docker搭建国内外分流DNS服务器

现在用了DNS分流就简单了,OpenClash直接配置本地DNS劫持停用,只干代理的活

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
22评论

  • 精彩
  • 最新
  • 如果能直接openwrt的ipk就好了

    校验提示文案

    提交

    Kation

    作者

    nknk

    [高兴] 等我研究研究看怎么制作ipk

    校验提示文案

    提交
    收起所有回复
  • 大佬我用的华硕里面的魔法插件,老婆反馈联网慢,公众号图片刷不出来,是不是也是dns设置的问题?

    校验提示文案

    提交
    可能是,你这个插件可能dns都代理去解析了,代理服务器不稳定就会卡。你把插件关了应该就不会出现这种问题了

    校验提示文案

    提交
    里面有dns设置,还有smart dns,总共有三种类型,是不是我每个都试试看看哪个好?感觉原理上来说都是国内外dns分流

    校验提示文案

    提交
    还有3条回复
    收起所有回复
  • SmartDNS

    校验提示文案

    提交
    那个不能按照ip来分流,只能自己配置域名,不够用 [高兴]

    校验提示文案

    提交
    能说的通俗一点么

    校验提示文案

    提交
    还有2条回复
    收起所有回复
  • mosdns飘过……

    校验提示文案

    提交
  • 学习了,有机会测试一下!

    校验提示文案

    提交
  • 用mosdns

    校验提示文案

    提交
  • dietpi下的unbound飘过

    校验提示文案

    提交
  • 我最近也遇到这个恼人的问题。之前我都是虚拟机爱快+op,设置好网关,不出国的就走爱快,出国的走OP,但是最近换了个硬件,性能不能稳定跑爱快+op就做硬op.就出这个问题了。我最后在clash里面设置了跳过某些固定ip才让家里息怒。你这个好复杂,我收藏了,但暂时没有这样改的动力。

    校验提示文案

    提交
    如果硬件太老那性能不行,因为你爱快又加op几层nat转发了又还虚拟机,推荐直接装op就行了

    校验提示文案

    提交
    我现在用的n4100 ,之前几个有名的up吹了一波,单路由器系统的确够用了。但虚拟机不行。说的挺中肯的。但是我之前用j4125做的虚拟机的,比现在单系统来说比较简单实用。回头双11买一台n100吧。

    校验提示文案

    提交
    收起所有回复
  • 给技术佬点赞,但是。。。有mosdns。。。

    校验提示文案

    提交
  • 我有一个C++版的,轻量级,一直没有开源

    校验提示文案

    提交
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
369
扫一下,分享更方便,购买更轻松