前言
在一些特殊场景下,我们可能会需要一台自己的可控DNS服务器,例如:内网搭建实验环境需要自定义的测试域名,这时只需把测试机的DNS服务器指向可控DNS即可(测试机多的情况下总不能每台测试机上都去改hosts文件吧?);或者直接作为内网设备的local DNS(一来方便随时添加自定义的域名解析,二来也方便为一些被dns污染的"特殊"域名单独添加转发器发往安全的DNS地址进行解析);或者用来作为自己的顶级域名的二级、三级域名的授权DNS服务器等等。当然,很多路由器上的dnsmasq其实也能实现大部分功能,不过我们本着“有困难要上,没有困难创造困难也要上”的精神,还是需要为家庭数据中心搭建一个自己的DNS服务器。
部署bind9
我是采用dockerhub上的eafxx/bind来实现DNS,这其实是通过webmin(基于web的linux系统管理工具,自带了很多功能,也可以算是一个linux面板)上带的bind(9.1.6版本)来实现的,命令如下:
docker run --name bind9 -d --restart=always \
-p 53:53/tcp -p 53:53/udp -p 10000:10000/tcp \
-v /docker/bind9/data:/data \
-e WEBMIN_ENABLED=true \
-e ROOT_PASSWORD=password \
-e WEBMIN_INIT_SSL_ENABLED=false \
-e WEBMIN_INIT_REFERERS=bind.example.com \
-e WEBMIN_INIT_REDIRECT_PORT=443 \
-e TZ=Asia/Shanghai \
eafxx/bind:latest
关键参数解释:
-p 10000:10000
webmin界面的访问端口,大家根据自己的实际情况修改即可。
-e WEBMIN_ENABLED=true
启用webmin访问
-e ROOT_PASSWORD=password
设置登录webmin界面的密码,默认用户名是root
-e WEBMIN_INIT_SSL_ENABLED=false
禁用webmin的ssl访问,因为我是放在反向代理之后,所以需要禁用
-e WEBMIN_INIT_REFERERS=bind.example.com
要配合反向代理使用,需指定反向代理对应的域名,否则无法访问
-e WEBMIN_INIT_REDIRECT_PORT=443
要配合反向代理使用,需要指定反向代理的端口,如果是放在云服务器上且备案后有443端口的,这里就指定443;如果是放在有公网地址的家庭宽带里,这里就指定对应的反向代理的端口即可。
初始化配置
部署完以后使用http://宿主机ip:10000来访问webmin的界面:
在"服务器"–"BIND DNS服务器"下就是bind的配置界面:
接下来我按照在内网部署DNS服务器的场景进行配置:
转发和传输
这就是转发器的配置,一般这里设置你需要的上级DNS服务器地址,例如阿里的DNS地址"223.5.5.5"或者google的地址"8.8.8.8"(需要科学或者魔法):
红框中的选项其实就是对应配置文件option中forward这个参数,"是"表示forward first,代表转发器设置的DNS服务器如果不响应,则DNS服务器自己会去查询;"否"表示forward only,表示转发器设置的DNS服务器不响应,DNS服务器自己也不会去查询,默认为first。
地址和拓扑
设置监听地址及端口:
监听的端口和地址,这里用默认也行,如果要指定不同的端口和地址,可以在"下面的列表"里进行指定,不过端口没事就不要去动了,地址的话,any就是表示任意地址,也可以单独指定某一个接口的IP地址,这里就根据你自己的需要来了。注意右下角的Allow recursive queries from,这里需要选择"列出的",然后在下面的方框里输入你内网的IP段,这等同于bind配置文件中option字段中的:
allow-recursion {
192.168.10.0/24;
};
当然,这里也可以直接填写any,既表示接受所有源IP地址发来的递归查询,最后选择左下角的保存。
杂类选项
这里面有个很关键的选项:
这里是告诉bind是否响应客户端提交的递归查询,默认值是yes,如果是作为内网的local DNS,这个保持默认即可;如果是放在公网云服务器的DNS又仅仅是作为某域的授权DNS,这里就需要改为no;如果放在公网上又需要接受递归查询的,这里改为yes,同时需要添加allow-recursion参数来指定接受递归查询的客户端IP范围(见上节内容 )以及通过recursive-clients参数来指定最大递归查询客户端的并发数量。
DNSSEC Verification
这里主要是2个选项DNSSEC相关的选项:
上图是默认配置,建议改为:
否则可能出现:
server can't find xxx.com: SERVFAIL
的报错。
完成以上配置以后把bind9容器重启一下:
docker restart bind9
以上就完成了bind9的初始化,可以作为内网的local dns来使用了。如果要添加测试域名进行解析,就需要创建对应的区域了:
这里就不多说了,大家搜一下网上的教程即可。
另:直接搭建DNS服务器其实更适合试验环境,如果仅仅需要一个本地的dns转发器,完全不需要使用这么麻烦的方法,只需要使用ADguard home即可实现,并且还能提供DOH、DOT以及过滤广告等功能,具体搭建步骤可以参见文章:docker系列 使用docker基于ADguard home搭建自己的无广告、无污染且支持DOH(DOT)的DNS服务器。
配置公网访问
如果要把管理页面发布到公网上进行访问,大家需要根据实际环境和自己使用的反向代理选择最适合自己的发布方式,可以参考我以前的几篇文章:
1、docker系列 使用docker基于NPM搭建自己的反向代理
2、linux面板系列 配置反向代理并使用非443端口进行发布
3、家庭数据中心系列 通过国内备案云主机白嫖cloudflare实现国外快速访问国内站点
4、家庭数据中心系列 通过无公网IP的家庭宽带白嫖cloudflare实现快速建站(通用)
其中第1,2种方式适合有公网ip却没有合法443端口的环境(家庭宽带、未备案的云主机),需要在url后面加非标端口(如果使用cloudflare建站的不需要加端口,但是需要自定义源站端口,这个可以参考:家庭数据中心系列 通过cloudflare的Origin Rules解决建站有公网IP却没有合法的80、443端口的问题)。第3种方式适合有备案的云主机,第4种方式适合所有环境(包括没有公网IP的环境),也是我建议的方式(不管你的环境有没有公网IP,因为这种方式不需要直接在公网上跑https流量)。