前言
今天晚上博主突发奇想:既然根域名服务器的存根文件是公开的,那为什么不自建一个呢?使用现有的资源,我们完全可以在短时间内自己搭建一个 DNS 根服务器,并且让你的递归 DNS 使用它。
DNS 解析原理
- 你打开电脑上的浏览器,输入了
https://www.baidu.com/
想要访问网页。此时你的浏览器会将你输入的 URL 中的域名取出,并根据你设置的系统 DNS 请求到域名服务器。 - 域名服务器检查自身缓存是否存在
www.baidu.com.
的记录,如存在则直接返回,如不存在则继续请求下去。 - 域名服务器向根域名服务器发出
query www.baidu.com.
请求,根服务器返回了.com
顶级域名的顶级域名服务器地址a.gtld-servers.net.
。 - 域名服务器向顶级域名服务器发出
query www.baidu.com.
请求,得到baidu.com
的权威域名服务器地址dns.baidu.com
。 - 域名服务器向权威域名服务器发出
query www.baidu.com.
请求,得到www
子域的解析记录。 - 重复以上步骤,直到得到可被用于请求的 IP 地址。并将其存入缓存后返回给客户端。如无记录,则根据域名状态返回错误码。
- 你的浏览器得到了 IP地址,向它发送请求。服务器返回页面。
到上述第六步时,DNS 解析过程就已经完成了。看似复杂,实则只在几十毫秒内。
自建 DNS 根服务器
目前可选的 DNS 服务器程序很多,例如广为人知的PowerDNS
和BIND9
。本文选择了PowerDNS
作为服务器程序。
- 安装 PowerDNS:
apt install pdns-server pdns-backend-mysql
修改它的配置文件,使其支持
BIND
格式的 zone 文件。vim /etc/powerdns/pdns.d/bind.conf
launch=bind bind-config=/etc/powerdns/bind.conf bind-check-interval=60 bind-ignore-broken-records=yes
- 去 IANA 下载 root.zone 文件。
- 对 root.zone 作一些修改:
- 删除所有第 1 列是
.
,并且第 4 列是NS
的行。 在最开头添加以下三行:
. 86400 IN NS root-server.你的域名. root-server.你的域名. 86400 IN A 你的服务器IP
注意:所有的域名后面的
.
不可省略!删除所有第 4 列不是 A,AAAA,SOA,NS 或者 DS 的行(这些记录与 DNSSEC 有关,而我们的更改会破坏 DNSSEC,因此直接删除即可)。
mv root.zone root.zone.bak cat root.zone.bak | awk '{if ($4=="A" || $4=="AAAA" || $4=="SOA" || $4=="NS" || $4=="DS") print $0}' > root.zone
如果有多台服务器要成为根服务器,重复以上步骤几次即可。
新建
/etc/powerdns/bind.conf
文件,添加如下内容。zone "." { type native; file "/etc/powerdns/root.zone"; };
systemctl restart pdns
重启 PowerDNS 服务器。
验证你的成果
- 运行
dig @你服务器 IP
,应当会得到如下回复(其中root-server.omn.cc
是我设置的域名): 运行
dig @你服务器IP www.example.com
,得到如下回复:;; AUTHORITY SECTION:
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
......;; ADDITIONAL SECTION:
m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
m.gtld-servers.net. 172800 IN A 192.55.83.30
l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
l.gtld-servers.net. 172800 IN A 192.41.162.30
......
恭喜!你的根服务器已经搭建好了!
使用你的根服务器来进行递归解析
有了根服务器,接下来就可以配置你的递归 DNS 服务器,让它们使用你自己的根服务器完成解析了。
将你在root.zone
文件里自己添加的两行/三行(如果你有IPV6)内容保存为roots.hint
文件,传到你的递归 DNS 服务器上去。
然后在 PowerDNS Recursor 的配置文件中新加一行:
hint-file=/etc/powerdns/root.hint
如果你开了 DNSSEC 验证,还需要添加一行:
lua-config-file=/etc/powerdns/script.lua
然后在/etc/powerdns/script.lua
中写入:
addNTA(".")
保存后重启 PowerDNS Recursor 即可。