1、DNS系统

 
DNS是英文Domain Name System(域名系统)的缩写,它是一种可以将域名和IP地址相互映射的以层次结构分布的数据库系统,为互联网的运行提供关键性的基础服务。各种基于域名的Web访问,email系统、文件共享系统等都依靠DNS服务得以正常实现。DNS系统采用备份技术和缓存技术保证了数据库运行的可靠性和服务速率。
2、DNS服务原理
DNS系统采用递归查询请求的方式来响应用户的查询。
 

 
1)用户向DNS 客户端发送DNS请求,客户端先查看本地缓存,如果缓存中有该域名,则直接返回给用户;客户端若没有域名的相关缓存,则向本地域名服务器提出解析请求。
2)本地域名服务器在收到请求后,先查看缓存,若缓存中有相关记录,则应答客户端的请求;否则,本地域名服务器直接向根域名服务器提出请求。
3)根域名服务器接到请求后,将包含有所需解释的域名的顶级域名服务器返回给本地域名服务器。
4)本地域名服务器根据根域名服务器的返回结果,向顶级域名服务器发送请求。
5)顶级域名服务器接到请求后,将包含所查询的域名的域名服务器返回给本地域名服务器。
6)本地域名服务器根据返回结果连接包含域名的域名服务器,得到查询结果,
然后将查询结果缓存,并向客户端应答。
7)客户端接到应答后,将查询结果缓存,然后向用户应答。
 
 

 
DNS的安全威胁主要可分为几种:DNS欺骗、分布式拒绝服务***、DNS软件漏洞***、管理缺陷等。下面分别对这几类***进行介绍。
DNS协议的相关数据结构
DNS数据报:
typedef struct dns
{
 unsigned short id;
 //标识,通过它客户端可以将DNS的请求与应答相匹配;
 unsigned short flags;
 //标志:[QR | opcode | AA| TC| RD| RA | zero | rcode ]
 unsigned short quests;
 //问题数目;
 unsigned short answers;
 //资源记录数目;
 unsigned short author;
 //授权资源记录数目;
 unsigned short addition;
 //额外资源记录数目;
}DNS,*PDNS;
在16位的标志中:QR位判断是查询/响应报文,opcode区别查询类型,AA判断是否为授权回答,TC判断是否可截断,RD判断是否期望递归查询,RA判断是否为可用递归,zero必须为0,rcode为返回码字段。
DNS查询数据报:
typedef struct query
{
 unsinged char *name;
 //查询的域名,这是一个大小在0到63之间的字符串;
 unsigned short type;
 //查询类型,大约有20个不同的类型
 unsigned short classes;
 //查询类,通常是A类既查询IP地址。
}QUERY,*PQUERY;
DNS响应数据报:
typedef struct response
{
 unsigned short name;
 //查询的域名
 unsigned short type;
 //查询类型
 unsigned short classes;
 //类型码
 unsigned int  ttl;
 //生存时间
 unsigned short length;
 //资源数据长度
 unsigned int  addr;
 //资源数据
}RESPONSE,*PRESPONSE;
1、DNS欺骗
我们可以看到,在DNS数据报头部的id(标识)是用来匹配响应和请求数据报的。现在,让我们来看看域名解析的整个过程。客户端首先以特定的标识向DNS服务器发送域名查询数据报,在DNS服务器查询之后以相同的ID号给客户端发送域名响应数据报。这时客户端会将收到的DNS响应数据报的ID和自己发送的查询数据报ID相比较,如果匹配则表明接收到的正是自己等待的数据报,如果不匹配则丢弃之。
  假如我们能够伪装DNS服务器提前向客户端发送响应数据报,那么客户端的DNS缓存里域名所对应的IP就是我们自定义的IP了,同时客户端也就被带到了我们希望的网站。条件只有一个,那就是我们发送的ID匹配的DSN响应数据报在DNS服务器发送的响应数据报之前到达客户端。下图清楚的展现了DNS ID欺骗的过程:
