DNS原理入门

2020-09-01

简介

Domain Name System(域名系统),简称DNS,在域名和ip地址之间建立映射关系,让网民通过简单好记的域名即可访问互联网。


域名

域名是一串用点分隔的字符。点把域名分成若干个部分,从右往左分别是 根域名、顶级域名、子域名等。


域名的构成

以上几部分组成了完整的域名。域名里的英文字母不区分大小写,每一级域名长度限制63个字符,总长度不能超过253个字符。后来出现的中文域名之类,也只是把Unicode字符串映射为有效的DNS字符集,本质上是一样的。


DNS记录

DNS是一个映射数据库,有不同的记录类型。常见的有:

DNS记录类型多达几十种,提供各种各样的功能。


每条DNS记录,除了存有记录类型、主机记录(对应的域名)、记录值(返回的内容),还有一个记录的有效时间TTL(Time To
 Live)。DNS服务器会根据TTL缓存查询到的记录,这样下次再访问的时候,只要缓存没有过期,就直接返回,节省了大量查询的时间。TTL设得大,能提高缓存命中率;设置得小,则修改记录时能更快生效。


域名解析过程

负责查找DNS记录的服务器,即DNS服务器(Domain Name Server)。客户端想上网,必须得先指定一个DNS服务器,每次需要查DNS记录的时候,就去找这台DNS服务器。

从客户端出发,浏览器、客户端操作系统、路由器、DNS服务器等节点,都会对DNS的查询记录进行缓存,一旦命中缓存,直接返回结果。此处只讨论没有命中缓存时,DNS服务器如何完成解析的过程。


储存DNS记录的服务器,被称为“权威域名服务器”。DNS是一个分布式的映射数据库,记录储存在不同的权威域名服务器中,想查找记录,首先得找到权威域名服务器。每一级域名都至少有一条NS记录,指向该级域名的权威域名服务器,储存在上一级域名的权威域名服务器中。DNS服务器从根域名服务器开始查,依次查询每级域名的NS记录,最终找到记录有这个域名DNS记录的权威域名服务器。

举个例子,DNS服务器收到本博客域名blog.oonne.com,解析过程如下:

  1. 找“根域名服务器”(.root),查询“顶级域名服务器”(.com),根域名服务器返回了.com的NS记录,记录了.com权威域名服务器的IP;
  2. 找“顶级域名服务器”(com),查询“次级域名服务器”(.oonne.com),顶级域名服务器返回了.oonne.com的NS记录,记录了oonne.com权威域名服务器的IP;
  3. 找“次级域名服务器”(oonne.com),查询主机名(blog.oonne.com),次级域名服务器里存有blog.oonne.com的A记录,直接返回blog.oonne.com的IP地址。至此拿到结果,查询结束。


整个过程由根域名服务器处开始查询。根域名服务器的IP地址很少变化,一般内置在DNS服务器里面,不需要查。早期的DNS受限于UDP数据包512字节的大小限制,只能容纳最多13个服务器地址,因此就规定全世界有13个根域名服务器,由12个组织独立运营。但其实,为了保证根域名服务器的可用性,每个服务器都会部署很多节点,所以根域名服务器不止13台。可以在这个网站查到根域名服务器的信息: https://root-servers.org


分级查询的实现,又分为递归查询和迭代查询,如下图所示。

DNS查询过程


为什么又使用TCP又使用UDP

DNS会同时占用UDP和TCP的53端口,这种“我全都要”的协议也算是一朵奇葩了。


在绝大多数情况下,DNS使用UDP通信,因为UDP速度快很多。设想一下,用TCP去请求DNS服务器,前后需要三次握手连接、请求和响应、四次挥手断开,共计9个数据包;而用UDP请求只需请求和响应两个数据包,延迟比TCP少了许多。而且UDP协议头内容少,数据包的大小也有优势,传输更快。因此DNS协议设计之初,就推荐优先使用UDP。

不过UDP的数据包有512字节的大小限制,当DNS记录超过512字节时,会被截断。(虽然EDNS机制允许UDP最多传输4096字节,但UDP本身就是不可靠的)。此时根据DNS协议,就会使用TCP进行重试。随着IPv6引入和DNS越来越多的新功能,DNS响应越来越大,TCP三次握手和协议头带来的额外开销就不再那么明显了,反而是可靠传输的优势逐渐体现了出来。


DNS还有一种AXFR类型的特殊查询,叫区传送(zone transfer),用于主域名服务器转移整个区域文件至二级域名服务器。由于数据量大,使用TCP来传输。


DNS劫持

DNS劫持,就是用户DNS解析的时候,返回一个错误的ip,以此骗用户去访问钓鱼网站。


上文提到域名的解析过程,解析的结果要么来源于缓存,要么来源于权威域名服务器。对应的DNS劫持的方式也有两种。一种是污染缓存内容,比如返回给路由器或DNS服务器错误的查询结果,又比如有些病毒直接改host文件,等等。另一种方式则更加过分,入侵权威域名服务器,篡改DNS记录。2010年发生的“史无前例”的百度被黑事件,就是百度域名在美国的注册商,被非法篡改了DNS记录,导致中国网友访问百度都跳转到伊朗网军网站。


防范DNS的思路有以下几种:

  1. HTTPDNS。使用https协议来请求DNS记录,替代原有的TCP和UDP。不仅需要DNS服务器支持,也需要客户端的支持。iOS和Android都有成熟的集成方案,Chrome浏览器也在83以后的版本中内置了 DoH(DNS over https)。
  2. 客户端校验。比如很多杀毒软件都会扫描hosts文件防止被恶意修改,访问网银等重要网站会校验一下DNS响应,防止被劫持。
  3. 给网站设置HSTS。


总结


学习DNS原理,不管是开发还是平时上网,都有许多帮助。



参考文献

  1. https://tools.ietf.org/html/rfc1034
  2. https://tools.ietf.org/html/rfc1035


本文未经许可禁止转载,如需转载关注微信公众号【工程师加一】并留言。