由于IP地址的烦琐导致的记忆和使用困难,互联网支持使用主机名称来识别包括客户机和服务器在内的主机。同时为了使用一系列协议,主机名称通过称为"名称解析"的过程转换成对应IP地址。
互联网中存在各种形式的名称解析,最普遍、最重要的一种采用分布式数据库系统是开发者所熟知的域名系统(DNS,Domain Name System)。之所以因为分布式,是因为互联网中没有一个站点能够知道所有的(主机地址-名称)对信息。每个站点维护自己的信息数据库,并允许一个服务程序供互联网上其他系统查询。DNS提供了允许客户机和服务器相互通信的协议,并且也提供了服务器之间交互信息的协议。
从应用程序角度看,访问DNS是通过一个称为地址解析器的应用程序库来完成的,在请求以"某个名称"作为目的地来打开一个连接或发送数据报之前,应用程序通过地址解析器将"该名称"转换成目的IPv4/IPv6地址。
DNS
DNS是一个分布式的客户机/服务器网络数据库,TCP/IP应用程序使用它来完成主机名称和IP地址之间的(双向)映射,提供电子邮件路由信息、服务命名和其他服务。DNS中使用的所有名称的集合构成了DNS名称空间,名称空间划分为层次且大小写不敏感。当前的DNS名称空间是一棵域名树,位于顶部的树根未命名,树的最高层是所谓的顶级域名(TLD),包括通用顶级域名(gTLD)、国家代码顶级域名(ccTLD)、国际化国家代码顶级域名(IDN ccTLD),以及由于历史原因而存在的一类特殊的称为ARPA的基础设施顶级域名(infrastructure TLD)。
gTLD可分为:通用(这个是网络上开发者们经常会接触的)、通用限制、赞助。通用gTLD是开放的,可无限制地使用。例如EDU用于教育机构、MIL用于美国军事机构、GOV用于政府机构、INT用于国际组织机构、JOBS用于人力资源管理机构、MUSEUM用于博物馆机构、COM/ORG/NET/INFO属于通用等等...
ccTLD包含ISO 3166标准指定的两个字母的国家代码,如cn、au、us、ca、jp、uk、br...
DNS名称树中的TLD下面的名称进一步划分成组,称为子域名。以fanyi.baidu.com为例:自右向左顺序进行结构拆分,com是通用顶级域名,baidu是百度的拼写(网站名称),fanyi是翻译的拼写(网页功能)。每个标签最多可到63个字符长度。DNS名称空间的层次结构允许不同的管理机构管理名称空间的不同部分,如fanyi.baidu.com可能只需要baidu.com子域的拥有者协商即可,DNS的这个特点是它的可扩展性的一个重要方面。
DNS由各个服务器的集合形成,服务器(DNS服务器/名称服务器)用来存储名称空间的相关信息。部分DNS名称空间的管理责任分配给个人或组织,管理者至少安置两台DNS服务器。
在DNS服务器的语言中,管理授权的范围称为区域,一个区域是DNS名称空间的一课子树,它可以独立管理而不受其他区域影响。每个域名都存在于某个区域中,即使是TLD,它也存在于根区域中。结构如下图:
例如图中,假设百度内部自己架构DNS服务器,则也称为一个区域。
前面说到管理者至少安置两台DNS服务器,这样做是为了形成冗余。如果一台服务器不能正常工作,至少另一台服务器可以使用,所有这些服务器都包含一个区域的完全相同的信息。通常情况下,在服务器之间,一台主服务器在磁盘文件中包含区域数据库,一个或多个辅助服务器使用称为区域传输的进程,从主服务器完整地获取该数据库的副本。DNS有一个专用的协议用于执行区域传输,但是区域内容的副本也可以通过其他方式获取。
大部分的DNS服务器(除去一些根服务器和TLD服务器)会缓存它们学习的区域信息(IP地址映射信息),直到该条信息的生存时间(TTL)的时间限制为止。当收到查询请求时,可以使用缓存来做应答,以减少DNS消息在网络中传输的流量损耗。服务器缓存DNS由系统配置决定,可手动启用或禁用。
DNS协议
DNS协议由两个主要部分组成:用于执行对DNS特定名称查询的"查询/响应"协议和名称服务器用于交互数据库记录的协议(区域传输)。DNS支持方法以通知辅助服务器区域数据库已演变,需要进行区域传输(也称DNS通知),也有方法动态更新区域。
来看一次首次DNS查询过程:
步骤解析:
1. 比如,笔记本A.HOME想要访问EXAMPLE.COM网站,由于A.HOME不知道EXAMPLE.COM的IP地址,于是想向本地的DNS服务器GW.HOME发送请求,构成消息1;
2. 如果是首次访问,GW.HOME并不知道EXAMPLE.COM的IP地址,也不知道EXAMPLE.COM域或COM TLD名称服务器,于是它转发查询至另一个DNS服务器(递归),转发至ISP提供的DNS服务器,构成消息2;
3. 假设该NDS服务器也不知道请求的地址及信息,它会联系根名称服务器中的一台,构成消息3;
4. 根服务器不是递归,它不作进一步处理。它返回需要联系的COM TLD名称服务器的信息,如可能返回名称A.GTLD-SERVERS.NET以及一个或多个它的IP地址,构成消息4;
5. ISP提供的服务器联系gTLD服务器,构成消息5;
6. gTLD返回域名EXAMPLE.COM的名称服务器的名称(A.IANA-SERVERS.NET)和IP地址,构成消息6;
7. ISP提供的服务器联系域名正确的服务器,构成消息7;
8. EXAMPLE.COM域名授权的DNS服务器回复请求,构成消息8;
9. 消息经过9-10返回到A.HOME,A.HOME知道了EXAMPLE.COM的IP地址,进行访问(GW.HOME若启用缓存,下一次访问会直接返回访问域名如EXAMPLE.COM的对应的IP地址)。
DNS操作(查询/响应/区域传输/通知和动态更新)的消息格式如下所示:
事务ID字段由客户端设置,由服务器返回,以匹配查询和响应。
QR字段表示请求是查询还是响应,0/1。
OpCode字段是操作码,查询和响应中正常值是0,其他值是4通知、5更新、1~3弃用。
AA字段标识"授权回答",和"缓存回答"相对。
TC字段表示是否是截断的,如使用UDP时,它表示当应答总长度超过512字节时,只返回前512字节。
RD字段表示期望递归,由查询方设置/响应方返回,它告诉服务器执行递归查询。如果字段未被设置,且被请求的DNS服务器没有授权回答,则被请求的DNS服务器返回一个可以联系获取回答的其他DNS服务器列表,全部查询可能通过联系其他DNS服务器完成,这称为迭代查询。
RA字段标识递归可用,由服务器响应设置,如果服务器支持递归查询的话。
Z字段值为0,保留字段。
AD字段表示包含的信息是已授权的。
CD字段标识禁用安全检查。
RCODE字段表示返回结果,如值0没有差错、3名称差错或不存在域名、1格式错误,查询不能被解读、5拒绝,服务器不希望提供回答、10在区域中不包含名称(用于更新)。
DNS消息末尾的可变长度区段包含问题、回答、授权信息和可能减少必要查询次数的额外信息。每个问题和资源记录(RR)以它所涉及的名称开始,每个名称又由一系列标签组成,标签分为数据标签和压缩标签。数据标签包含构成一个标签的两字符;压缩标签充当指向其他标签的指针(有助于节省DNS信息的空间)。
两种类型的标签:
每个数据标签以1字节开始计数,计数指定了紧随其后的字节数目,名称以值为0的字节结束,0也是一个标签,表示标签长度为0。如下:
# www.baidu.com |3|w|w|w|5|b|a|i|d|u|3|c|o|m|0| # 或者 | |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15| |0 | 3 | w | |2 | w | w | |4 | 5 | b | |6 | a | i | |8 | d | u | |10| 3 | c | |12| o | m | |14| 0 |
由于写法可省略根标签,所以"www.baidu.com"其实是由"www.baidu.com."而来。www标签长度为3,baidu标签长度为5,com长度为3,根标签长度为0。
当涉及到多个名称时,一些标签就有可能重复,为了避免这种冗余和节省空间,将已有的标签能出现的任意位置,前面的单一计数字节的2个高位置为1,剩余的位与随后的字节中的位组合形成一个14位的指针(偏移量),因此,压缩标签能够指向距离开始处多达16383字节的位置。如下:
# www.baidu.com fanyi.baidu.com |3|w|w|w|5|b|a|i|d|u|3|c|o|m|0|5|f|a|n|y|i|192|4|192|10|0| # 或者 | |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15| |0 | 3 | w | |2 | w | w | |4 | 5 | b | |6 | a | i | |8 | d | u | |10| 3 | c | |12| o | m | |14| 5 | f | |16| a | n | |18| y | i | |20|1|1| 4(PTR_1) | |24|1|1| 10(PTR_2) | |34| 0 | # PTR_1 计算 # 1100 0000 0000 0100 # PTR_2 计算 # 1100 0000 0000 1010
DNS的一种扩展格式称为EDNSO,它指定了一种特殊类型的RR,被添加到请求或者响应消息中额外的数据区段来表示EDNS0的使用。EDNS0允许DNS超过512字节的长度限制,并可能包含一套扩展的错误代码(4位响应字段RCODE不足以指明差错类型的情况下)。
对于TCP和UDP来说,DNS的知名端口号都是53,常见的格式如下:
当解析器发出一个查询消息,而返回的响应消息TC字段被设置,真实的响应消息长度超过512字节时,服务器只返回512字节,该解析器会使用TCP再次发出请求消息以允许接收更多的消息,这是现在必须被支持的配置[RFC5966]。
问题或者查询字段格式如图所示:
查询名称字段由一系列标签组成。查询类型指明正在执行的查询类型,场景的查询类型值A(如果IPv6的DNS解析,则为AAAA),以为着需要一个与查询名称对应的IP地址。查询类值1为互联网类、254为没有类、255为所有类。
回答、授权和额外信息区段格式如图所示:
名称依然是一系列标签组成,是随后的资源数据对应的域名。类型字段指定为RR类型代码中的一个,RR类型下面有表格会列出。类字段是1。
TTL字段可是RR可以被缓存的秒数;资源数据长度(RDLENGTH)字段指定资源数据(RDATA)字段中包含的字节数;资源数据(RDATA)字段指定数据,数据类型取决于类型。
资源记录类型表:
其中地址(A/AAAA)和NS(名称服务器记录)是DNS中最重要的两点。地址记录IP地址,NS记录包含授权DNS服务器的名称,该服务器包含一个特定区域的信息,该服务器的IP地址也通常作为DNS响应中的额外信息区段中的胶记录(glue record)提供。当授权名称服务器和它们要授权的名称使用相同的域名时,需要这种胶记录来避免循环。
CNAME记录代表规范名称的记录,用于将单一域名的别名引入到DNS命名系统中。
PTR(指针)记录用于响应逆向DNS查询,它以一种特殊的方式使用特殊的in-addr.arpa(或者IPv6的ip6.arpa)域。比如IPv4地址128.32.112.208,为了确定这个地址的名称,首先将该地址逆转,再添加特殊的域,构成208.112.32.128.in-addr.arpa.进行PTR记录的查询。根据[RFC5855],域in-addr-servers.arpa和ip6-servers.arpa分别用于形成与服务器相关的域名,并且该服务器为IPv4和IPv6提供逆向DNS映射。
当组织加入互联网并获得授权来填充部分DNS名称空间时,它们往往也获得与它们互联网上的IPv4地址相对应的部分in-addr.rapa名称空间的授权。[RFC2317]给出了实现的标准方法,添加前缀长度到逆转后的字节组中,并使用它作为域名中的第一个标签。比如假设站点12.17.136.128/25,即包含123个地址的前缀,则为形式为X.136.17.12.in-addr.arpa的每个名称创建一个CNAME RR,可能有站点的ISP维护:
128.136.17.12.in-addr.arpa. canonical name = 128.128/25.136.17.12.in-addr.arpa. 129.136.17.12.in-addr.arpa. canonical name = 129.128/25.136.17.12.in-addr.arpa. ... 255.136.17.12.in-addr.arpa. canonical name = 255.128/25.136.17.12.in-addr.arpa.
DNS中,每个区域有一个授权记录,使用称为授权启动(SOA)的RR类型。它们提供部分DNS名称空间和服务器之间的授权联系,该服务器允许地址和其他信息进行查询以提供区域信息。SOA RR用于识别主机的名称,提供官方永久性数据库、负责方的e-mail地址、区域更新参数和默认TTL。
区域更新参数包括一个序列号、更新时间、重试时间和终止时间。每当要改变区域内容时,序列号通常由网络管理员增加(至少1 )。辅助服务器使用它来确定是否应该启动区域传输(当它们没有序列号最大的区域内容的副本时)。更新时间告诉辅助服务器,在从主服务器检查SOA记录之前需要等待的时间以及它的版本号,以确定是否需要区域传输。重试时间和终止时间是在区域传输失败的情况下使用的。重试时间值给出辅助服务器重试前需要等待的时间(秒)。终止时间是辅助服务器在放弃之前保持重试区域传输的上限(秒)。如果它放弃了,这样的服务器停止响应对该区域的查询。
MX记录提供了邮件交换器的名称,邮件交换器为在简单邮件传输协议中愿意代表与域名相关的用户接收传入电子邮件的主机。MX包含优先级值,因此对于一个特定的域名,多个MX记录可以同时出现。
EDNS0定义了特殊的OPT伪RR。OPT RR 不被缓存、转发或持续存储,该记录位于DNS消息的额外消息区段。
SRV服务记录推广了MX记录的格式,以描述主机、协议和用于连接特定服务的端口号。格式如下:
_Service._Proto.Name TTL IN SRV Prio Weight Port Target # service标识符 服务的正式名称 # TTL 生存时间 # IN 互联网类 # SRV SRV RR 类型 # Prio 16位无符号值,优先级,越小越高 # Weight 在优先级相等时做权值,值越大表明选择概率越大 # Port TCP/UDP端口号 # Target 提供服务的目标主机的域名
DNS的区域传输用于从一个服务器到另一个服务器复制一个区域的一个组RR(主要是从主服务器向从服务器),已达到保持多台服务器的区域内内容同步。区域传输方案如下图:
区域传输在轮询后开启,在轮询中,从服务器周期性的联系主服务器,通过比较区域的版本号以查看区域传输是否为必要的;如果需要开启区域传输,当区域内容改变时使用异步更新机制。这被称为DNS NOTIFY。
区域传输又分为完整区域传输、增量区域传输。使用完整区域传输(AXFR)的DNS消息使用TCP请求一个整个区域内容;使用增量区域传输和IXFR消息类型,只提供区域中的变化(改进了内容同步的效率)。
DNS相关
排序列表、循环和分离DNS
DNS服务器可以返回所有匹配的数据给任何客户端,并以服务器认为最方便的顺序返回。显然对数据而言,这是不安全的。于是DNS服务器允许一些特殊配置选项和行为来构成返回数据的筛选及排序列表,达到一定的操作、隐私和性能目标。DNS服务器也可以配置为使用"DNS循环",这意味着服务器交换返回地址记录的顺序,使的每个新的客户端访问不同的服务器上的服务。为了数据的隐私,可以使用一种称为"分离DNS"的技术,使响应查询的返回的资源记录集合依赖于客户端的身份,并可能查询目的地址。
开放DNS服务器和DynDNS
许多家庭用户由对应ISP分配一个单一的IPv4地址,并且地址随用户的电脑或家庭网关连接、断开和重连而改变。因此,用户往往难以建立一个DNS条目来允许运行的服务对互联网是可见的。一种开放动态DNS服务器可以用来支持特殊的更新协议,称为DNS更新API[DynDNS]。凭此,用户可以根据预先注册或账号在提供商的DNS服务器中更新条目。为了使用这项服务(DynDNS),客户端系统上运行DDNS客户端程序,也可能是在用户的家用路由器上。大多数情况下,这些程序被配置为需要登录信息以用于访问远程DDNS服务。当服务被调用时,客户端程序与服务器联系,提供它的主机的当前全球IP地址,并且变为静态,之后它会定期更新与服务器的信息(允许服务器在某个时间间隔内没有接收到更新时清除信息)。
DNS扩展性
DNS是互联网上最普遍的服务之一,也常作为基础,通过扩展添加新的功能。[RFC5507]为扩展DNS设想了各种方法,最终结论是建立和实现新的RR类型是最有吸引力的办法。[RFC3597]指定将未知RR类型作为不透明的数据来处理,如果不认可就不解释它们。对于未知的RR类型,嵌入的域名不得使用压缩标签且以大小写敏感的方式做比较。
LLMNR和mDNS
当只有少数本地主机希望通信时,配置一组DNS服务器的开销就显的大了。对于这种情况,可以使用一个特殊的DNS本地版本,称为本地链路组播名称解析(LLMNR)[RFC4795]。它是一个由微软开发的基于DNS的(非标准)协议,在本地环境中使用以帮助发现局域网上的设备。
组播DNS(mDNS)是另一种形式的本地类DNS功能,有苹果公司开发。mDNS使用通过本地组播地址携带的DNS消息,使用UDP端口5353,规定特殊的TLD.local用特殊的语义处理。在该TLD中的域名的任何DNS查询被发送到mDNS IPv4地址255.0.0.251或IPv6地址ff02::fb。对于其他域的查询可以随意发送到这些组播地址,允许本地链路服务来响应全局名称的映射就可能引起重大的安全问题了。对此,可以使用DNSSEC(该知识点在第18章介绍)。
LDAP
LDAP为DNS数据的应用提供了更丰富的查询和操作,现为LDAPv3版本[RFC4510]。
LDAP是一种互联网应用层协议,可以根据X.500[X500]数据和服务模型提供对于一般目录的访问,同时也提供了搜索、修改、添加、比较和删除基于用户选择模式的条目的能力。LDAP服务器经常在企业内部用于保留目录信息。
DNS相关攻击
DNS攻击主要有两种形式。第一种涉及DoS攻击,导致DNS服务器过载,使DNS不起作用。第二种是改变资源记录的内容以做服务器伪装,导致访问的地址是其他"错误"地址。
参考:
《TCP IP 详解卷1:协议》