Client <--response--| . . . . . .. . . . . . . . . . DNS Server
          |<--[a.b.c == 112.112.112.112]-- Your Computer
到此,我想大家都知道了DNS ID欺骗的实质了,那么如何才能实现呢?这要分两种情况:
  1. 本地主机与DNS服务器,本地主机与客户端主机均不在同一个局域网内,方法有以下几种:向客户端主机随机发送大量DNS响应数据报,命中率很低;向DNS服务器发起拒绝服务***,太粗鲁;BIND漏洞,使用范围比较窄。
  2. 本地主机至少与DNS服务器或客户端主机中的某一台处在同一个局域网内:我们可以通过ARP欺骗来实现可靠而稳定的DNS ID欺骗,下面我们将详细讨论这种情况。
1、DNS ID欺骗
DNS ID欺骗中的***者必须跟用户处于同一个局域网内。
 

***流程:
1)Arp欺骗。欺骗者向用户发送伪造的arp应答报文,更新用户本地的arp缓存,使用户认为欺骗者为网关。这样,在用户向本地DNS服务器发送请求时,数据的流向就改为用户—欺骗者—网关—本地DNS服务器。欺骗者通过sniffer软件,嗅探到DNS请求包的ID和端口号。
2)欺骗者利用得到的ID和端口号,优先向用户发送伪造DNS应答,用户在对ID和端口号进行核对后认为是正确的应答。此时用户访问的域名已经被替换为欺骗者伪造的IP。
3)本地DNS服务器发送的真的DNS应答包因为晚于伪造包,用户收到后丢弃。至此,DNS ID欺骗***完成。
2、DNS缓存中毒
在介绍***原理和过程之前首先来介绍一下 DNS 工作的过程。DNS 被设计成客户 - 服务器应用程序,需要把地址映射为名字或把名字映射为地址的主机需要调用 DNS 解析程序,向最近的 DNS 服务器发出查询请求,此时,DNS 服务器可以有两种方式来响应客户的请求,一种叫递归解析,另一种叫迭代解析。DNS 缓存中毒***主要是针对递归解析方式工作并缓存非本域的解析结果的 DNS 服务器。
  当***者与用户不是处于同一个局域网时,***者无法得到DNS请求报文的ID与端口号,“生日***”就是在这种情况下的对DNS缓存的一种***方式。
 

