2017-01-07 整理程序员
这个东东也是今年博主参见校招的时候被不少公司问过的,虽然理论性比较强,可是做为一个程序员,我的认为熟悉DNS是很是重要的,要理解它并能帮助解决一些实际问题。面试
虽然当时回答了,可是仍是感受得系统总结下,备忘。数据库
Domain Name System = DNS(域名系统)实际上是一个数据库,是用于 TCP/IP 程序的分布式数据库,同时也是一种重要的网络协议。DNS储存了网络中的 IP 地址与对应主机的信息,邮件路由信息和其余网络应用方面的信息,用户经过询问解决库(解决库发送询问并对DNS回应进行说明)在 DNS 上查询信息。ubuntu
DNS是网络分层里的应用层协议,事实上他是为其余应用层协议工做的,简单说就是把域名,或者说主机名转化为IP地址(同时也提供反向域名查询的功能),相似字典,好比访问 www.baidu.com,实际访问的是它的IP地址,由于机器识别的是拥有固定格式和含义的IP地址,而域名能够千奇百怪,甚至是中文,不利于识别。还有好比公司内部的域验证,经过分配给员工的域帐号登陆内网就必须经过DNS来找到域名权限服务器,来认证身份,故有些书上说:DNS是因特网世界里不可缺乏的东西。浏览器
人和人要互相识别和记忆,须要名字做为辅助,而对于网络世界,在因特网内也须要一种命名系统来作相似的事情,该系统使用了域来划分,任何一个网络里的主机(或者路由器)都有独一无二的域名(相似国家代码),域又能继续划分为子域(相似每一个国家有不一样的省份代码),子域还能继续划分(每一个省都有本身的各个城市的代码)……在因特网内对应的就是顶级域名(com,net,cn,org等),二级域名……注意这仅仅是一种逻辑的划分。而这些域名系统在形式上组成了一种树结构。缓存
名字(也叫标号)组成只能是英文或者数字,目前中文也支持了,长度不大于63个字符,总共完整域名长度不超过255个字符,英文域名不区分大小写,从右到左,域名级别依次下降。www是表示万维网,不属于域名。安全
域名的名字空间是一个树结构,根没有名字,各个树叶是单台计算机名,不能继续划分。服务器
DNS服务器管理范围的单位是区,不是域,由于区才是DNS服务器管理的实际范围,区是域的子集,同一个区里的主机节点必须互通,它们都有一个统一的访问权限,该访问权限在经过一个权限域名服务器管理。好比,公司a,有两个部门x,y,部门x又有两个分部q和r,a会设立一个区叫a.com(区和域能够同名),这是一个大的权限范围,而后下属再设立一个区,叫x.a.com,那么区a.com和x.a.com都属于域a.com。网络
DNS服务器也是相似域名空间树同样的树结构,依次分为根域名服务器(知道全部的顶级域名服务器的域名和IP,最重要,它要是瘫痪,整个DNS就完蛋),而后是顶级域名服务器(管理二级域名),其次是权限域名服务器(负责区的域名服务器)。架构
最后是本地域名服务器(也叫默认域名服务器),本地域名服务器离主机很近(书上说不超过几个路由器),速度很快,其实本地域名服务器本质不属于域名服务器架构。
如图就是Linux的本地域名服务器配置
如图是Windows下本地DNS服务器配置
由于因特网规模很大,因此整个因特网只使用一个域名服务器是不行的。为了可靠,使用了分布式的域名系统,即便单个计算机除了故障,也不会妨碍整个DNS系统的正常运行。并采用c/s方式。DNS使大多数名字都在本地解析(resolve),仅有少许解析须要在因特网上通讯,所以分布式DNS系统借助分布式的主机备份和缓存机制,很是强壮和有足够的性能。
DNS劫持又称域名劫持,说白了就是当用户请求DNS解析的时候,对正常的DNS请求报文进行拦截,偷到请求的域名,而后就能够作手脚,好比经常遇到访问某个健康的网址的时候,明明输入的网址是xxxx.com,结果却跳转到了不可描述的网站……即把审查范围,或者权限范围之外的请求放行,不然返回假的IP地址或者什么都不作使请求失去响应,效果就是让人误觉得断网(360网络诊断里常常说的,打的开QQ,可是没法浏览网页的现象),或者获得了假网址,黑客们常常利用漏洞或者程序的缺陷对用户的DNS进行篡改,进行钓鱼网站的欺诈活动。
解决办法能够手动修改本地DNS域名服务器地址,首选DNS服务器:114.114.114.114,是国内第一个、全球第三个开放的DNS服务地址,又称114DNS,或8.8.8.8(google提供的DNS服务器)等,而后修改宽带密码,路由器密码,主机密码。
当一个应用须要把主机名解析为IP地址时,该应用进程就调用地址解析程序,它本身就变为了DNS的一个客户,把待解析的域名放在DNS请求报文中,以UDP方式先发给本地域名服务器,本地域名服务器在查找域名后,把对应的IP地址放在回答报文中返回,应用程序得到目的主机的IP地址后便可进行通讯。若本地域名服务器不能回答该请求,则此域名服务器就暂时称为DNS的另外一个客户,并向其余域名服务器发出查询请求。这种过程直至找到可以回答该请求的域名服务器为止。
若是主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户端的身份(递归思想),向根域名服务器继续发出查询报文(替主机查询),不让主机本身进行查询。递归查询返回的结果或者是IP,或者报错。这是从上到下的递归查询过程。
当根域名服务器收到本地域名服务器的查询请求,要么给出ip,要么通知本地域名服务器下一步应该去请求哪个顶级域名服务器查询(并告知本地域名服务器本身知道的顶级域名的IP),让本地域名服务器继续查询,而不是替他查询。同理,顶级域名服务器没法返回IP的时候,也会通知本地域名服务器下一步向谁查询(查询哪个权限域名服务器)……这是一个迭代过程。
到底采用哪一种查询,取决于原始查询报文的设置,不绝对。
DNS中使用了高速缓存,由于域名到地址的映射不常变,故为提升效率而设,主机在启动时从本地服务器下载名和地址的所有数据,并维护存放本身最近使用的域名的缓存,而且只在从缓存中找不到名字时才使用根域名服务器发起查询。实际中,当一个 DNS 服务器接收到一个 DNS 回答后,会将其信息缓存一段时间,当再有一个对相同域名的查询时,即可直接回复。经过 DNS 缓存,大部分查询都只须要本地 DNS 服务器即可完成解析。
本地域名服务器在接收到DNS请求时,先查找DNS缓存,若是缓存命中直接返回结果,若是黑客攻入路由器,对部分域名的缓存进行了更改,好比将缓存的结果指向不可描述的页面,那么即致使用户的正常请求被转移……,此时能够清除各级缓存(浏览器,系统,路由器,DNS缓存)。貌似没法避免,只能是提升安全意识,即便使用了 HTTPS也不行,由于DNS解析过程发生在HTTPS请求交互前。
Hosts是一个没有扩展名的系统文件,做用是将一些经常使用的网址域名与其对应的IP地址创建一个关联“数据库”, 其实 hosts 文件能够看做是一个小型的本地 DNS 服务器。
优先顺序是:当用户在地址栏输入一个URL以后,浏览器首先查询浏览器的缓存,找不到就去查询Hosts文件和本地DNS缓存,若是hosts和本地DNS缓存都没有找到域名对应的IP,则自动进入路由器的缓存中检查,以上均为客服端DNS缓存,若在客户端DNS缓存仍是没找到,则进入ISP DNS缓存中查询,仍是找不到,最终才向 根DNS 服务器发出 DNS 查询报文,再找不到就报错……
+---------------------+
| 报文头 |
+---------------------+
| 问题 | 向服务器提出的查询记录
+---------------------+
| 回答 | 服务器回复的资源记录
+---------------------+
| 受权 | 权威的资源记录
+---------------------+
| 格外的 | 格外的资源记录
+---------------------+
哎,这个报文格式和名字也是醉了,不过不碍事,当在浏览器内输入URL时,便开始了DNS解析过程,最后会把找到后的IP地址告知浏览器客户端,方便它继续发出 HTTP(s)请求,该过程当中,浏览器提出的查询记录类型叫A记录(address)查询,其余查询记录类型常见的有A(地址)记录、CNAME(别名)记录、MX(邮件交换)记录等。
好比问:www.baidu.com的A记录是什么?
是 220.181.110.181
这个A记录意思是从域名解析获得IP地址。那么反过来,从IP地址获得域名的解析过程也须要一个记录,叫PTR记录(和A记录功能相反),可使用nslookup命令查询,能够经过查询IP地址的PTR记录来获得该IP地址指向的域名,达到反查的目的。
IP反向解析主要应用到邮件服务器中来阻拦垃圾邮件,好比用 xxx@xxx.com 给邮箱 xxxxx@qq.com 发了一封信。qq邮件服务器会查看信头文件,信头文件显示信是由哪一个IP地址发出的,而后根据IP地址反向解析,如反向解析到这个IP所对应的域名是xxx.com (不在黑名单)那么就接受,不然拒绝。
域名系统中,一个IP地址可对应多个域名,在Internet上是不会去傻傻的遍历整个域名树的。故DNS的顶级域名提供了一个特别的顶级域——arpa 用来作反向域名解析,也称为反向域名。当一个主机加入网络,得到DNS受权,它的IP地址假设为192.168.1.1,它也顺便得到了对应IP地址的 in-addr.arpa (逆向解析域in-addr.arpa)空间的受权,注意DNS名由树底部向上组织,故它的DNS名字为192.168 .1.1.in-addr.arpa。IP地址的第一字节必定位于in-addr的下一级。这样欲解析的IP地址就会被表达成一种像域名同样的形式,后缀以反向解析域名"in-addr.arpa"结尾。
本质上:反向域名解析是将IP地址表达成了一个域名,这样反向解析的很大部分能够归入正向解析中。
如上是一般状况下的DNS报文,基于UDP数据报封装(同时DNS也支持TCP),而且要知道DNS服务器的默认端口是53
观察出现的数据包
如图,第一行是DNS查询报文,第二行是DNS回答报文。
证明了DNS确实为应用层的协议,目的端口号确实是53,传输层通常状况下采用UDP也是ok的,网络层是IP协议,数据链路层有以太网帧。
对应的抽象报文格式图
+---------------------+
| 报文头 |
+---------------------+
| 问题 | 向服务器提出的查询记录
+---------------------+
| 回答 | 服务器回复的资源记录
+---------------------+
| 受权 | 权威的资源记录
+---------------------+
| 格外的 | 格外的资源记录
+---------------------+
首部12字节
以上是12字节的DNS包头
+---------------------+
| 报文头 |
+---------------------+
| 问题 | 向服务器提出的查询记录
+---------------------+
| 回答 | 服务器回复的资源记录
+---------------------+
| 受权 | 权威的资源记录
+---------------------+
| 格外的 | 格外的资源记录
+---------------------+
Queries为查询或者响应的正文,以下是请求报文里的问题部分
每一个问题对应一个查询类型,响应报文里的资源记录部分里每一个响应(资源记录)也对应一个资源类型。PS:资源记录也叫响应,以下
大致和查询报文一致,响应包就是多出了一个Answers字段
响应报文的answer字段,第一个是请求的域名,而后cname记录表示出别名为www.a.shifen.com,这个别名的地址看下面具体的回答
DNS同时支持UDP和TCP访问,当名字解析器发出一个查询请求,而且返回响应报文中的TC位设置为1时,名字解析器一般使用TCP重发原来的查询请求,TCP能将用户的数据流分为一些报文段,用多个报文段来传送任意长度的用户数据,即容许返回的响应超过512个字节。
此外,为了减轻单台DNS服务器的负载,有时要将同一DNS区域的内容保存在多个DNS服务器中(主从备份,分布式存储),这时,就要用到DNS的“区域传输”功能。在分布式的DNS数据库中,当一个域的辅助名字服务器在启动时,将从该域的主名字服务器执行区域传送。辅助服务器将定时(一般是3小时)向主服务器进行查询以便了解主服务器数据是否发生变更,若是有变更,为了数据一致性,将执行一次区域传送,区域传送将使用TCP,由于传送的数据远比一个查询或响应多。
故DNS主要使用UDP,TCP为辅,若是是UDP,那么不管是名字解析器仍是名字服务器都必须本身处理超时和重传。此外,DNS不像其余的使用UDP的应用同样,大部分操做集中在局域网上,DNS查询和响应一般通过广域网。分组丢失率和往返时间的不肯定性在广域网上比局域网上更大。这样对于DNS客户程序,一个好的重传和超时程序就显得更重要。
DNS服务器使用的熟知端口号不管对UDP仍是TCP都是53
BIND (Berkeley Internet Name Domain)是DNS协议的一个实现,提供了DNS主要功能的开放实现,包括
Bind 是一款开源的 DNS 服务器软件,由美国加州大学 Berkeley 分校开发和维护的,按照 ISC 的调查报告,BIND 是世界上使用最多最普遍的域名服务系统,经过搭建私有的 DNS 服务器,能够把国外的一些不可描述的 ip 地址放到本身的 DNS 服务器中畅快浏览。
安装环境本地ubuntu,客户端和服务器都是使用的一台机器
找一台机器做为DNS客户端,将客户端的 DNS 修改成刚刚搭建的DNS服务器的 ip 地址
使用nslookup来查询服务器(若使用其余的客户端, ip 地址 须要加入到 "trusted" ACL 里面)。