使用dnsmasq搭建局域网DNS解析服务

dns 服务是啥呢,全名 Domain Name System ,互联网通信中一般都是使用ip地址进行通信,但是毫无规律的数字很难记,而且服务器可能会更换,随之而来的就是ip也会发生变动,在此之上抽象出了域名这么一层东西。虽然说现在的dns还广泛应用于负载均衡等用途,不过起源还是用来做域名-ip的转换的。

Why

那么,跟我们有啥关系呢?一般来说,用默认的就行,不过我们可能还需要其他一些特殊用途呢?比如说抵抗运营商dns污染,比如说去广告,再比如说内外网区分解析,再比如dns缓存,等等等等。

How

这篇文章的重点不是介绍有啥用途啦,毕竟这不是一篇种草文,也没人给我广告费。。。

dnsmasq

今天的主角是 dnsmasq ,搭建软路由的童鞋应该很熟悉了。除了可以用作前面提到的dns解析服务,它还有一个很重要的功能就是提供ip分配,即dhcp服务,不过本文重点是在自建dns,dhcp服务还是交给专业的路由器来做比较稳定。

安装很容易啊,不管什么平台,一句命令就能装上。

sudo apt install -y dnsmasq

不过大鱼自动接触到docker之后,就跟着了魔似的,什么都想装在容器里,这不,dnsmasq也想部署在容器里面。找了一圈,没有官方镜像,本着安全的原则,自己写了一个,也很简单。基础镜像依旧是用alpine,尽可能小一点。最后一行表示让dnsmasq在前台运行,不然容器就直接退出了。

FROM alpine:3.10

RUN apk add --no-cache dnsmasq

CMD ["/usr/sbin/dnsmasq", "-k"]

Dockerfile地址在 这里

当然了,不是让大家都自己去做镜像,这里直接用现成的就可以。

运行

首先创建一个空的 /data/dnsmasq/ 目录,后续再介绍如何配置。

docker run \
	--name dnsmasq \
	-d \
	--restart always \
	--cap-add=NET_ADMIN \
	--publish 53:53/udp \
	--net host \
	--mount type=bind,src=/data/dnsmasq/,dst=/etc/dnsmasq.d/ \
	newnius/dnsmasq

这里有一个 cap-add 参数,其实非常不喜欢给容器特殊权限,找了其他人的镜像,很少有消去这个权限的,而且贼复杂。。。这个权限只有dhcp的时候才需要,dnsmasq强制检查了,比较烦,勉强接受吧。然后别忘了暴露53端口,协议是udp。

这里需要注意一下,我加了 --net host 这个参数,让容器运行在宿主机相同的网络上,之前没有的时候,外部服务没问题,但是本机其他容器里面域名解析会不正常,你说咯哦酷派显示 nslookup: can't resolve '(null)': Name does not resolve 。用dig排查了一下,发现是因为请求的ip和返回的ip地址不一致,没有通过验证,会显示以下错误。

/ # dig @192.168.0.3 blog.newnius.com
;; reply from unexpected source: 172.17.0.1#53, expected 192.168.0.3#53
;; reply from unexpected source: 172.17.0.1#53, expected 192.168.0.3#53
;; reply from unexpected source: 172.17.0.1#53, expected 192.168.0.3#53

加上 --host net 解决了这个网络问题,发现其他镜像都没有提到过这个问题。

可以用 dig @192.168.0.3 blog.newnius.com 命令来检查服务是否启动成功,这里就实现了一个简单的dns服务。

配置

默认的配置下,没有自定义的解析,所有解析都会走上游dns服务器。这里我们可以自己修改一下。

默认的配置文件在容器的 /etc/dnsmasq.conf 位置,或者也可以 在这里找到默认的配置文件

这里需要需要修改的有这么几处:

配置上游dns,我们要做的毕竟只是修改部分记录,对于其他的,就交给上游dns服务商来处理好了。

默认情况下,dnsmasq会从 /etc/resolv.conf 文件读取上游dns,这里我们可以自己来换成其他的。在宿主机 /data/dnsmasq/ 目录创建一个名为 global.conf 的文件用来覆盖默认配置。加上 no-resolv 这行,表示不要读取 /etc/resolv.conf 文件。为啥不是修改成其他路径呢?因为这样可以少挂载一个文件夹:smile:,把配置都放在 /data/dnsmasq/ 目录就好了,另外就是 /etc/resolv.conf 是自动生成的,如果路由器上配置了这个地址,自己的上游还是自己,会出现问题。再写上自定义的上游dns,这里可以写公共的dns服务商,但是为了速度起见,推荐使用当前网络分配的,可以看看当前宿主机的 /etc/resolv.conf 文件。

# global.conf

# 不要解析 /etc/resolv.conf
no-resolv

# 缓存的记录数,默认是150,调大一点,免得每次都要花时间重新询问
cache-size=1500

# 这个可以配置多个上游服务器
server=114.114.114.114

# 表示同时查询上游dns,哪个先返回就用哪一个
all-servers

配置自定义的记录

这里只是作为参考,比如说我们想要在dns层面做广告过滤,只需要把他们的广告域名改成 127.0.0.1 就可以了。比如说要屏蔽google的广告,新建一个文件

# ads_block.conf

address=/doubleclick.net/127.0.0.1

重启docker容器即可生效(似乎dnsmasq也会自己监听文件的变化)。

docker restart dnsmasq

配置路由器下dhcp默认dns

自建dns到以上就结束了,不过需要自己指定才会用山,如果希望连入路由器的设备自动使用这个dns的话,就需要在路由器上进行配置。

找到 DHCP 服务器设置页面,然后首选和备选dns都改成dns服务所在的ip地址。大鱼用的是tp-link路由器,其他路由器可以在类似的地方找到。其他设备重新连入时就会使用自己的dns服务了。

有一点需要注意一下,可能有多个地方配置dns,之前是在首页配置的,提示不能跟路由器子网相同,感觉挺奇怪的,不知道它那个地方的dns是用在什么地方。。。

本文主要是介绍如何部署,更加详细的广告过滤等配置或许以后再更新。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章