(1)应用程序需要解析一个域名时,会向本机上的 DNS客户端--解析程序发起域名解析的请求,解析程序收到应用程序的请求后会代表应用程序向首选 DNS 服务器 DNS1 发起
域名解析请求;
(2)DNS1 收到解析请求后会去查询自己的管辖域,如果请求的是自己管辖域的域名就会直接将查询结果返回给解析程序,进而传递给应用程序,如果不在 DNS1 的管辖域内,
DNS1 就向它的上级服务器 DNS2 发起解析请求,等待 DNS2的查询结果;
(3)如果 DNS2 解析不了,就会告诉 DNS1,我解析不了,但是我知道 DNS3 可能会知道,你去问问 DNS3 看看;
(4)DNS1 就会给 DNS3 发出解析请求,等到 DNS3 的查询结果;
(5)如果 DNS3 可以解析,那么就告诉 DNS1 解析结果,如果 DNS3 也解析不了,那么 DNS3 也会像 DNS2 那样,告诉DNS 它所知道的某个 DNS 可能会知道;
(6)最后,DNS1 又向 DNS4 发出查询请求,等待查询结果;
(7)DNS4 可以解析该域名,就发送一个相应包给 DNS1解析结果;
(8)DNS1收到解析结果后就会将结果发送给客户端的解析程序,并将解析结果保存在自己的缓存中,以便以后再有请求解析该域名时,就可以直接从缓存中得到解析的结果,
提高效率。至此,整个解析过程就结束了。
DNS 服务器不是收到的任何 DNS 响应数据包都会接受的,它会解码数据包,检查数据包是否符合接受的标准,那DNS 服务器检查数据包中的哪些数据来判断该数据包是不是它所希望的包呢?
(1)响应数据包中目的端口
在 DNS 服务器发出的查询请求包中包含了它的 UDP 端口号,对方收到该数据包后返回的响应数据包中的目的端口号就应该为 DNS 服务器发出包的源 UDP 端口号,如果收到数据包中的目的端口号不对,就说明不是对 DNS 服务器发出的请求的响应,因此,网络协议栈就会直接丢弃该数据包,而不会将数据包传递到 DNS 服务器。
(2)响应数据包中的问题域
当给某个查询请求数据包发回响应数据包时,DNS 服务器会拷贝请求数据包中的问题域,因此 DNS 服务器收到响应数据包后就可以通过检查问题域是否与发出的查询包中的问题域是否一致来判断响应数据包的合法性。举个例子,DNS1 向 DNS2发出问题域是 www.nsfocus.com 的请求数据包,询问 www.nsfocus.com 的IP地址,DNS1不能将问题域为www.baidu.com 的响应数据包中的地址做为查询域名为www.nsfocus.com的地址的回答。当出现这样的情况服务器就会丢弃该数据包。
(3)响应数据包中的查询 ID(TID)
DNS 服务器没发出一个查询请求都会分配对应的一个查询 ID 号,在内部对应是某一个域名查询请求,在 DNS 服务器内部区分不同的查询就要 TID 号,如果 DNS 服务器收到的响应数据包中的 TID 号不在 DNS 服务器等待响应数据的 TID中,就表示 DNS 服务器收到的响应数据包不是回答自己发出的查询请求的,服务器就会丢弃该数据包。
(4)响应数据包中的授权域和附加域
授权域和附加域中的域名必须和问题域中的域名是同属于某个域名下的子域名。
如果上述所有条件都满足了,DNS 域名服务器就会接受该响应数据包是对它发出的某个查询请求的响应,使用相应数据包中的数据,并缓存结果。
如果某个***者可以预测和伪造响应数据包,他就可以对 DNS 服务器发起缓存中毒***了。由于 DNS 服务器发送的数据包中的 TID 只有 16 位,而且大部分的 DNS 实现发出的请求中的源端口都是固定不变的。因此,***者就可以伪造DNS 响应包,DNS 服务器在收到响应包后就会将解析结果保存在自己的缓存中,进而实现了缓存中毒***。值得注意的是当 DNS 服务器收到了不是它所希望的的数据包时,它就会简单的丢弃数据包,因此,***者就不必每次都需要猜对所有的数据,可以发送许多包猜测一些关键的
参数。
由于 DNS 服务器发出的请求包中的源端口都是固定的,因此,***者就可以向***目标发送一个精心构造的域名请求,通过上述的递归解析,最终***目标就会向***者控制
的 DNS 服务器发出查询请求,此时,***者就可以通过抓包来得到***目标发出查询请求时所用的 UDP 端口是多少。接下来就是猜测目标 DNS 服务器查询包中的 TID 了。由于一些DNS 实现使用了简单的 TID 生成算法,如,简单的加一,这样就可以预测 DNS 服务器下一个查询请求会使用的 TID 了,***者就可以向目标服务器发送大量的带预测 TID 的请求响应包来命中目标服务器的查询请求,在目标服务器接收了伪造的响应包后,就会将伪造包中的响应数据存储在自己的缓存中,到此 DNS 缓存中毒就算成功了。
***流程如下:
1、  ***者向DNS服务器发送一定数量的DNS请求包,请求的DNS选择该DNS服务器解析不了的,这样的情况下,DNS服务器会向上层DNS服务器发出相同数量的请求。
2、  ***者快速向DNS服务器发送一定数量的伪造的DNS应答包,其中ID和端口号为随机的,当ID和端口号与正确的相碰撞时,缓存***成功。DNS服务器将错误的DNS解析项缓存,这样,所有DNS请求都将导向***者伪造的IP地址。
“生日悖论”的数学模型可以证明,一次成功的***所需发送伪造包的数量并不多,即是说“生日***”是易于发动,也易于成功的。
2、分布式拒绝服务***
DNS放大***的基本原理
DNS 放大***是一种新型的拒绝服务***,***者利用僵尸网络中大量的被控主机,伪装成被***主机,在特定的时间点上,连续向多个允许递归查询的 DNS 服务器发送大量
的 DNS 查询请求,迫使其提供应答服务,经 DNS 服务器放大后的大量应答数据发送到被***主机,形成***流量,导致其无法提供正常服务甚至瘫痪。
如图 2 所示,要实现这种***,***者首先要找到支持递归查询的第三方 DNS 服务器并向其发送一个查询请求,这台DNS 服务器随后会把这个查询按照递归的原则发送给其他 DNS服务器。之后***者会向这些服务器发送一个 DNS 记录查询,在这些 DNS 服务器上存储一个文本记录用于进行放大***,接着***者会以被***者的 IP 地址向这些服务器发送带有 EDNS选项的 DNS 查询信息,这些第三方 DNS 服务器会使用经过放大的文本进行回复,用大量的 UDP 数据包淹没被***者。
2.3 DNS放大***的特点
2.3.1充分利用DNS服务器的特性
DNS 自身的特性决定了它可以被利用作为“***放大器”进行 DDOS ***。一是 DNS 协议自身的弱点导致 DNS 查询请求报文及查询应答报文均可被伪造,网络***者可以通过构造虚假的源地址伪装成被***主机向 DNS 服务器发送 DNS查询请求,同时还可以隐藏***者的身份 ;二是 DNS 服务器对 DNS 查询请求是“有求必应”,并且无法判断一个 DNS 查询请求是否为恶意*** ;三是 DNS 服务器解析域名时,应答报文比查询报文要大,可以实现放大***的效果。
2.3.2 ***流量大
2005 年之前,***者能够向 DNS 服务器发出 60 个字节的查询信息,收到 512 个字节的回应信息,使通讯量放大 8.5倍。随着对 DNS 协议的深入研究,***者发现利用具有递归
查询功能的 DNS 服务器可以把 DNS 回应数据放大到 66 倍 [2] 。如果数以万计的计算机,伪装成被***主机同时向 DNS 服务器连续发送大量的 DNS 请求数据包,由 DNS 服务器返回的应答数据流量成倍放大,甚至能够超过每秒钟 100GB,这对被***主机来说是致命的***行为。
2.3.3 可以依靠僵尸网络发动***
互联网中存在着大量的僵尸网络,为实施 DNS 放大***提供了便利条件。网络***者可以利用僵尸网络中大量的被控主机,在特定的时间点上,连续向 DNS 服务器发送大量的请求引发 DNS 解析过程,可以形成极大的***流量,同时具有极强的隐蔽性。
***者通过控制的“僵尸网络”(成百上千的被控主机群)向目标DNS服务器发送DNS查询请求,从而导致目标DNS服务器过载以及网络线路堵塞。从而形成分布式拒绝服务***。
著名的“ 暴风影音DNS***”事件就是分布式拒绝服务***的一个实例。
3、软件漏洞***
1、  DoS(Deny of Service)***
利用DNS软件的漏洞,如9.2.0版本以前的BIND,向正在运行的BIND设备发送特定的DNS数据包请求,BIND会自动关闭,用户的请求将无法得到DNS服务器的任何应答,用户也将无法访问互联网,从而形成DoS***。
2、  缓冲区溢出***
利用DNS软件对输入的请求字符串不做做严格的检查的安全漏洞,***者构造特殊的数据包***DNS服务器,以期造成DNS软件的缓冲区溢出,在溢出成功后,通过执行特殊的代码获得高级的权限,从而得到DNS服务器的控制权。
4、管理缺陷
DNS现有的管理、配置以及安全机制的规划都非常有限,甚至还很初级。例如目前全球DNS系统仍然主要依赖多点镜像、负载均衡等方法来应对流量突发访问以及遭受DDOS***时保持正常运转。另外对DNS的管理和配置以及安全防护也主要依赖管理者的实际经验。
作为互联网关键基础设施的DNS,目前仍然存在4个方面的主要问题:
技术方面:RFC1035规定DNS协议基于UDP,最长只能是512字节,全球最多只能有13台根服务器,IP分片难以处理,DNSSEC和IPv6也难以支持等。解决的方案提出了两个,一是虽然做了ENDS0的扩展但实际应用的很少,二是鼓励基于TCP的DNS但可能会带来更大的问题。其他的问题还有缓冲区投毒,无法知道非法的gTLD( 通用顶级域)和 ccTLD而导致的根服务器污染,UDP的欺骗***,DNSSEC中的根密钥管理和更新问题等,与IPv6共存时DNS串行解析增加的新延迟,利用相似字符进行网络钓鱼等。
实现方面:常用的名字服务器软件(BIND和Windows)历史上有一些可以被利用的安全漏洞,可用来做投毒、中间人***和DOS***等,尤其是在递归解析时。另外,由于无效TLD、重复解析和源地址错误(如RFC1918)等,根服务器上75%-98%的流量实际上是没必要的,缺少缓存、UDP缺乏循环监测机制和anycast以及超额部署DNS,都污染了DNS。另外,WEB浏览器也喜欢为应用增加一些没法解析的名字上去。
运营方面:如不合格的代理机构,网络的差异性,开放的解析软件,没有SOA,名字服务器复杂的相互依赖,TTL的设置,名字空间的随意扩展,把DNS当作负载均衡技术用等。
注册方面:注册相当乱。
 
应对上述DNS安全威胁的主要办法可总结如下:
防范Arp***、采用UDP随机端口、建立静态IP映射、运行最新版本的BIND、限制查询、利用防火墙进行保护、利用交叉检验、使用TSIG机制、利用DNSSEC机制。
下面分别做出说明。
1、防范Arp***
主要是针对局域网的DNS ID欺骗***。如上所述,DNS ID欺骗是基于Arp欺骗的,防范了Arp欺骗***,DNS ID欺骗***是无法成功实施的。
2、采用UDP随机端口
不再使用默认的53端口查询,而是在UDP端口范围内随机选择,可使对ID与端口组合的猜解难度增加6万倍,从而降低使DNS缓存***的成功率。
3、建立静态IP映射
主要是指DNS服务器对少部分重要网站或经常访问的网站做静态映射表,使对这些网站的访问不再需要经过缓存或者向上一级的迭代查询,从而在机制上杜绝DNS欺骗***。(就是添加主机记录)
4、运行最新版本的BIND
使用最新版本的BIND,可以防止已知的针对DNS软件的***(如DoS***、缓冲区溢出漏洞***等)。应密切关注BIND安全公告,及时打好补丁。
5、限制查询
在BIND8和BIND9之后,BIND的allow-query子句允许管理员对到来的查询请求使用基于IP地址的控制策略,访问控制列表可以对特定的区甚至是对该域名服务器受到的任何查询请求使用限制策略。如限制所有查询、限制特定区的查询、防止未授权的区的查询、以最少权限运行BIND等。 http://www.nsfocus.net/vulndb/16089 
6、利用防火墙进行保护
这种保护方式可以使受保护的DNS服务器不致遭受分布式拒绝服务***、软件漏洞***。原理是在DNS服务器主机上建立一个伪DNS服务器供外部查询,而在内部系统上建立一个真实的DNS服务器专供内部使用。配置用户的内部DNS客户机,用于对内部服务器的所有查询,当内部主机访问某个网站时,仅当内部DNS服务器上没有缓存记录时,内部DNS才将查询请求发送到外部DNS服务器上,以保护内部服务器免受***。
7、利用交叉检验
这种保护方式可以从一定程度上防范DNS欺骗***。原理是反向查询已得到的IP地址对应的主机名,用该主机名查询DNS服务器对应于该主机名的IP地址,如果一致,则请求合法,否则非法。
8、使用TSIG机制
1.TSIG技术
交易签章 (TSIGRFC 2845),是为了保护 DNS安全而发展的。从BIND 8.2版本开始引入 TSIG 机制,其验证 DNS 讯息方式是使用共享金钥 (Secret Key) 及单向杂凑函式(One-way hash function) 来提供讯息的验证和数据的完整性。主要针对区带传输(ZONE Transfer)进行保护的作用,利用密码学编码方式为通讯传输信息加密以保证 DNS 讯息的安全,特别是响应与更新的讯息数据。也就是说在DNS服务器之间进行辖区传送时所提供保护的机制,以确保传输数据不被窃取及监听。
2.SIG0 技术简介
    SIG0是一九九九年三月 由  IBM公 司的D. Eastlake 提出成为标准。其是利用公开金钥机制为辖区资料进行数字签章的动作,以保证每笔传输的 source record 具有可验证性与不可否认性。实际上 SIG0 才是防止 DNS Spoofing 发生最主要的技术,SIG0 是使用公开金钥加密法,让辖区管理者为其辖区数据加上数字签章,由此证明辖区资料的可信赖性。除此之外,SIG0 保有是否选择认证机制的弹性,以及可灵活地配合自订的安全机制。
9、利用DNSSEC机制
为保证客户机发送的解析请求的完整性,保护DNS服务器及其中的信息,防止***者冒充合法用户向他人提供虚假DNS信息,IETF(网络工程任务组)提出了DNS安全扩展(DNSSEC)的安全防范思想。
   1、 DNSSEC工作原理
为提高DNS访问数据包的安全性,DNSSEC在兼容现有协议的基础上引入加密和认证体系,在每个区域都有一对区域级的密钥对,密钥对中的公钥对域名记录信息进行数字签名,从而使支持DNSSEC的接收者可以校验应答信息的可靠性。
BIND9.0支持DNS的安全扩展功能…。DNSSEC引入两个全新的资源记录类型:KEY和SIG,允许客户端和域名服务器对任何DNS数据来源进行密钥验证。DNSSEC主要依靠公钥技术对于包含在DNS中的信息创建密钥签名,密钥签名通过计算出一个密钥Hash数来提供DNS中数据的完整性,并将该Hash数封装进行保护。私/公钥对中的私钥用来封装Hash数,然后可以用公钥把Hash数翻译出来。如果这个翻译出的Hash值匹配接收者计算出来的Hash数,那么表明数据是完整的、没有被篡改的。
   2、 DNSSEC的实施
1)、创建一组密钥对
#cd/vat/named
#dnssec -keygen -a RSA -b 512 -n ZONE qfnu.edu.Kqfnu.edu+002+27782
2)、生成密钥记录
#dnssec –makekeyset -t 172802 I<qfnu.edu.+002+27782.key
3)、发送密钥文件到上一级域管理员,以供签名使用
#dnssec -signkey keyset -qfnu.edu Kedu.+002+65396.private
然后将返回qfnu.edu.signedkey文件
4)、在进行区域签名之前,必须先将密钥记录添加到区域数据文件之中
#cat“$include Kqfnn.edu.+002+27782.key”>>db.qfnu.edu
5)、对区域进行签名
#dnssec –signzone -O qfnu.edu db.qfnu.edu
6)、修改named.conf里的zone语句,系统将会载新的区域数据文件
   3、 DNSSEC的不足
一方面,DNSSEC安全性虽然有所提高,但是标记和校验必然产生额外的开销,从而影响网络和服务器的性能,签名的数据量很大,加重了域名服务器对骨干网以及非骨干网连接的负担,同时简明校验也对CPU造成了很大的负担,同时签名和密钥也占用了磁盘的 空间以及RAM容量。DNSSEC中的根密钥管理和更新问题。
另一方面,安全性能方面的考虑。绝大多数的DNS软件是美国出口的,它们为了通过美国政府的安全规定而被迫降低加密算法和过程的安全强度。
第三方面,RSA算法的使用。RSA拥有美国专利,与某些厂商和组织倡导的“免费/开放”目标有所冲突,但是同时又别无选择。在成本方面也是部署中的一个问题。