阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

自己搭建递归DNS服务器

179次阅读
没有评论

共计 2345 个字符,预计需要花费 6 分钟才能阅读完成。

一般情况下,当我们连接到一个陌生的网络环境时,我们会委托由 DHCP 告知的 DNS 服务器来做域名解析的工作。但在我看来,这样的做法有着很大的安全隐患。

使用他人提供的 DNS 服务器,意味着你查询得到的结果是服务器管理员想要给你的结果。由于权威 DNS 的作用就是给原本没有域名的主机赋予域名(详情可查阅维基百科),因此在一般情况下,相信权威 DNS 的解析结果并不会有什么问题,除非权威 DNS 的管理员中出了叛徒:-)

然而非权威 DNS 就不一样了:它们的作用并不是为主机赋予域名,而仅仅是解析由客户端发来的域名,并给出结果。最常见的非权威 DNS 是递归 DNS,它按如下方式工作:

比如你打算向一个递归 DNS 查询 www.linuxidc.com 的 IP 地址,而该递归 DNS 尚未缓存相关的所有地址,则递归 DNS 首先会向根权威 DNS 查询负责所有.com 域名的权威 DNS 的地址,然后向该权威 DNS(暂名为 A)查询负责 linuxidc.com 的下一级权威 DNS——B 的地址,最后向 B 查询 www.linuxidc.com 的地址,将得到的地址返回给客户端。可以看到,这是一个 递归 式的过程,我们可以使用 BIND 附带的 DNS 调试工具 dig$ dig +trace <domain-name>的命令来观测这一过程。

但有些非权威 DNS 完全可能将服务器管理员设置的另一个地址返回给你,从而达到一些不可告人的目的。其效果和 DNS 劫持有几分相似,然而在这种攻击场景中并没有人篡改在网络中传输的 DNS 数据包,而是你使用的 DNS 返回的信息本身就是有问题的。

即使你直接使用的非权威 DNS 没有包藏祸心,权威 DNS 返回给它的查询结果仍然有可能被篡改。尽管 DNSSEC 提供了基于数字签名的机制来防止篡改,但我们仍然无法知道我们使用的非权威 DNS 是否使用了 DNSSEC。

安全是不能托付给别人的。以上现实情况都指向一个解决方案:在自己的每一台计算机上搭建一个可以做递归查询的非权威 DNS 服务器,然后让这台计算机上的 DNS 客户端只使用它来做 DNS 查询。

这样的自由软件主要有 Unbound 和 BIND,我使用的是历史最悠久的 DNS 服务器软件——BIND。

BIND 的默认配置就是一个递归 DNS 服务器,最新版的 BIND 还自带了 DNSSEC 的支持。这意味着当你打算解析一个途经的各级权威 DNS 都部署了 DNSSEC 的域名(比如台湾地区的域名)时,任何篡改手段都会失去作用,并且只要篡改者无法阻挡真正的查询结果到达,你就总能得到正确的结果。

然而 DNSSEC 尚未完全普及,实际情况常常是最后一级权威 DNS(即最终给出你打算解析的域名对应 IP 地址的权威 DNS)没有 DNSSEC 支持,这样最顽固的 DNS 缓存投毒攻击仍然会污染我们的递归 DNS 服务器的缓存。但如果我们知道某些非权威 DNS,向它们查询某些 特定的 被污染域名总能给出正确的结果,我们还可以利用 BIND 的 DNS zone 功能(很可惜 unbound 似乎无此功能),让它遇到这些域名时转到这些防污染 DNS 上解析。

BIND 的主配置文件 named.conf 一般会用 include 语句拆分成几个子配置文件分别管理。我们可以增加一个子配置文件专门配置 zone,如

  1. include "/etc/bind/named.conf.zones";

然后在这个子配置文件中写入转发规则:

  1. zone "domain.example.com"{
  2. type forward;
  3. forwarders { ipaddr-of-server0; ipaddr-of-server1;...};
  4. };

当然,子配置文件还可以使用 include 语句进一步拆分。更高级的用法可以参考 BIND 的 man pages。

这样一来,绝大部分域名仍然倚靠部署在本机的非权威 DNS 进行带缓存的递归查询,避开了不可信的、由他人提供的、参数不明的非权威 DNS;而少数污染严重的域名则转交给 相应的 防污染 DNS 解析,这些指向特定防污染 DNS 的 zone 可以随发现随添加。综合这两种方法可以抵挡常见的大部分与 DNS 相关的攻击。

如果你改写了 BIND 的配置文件,建议使用 named-checkconf 和 named-checkzone 检查其语法。需要重新启动 BIND 使配置生效。注意:这些操作一般都需要 root 权限。

安装 BIND 并用 dig 测试,确认它能正常工作后,在你的 dhclient.conf(位置可能与发行版有关)中添加一行:

  1. prepend domain-name-servers 127.0.0.1;

或把这些文字前面的注释符号去掉。重新连接网络之后 /etc/resolv.conf 文件会被更新,机器上的客户端就会根据其中的信息使用监听于本机 53 端口的 DNS 服务器做 DNS 查询,DHCP 给出的 DNS 将被屏蔽掉。

屏蔽 DHCP 给出的 DNS 是负责更新 resolv.conf 的 resolvconf 程序的默认配置 TRUNCATE_NAMESERVER_LIST_AFTER_LOOPBACK_ADDRESS 的功能。如果你需要 DHCP 给出的 DNS,可以在 /etc/default/resolvconf(位置可能与发行版有关)中将其设置为 no 来关闭这一保护,但因前文所述理由这样做会有安全隐患,笔者不推荐关闭这一功能。如果需要对付某些公共无线局域网热点的注册流程,可以将 DHCP 给出的 DNS 信息手动写入 resolv.conf,注册成功后再去掉;笔者也在研究更安全的对付注册流程的方法。当然笔者曾见过某些特别恶劣的公共无线局域网热点,其中不指向 DHCP 提供的 DNS 的所有查询都会被屏蔽,遇到这种流氓热点你唯一能做的就是躲着走了。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-12/126549.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-21发表,共计2345字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中