1. 主要内容
不说废话,直接进入正题。先说说本文本文的主要内容,好让你决定是否看下去:
2. DNS是啥关于DNS是啥,想必学过计算机网络的应该都知道,它是Domain Name System的简写,中文翻译过来就是域名系统,是用来将主机名转换为ip的。事实上,除了进行主机名到IP地址的转换外,DNS通常还提供主机名到以下几项的转换服务:
问:为什么会有DNS,或者说为什么要弄出两种方式(主机名和IP地址)来标识一台主机呢?
答:这是因为主机名便于人的记忆,而IP地址便于计算机网络设备的处理,于是需要DNS来做前者到后者的转换。
3. DNS工作原理DNS实际上是由一个分层的DNS服务器实现的分布式数据库和一个让主机能够查询分布式数据库的应用层协议组成。因此,要了解DNS的工作原理,需要从以上两个方便入手。
3.1 DNS的分布式架构先来了解DNS的分布式架构。
DNS服务器根据域名命名空间(domian name space)组织成如下图所示的树形结构(当然,只给出部分DNS服务器,只为显示出DNS服务器的层次结构):
在图中,根节点代表的是根DNS服务器,因特网上共有13台,编号从A到M;根DNS服务器之下的一层被称为顶级DNS服务器;再往下一层被称为权威DNS服务器。
当一个应用要通过DNS来查询某个主机名,比如的ip时,粗略地说,查询过程是这样的:它先与根服务器之一联系,根服务器根据顶级域名com,会响应命名空间为com的顶级域服务器的ip;于是该应用接着向com顶级域服务器发出请求,com顶级域服务器会响应命名空间为google.com的权威DNS服务器的ip地址;最后该应用将请求命名空间为google.com的权威DNS服务器,该权威DNS服务器会响应主机名为的ip。
实际上,除了上图层次结构中所展示的DNS外,还有一类与我们接触更为密切的DNS服务器,它们是本地DNS服务器,我们经常在电脑上配置的DNS服务器通常就是此类。它们一般由某公司,某大学,或某居民区提供,比如Google提供的DNS服务器8.8.8.8;比如常被人诟病的114.114.114.114等。
加入了本地DNS的查询过程跟之前的查询过程基本上是一致的,查询流程如下图所示:
在实际工作中,DNS服务器是带缓存的。即DNS服务器在每次收到DNS请求时,都会先查询自身数据库包括缓存中有无要查询的主机名的ip,若有且没有过期,则直接响应该ip,否则才会按上图流程进行查询;而服务器在每次收到响应信息后,都会将响应信息缓存起来;
3.2 DNS应用层协议 3.2.1 DNS资源记录在介绍DNS层协议之前,先了解一下DNS服务器存储的资源记录(Resource Records,RRs),一条资源记录(RR)记载着一个映射关系。每条RR通常包含如下表所示的一些信息:
字段 含义
NAME 名字
TYPE 类型
CLASS 类
TTL 生存时间
RDLENGTH RDATA所占的字节数
RDATA 数据
NAME和RDATA表示的含义根据TYPE的取值不同而不同,常见的:
TYPE实际上还有其他类型,所有可能的type及其约定的数值表示如下:
TYPE value meaning
A 1 a host address
NS 2 an authoritative name server
MD 3 a mail destination (Obsolete - use MX)
MF 4 a mail forwarder (Obsolete - use MX)
CNAME 5 the canonical name for an alias
SOA 6 marks the start of a zone of authority
MB 7 a mailbox domain name (EXPERIMENTAL)
MG 8 a mail group member (EXPERIMENTAL)
MR 9 a mail rename domain name (EXPERIMENTAL)
NULL 10 a null RR (EXPERIMENTAL)
WKS 11 a well known service description
PTR 12 a domain name pointer
HINFO 13 host information
MINFO 14 mailbox or mail list information
MX 15 mail exchange
TXT 16 text strings
3.2.2 整体及Header部分下面介绍第二个方面,DNS协议。
DNS请求与响应的格式是一致的,其整体分为Header、Question、Answer、Authority、Additional5部分,如下图所示:
Header部分是一定有的,长度固定为12个字节;其余4部分可能有也可能没有,并且长度也不一定,这个在Header部分中有指明。Header的结构如下:
下面说明一下各个字段的含义:
3.2.3 Question部分Question部分的每一个实体的格式如下图所示:
3.2.4 Answer、Authority、Additional部分Answer、Authority、Additional部分格式一致,每部分都由若干实体组成,每个实体即为一条RR,之前有过介绍,格式如下图所示:
DNS协议是工作在应用层的,运输层依赖的是UDP协议。下面尝试使用Python3.6来实现一个简单的DNS服务器。
在此之前先用Wireshark抓一下DNS包,验证一下上面的DNS协议的格式,也便于之后的实现。Wireshark的用法就不做介绍了,相信装好随便点点就知道怎么用了。先打开监听,添加过滤条件,然后用nslookup命令发送一个DNS包,比如我们尝试查询的ip:
nslookup然后可以在Wireshark中看到如下图所示的请求数据包:
响应数据如下图所示:
4. 实现一个简单的DNS服务器下面用Python来实现一个非常简单的DNS服务器。
4.1 代理功能首先,它应该具有最基本的“代理”功能,即我们的DNS服务器在接到DNS请求后,直接将请求转发到某DNS服务器(如114.114.114.114)上,然后再将那台DNS的响应结果返回给DNS客户端: