输入有误 發表於 2020-6-8 11:28:00

域名解析-DNS转化

<h2 class="md-end-block md-heading md-focus"><span class="md-plain">前言</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">简介</span></h3>
<p class="md-end-block md-p"><span class="md-plain">域名(Domain Name),是由一串用点分隔的名字组成的互联网上某台计算机或某组计算机的标识,它的目的是为了方便人们更简单便捷地访问互联网上的服务。在实际的系统实现中,域名通过DNS(Domain Name System)系统转化为服务器的IP地址,以方便机器通过IP进行寻址和通信。上述行为,我们称之为域名解析</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">为什么需要DNS解析域名为IP地址</span></h2>
<p class="md-end-block md-p"><span class="md-plain">网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址的,所以计算机在网络上进行通讯时只能识别如“202.96.134.133”之类的IP地址,而不能认识域名。我们无法记住10个以上IP地址的网站,所以我们访问网站时,更多的是在浏览器地址栏中输入域名,就能看到所需要的页面,这是因为有一个叫“DNS服务器”的计算机自动把我们的域名“翻译”成了相应的IP地址,然后调出IP地址所对应的网页</span></p>
<p class="md-end-block md-p"><span class="md-plain">作为一次网络通信最前置的环节,域名解析的重要性不言而喻。在传统的基于浏览器的网站访问场景下,域名解析环节由浏览器内核实现,网站开发者无需关心域名解析的细节。But there are always two sides to every coin,一旦域名解析环节发生异常,开发者面对这样的黑盒架构就会显得束手无策,一个很典型的例子即域名劫持问题</span></p>
<p class="md-end-block md-p"><span class="md-plain">进入移动互联网时代,大量的应用基于C/S架构构建。相较于传统的面向浏览器的Web App,C/S架构的应用赋予了我们非常大的软件定制空间,开发者甚至可以渗透到整个应用的底层网络实现当中,域名解析环节的优化因此变为了可能</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">名词概念</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">域名系统</span></h3>
<p class="md-end-block md-p"><span class="md-plain">域名系统(英文:Domain Name System,缩写:DNS)是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工作。DNS就是这样的一位“翻译官”,它的基本工作原理可用下图来表示。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/1.png"><img src="https://qiniu-app.qtshe.com/1.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">DNS解析是分布式存储的,比如根域名服务器ROOT DNS,只存储260个顶级域名的DNS服务器的ip地址。顶级域名服务器如.com的DNS服务器,存储的则是一些一级域名的权威DNS服务器地址(如suning.com,qq.com,163.com的DNS)。而suning.com的权威DNS存储的才是具体的主机记录(如A记录,cname记录,txt记录)</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">根域、顶级域、二级域</span></h3>
<p class="md-end-block md-p"><span class="md-plain">DNS系统一般采用树状结构进行组织,以<span class="md-pair-s"><code>ru.wikipedia.org</code><span class="md-plain">为例,<span class="md-pair-s"><code>org</code><span class="md-plain">为顶级域名,<span class="md-pair-s"><code>wikipedia</code><span class="md-plain">为二级域名,<span class="md-pair-s"><code>ru</code><span class="md-plain">为三级域名,域名树状组织结构如下图所示</span></span></span></span></span></span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/2.png"><img src="https://qiniu-app.qtshe.com/2.png" width="649" height="383"></span></p>
<ol class="ol-list" start="">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">根域名服务器(ROOT)</span></p>
<p class="md-end-block md-p"><span class="md-plain">根服务器主要用来管理互联网的主目录,全世界IPv4根服务器只有13台(这13台IPv4根域名服务器名字分别为“A”至“M”),1个为主根服务器在美国。其余12个均为辅根服务器,其中9个在美国,欧洲2个,位于英国和瑞典,亚洲1个位于日本。根服务器中有经美国政府批准的260个左右的互联网后缀(如.com、.net、.cn等)</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">顶级域名服务器</span></p>
<p class="md-end-block md-p"><span class="md-plain">负责解析本身顶级域名下一级域名对应的权威DNS服务器地址</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">localDNS 本地DNS</span></p>
<p class="md-end-block md-p"><span class="md-plain">一般是运营商的dns,主要作用是代理用户进行迭代解析</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">本地host记录</span></p>
<p class="md-end-block md-p"><span class="md-plain">这个优先级最高可以在自己电脑自定义域名的解析记录,如果本机有就不会再往上迭代。PC的host(C:\Windows\System32\drivers\etc\hosts)</span></p>
</li>
</ol>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">权威DNS</span></h3>
<p class="md-end-block md-p"><span class="md-plain">权威DNS即最终决定域名解析结果的服务器,开发者可以在权威DNS上配置、变更、删除具体域名的对应解析结果信息,阿里云云解析即权威DNS服务提供商</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">递归DNS</span></h3>
<p class="md-end-block md-p"><span class="md-plain">递归DNS又称为Local DNS,它没有域名解析结果的决定权,但代理了用户向权威DNS获取域名解析结果的过程。递归DNS上有缓存模块,当目标域名存在缓存解析结果并且TTL未过期时(每个域名都有TTL时间,即有效生存时间,若域名解析结果缓存的时间超过TTL,需要重新向权威DNS获取解析结果),递归DNS会返回缓存结果,否则,递归DNS会一级一级地查询各个层级域名的权威DNS直至获取最终完整域名的解析结果</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">公共DNS</span></h3>
<p class="md-end-block md-p"><span class="md-plain">公共DNS是递归DNS的一种特例,它是一种全网开放的递归DNS服务,而传统的递归DNS信息一般由运营商分发给用户。一个比较典型的公共DNS即Google的<span class="md-pair-s"><code>8.8.8.8</code><span class="md-plain">,我们可以通过在操作系统配置文件中配置公共DNS来代替Local DNS完成域名解析流程</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">在实际的使用过程中,我们通常不需要手工指定自己的Local DNS地址。运营商会通过DHCP协议在系统网络初始化阶段将Local DNS地址分配给我们的计算机。当我们需要使用公共DNS服务时,我们就必须手工指定这些服务的地址。以Linux为例,我们可以通过在'/etc/resolv.conf'中添加Local DNS地址项来改变本机Local DNS的地址</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">递归查询</span></h3>
<p class="md-end-block md-p"><span class="md-plain">主机向本地域名服务器的查询一般都是采用递归查询。所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其它根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的IP地址</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/3.png"><img src="https://qiniu-app.qtshe.com/3.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">迭代查询</span></h3>
<p class="md-end-block md-p"><span class="md-plain">本地域名服务器向根域名服务器的查询的迭代查询。迭代查询的特点:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地服务器进行后续的查询。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器,让本地域名服务器再向顶级域名服务器查询。顶级域名服务器在收到本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个权限域名服务器进行查询。最后,知道了所要解析的IP地址或报错,然后把这个结果返回给发起查询的主机</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/3.png"><img src="https://qiniu-app.qtshe.com/3.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">域名解析记录</span></h3>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">A记录</span></p>
<p class="md-end-block md-p"><span class="md-plain">A代表的是Address,用来指定域名对应的IP地址,比如将map.baidu.com指定到180.97.34.157,将zhidao.baidu.com指定到180.149.131.245,A记录允许将多个域名解析到一个IP地址,但不允许将一个域名解析到多个IP地址上</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">MX记录</span></p>
<p class="md-end-block md-p"><span class="md-plain">MX代表的是Mail Exchage,就是可以将某个域名下的邮件服务器指向自己的Mail Server,如baidu.com域名的A记录IP地址是180.97.34.157,如果将MX记录设置为180.97.34.154,即<span class="md-link md-pair-s">xxx@baidu.com<span class="md-plain">的邮件路由,那么DNS会将邮件发送到180.97.34.154所在的服务器,而正常web请求仍然会解析到A记录的IP地址180.97.34.157</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">CNAME记录</span></p>
<p class="md-end-block md-p"><span class="md-plain">CNAME指的就是Canonical Name,也就是别名解析,可以将指定的域名解析到其他域名上,而其他域名就是指定域名的别名,整个解析过程称为别名解析。比如将baidu.com解析到itlemon.cn,将csdn.net解析到itlemon.cn,那么itlemon.cn就是baidu.com和CSDN.net的别名</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">NS记录</span></p>
<p class="md-end-block md-p"><span class="md-plain">就是为某个域名指定了特定的<span class="md-pair-s"><code>DNS</code><span class="md-plain">服务器去解析</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">TXT记录</span></p>
<p class="md-end-block md-p"><span class="md-plain">为某个主机名或者域名设置特定的说明,比如为itlemon.cn设置的的TXT记录为“Lemon的技术笔记”,这个TXT记录为itlemon.cn的说明</span></p>
</li>
</ul>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">域名的解析过程</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">步骤及原理图</span></h3>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/5.png"><img src="https://qiniu-app.qtshe.com/5.png" width="730" height="519"></span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">DNS解析过程</span></h3>
<ol class="ol-list" start="">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">检查浏览器缓存中是否缓存过该域名对应的IP地址</span></p>
<p class="md-end-block md-p"><span class="md-plain">用户通过浏览器浏览过某网站之后,浏览器就会自动缓存该网站域名对应的<span class="md-pair-s"><code>IP</code><span class="md-plain">地址,当用户再次访问的时候,浏览器就会从缓存中查找该域名对应的IP地址,因为缓存不仅是有大小限制,而且还有时间限制(域名被缓存的时间通过<span class="md-pair-s"><code>TTL</code><span class="md-plain">属性来设置),所以存在域名对应的<span class="md-pair-s"><code>IP</code><span class="md-plain">找不到的情况。当浏览器从缓存中找到了该网站域名对应的<span class="md-pair-s"><code>IP</code><span class="md-plain">地址,那么整个<span class="md-pair-s"><code>DNS</code><span class="md-plain">解析过程结束,如果没有找到,将进行下一步骤。对于<span class="md-pair-s"><code>IP</code><span class="md-plain">的缓存时间问题,不宜设置太长的缓存时间,时间太长,如果域名对应的<span class="md-pair-s"><code>IP</code><span class="md-plain">发生变化,那么用户将在一段时间内无法正常访问到网站,如果太短,那么又造成频繁解析域名</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">如果在浏览器缓存中没有找到IP,那么将继续查找本机系统是否缓存过IP</span></p>
<p class="md-end-block md-p"><span class="md-plain">如果第一个步骤没有完成对域名的解析过程,那么浏览器会去系统缓存中查找系统是否缓存过这个域名对应的<span class="md-pair-s"><code>IP</code><span class="md-plain">地址,也可以理解为系统自己也具备域名解析的基本能力。在<span class="md-pair-s"><code>Windows</code><span class="md-plain">系统中,可以通过设置<span class="md-pair-s"><code>hosts</code><span class="md-plain">文件来将域名手动绑定到某<span class="md-pair-s"><code>IP</code><span class="md-plain">上,<span class="md-pair-s"><code>hosts</code><span class="md-plain">文件位置在<span class="md-pair-s"><code>C:\Windows\System32\drivers\etc\hosts</code><span class="md-plain">。对于普通用户,并不推荐自己手动绑定域名和<span class="md-pair-s"><code>IP</code><span class="md-plain">,对于开发者来说,通过绑定域名和<span class="md-pair-s"><code>IP</code><span class="md-plain">,可以轻松切换环境,可以从测试环境切换到开发环境,方便开发和测试。在<span class="md-pair-s"><code>XP</code><span class="md-plain">系统中,黑客常常修改他的电脑的<span class="md-pair-s"><code>hosts</code><span class="md-plain">文件,将用户常常访问的域名绑定到他指定的<span class="md-pair-s"><code>IP</code><span class="md-plain">上,从而实现了本地<span class="md-pair-s"><code>DNS</code><span class="md-plain">解析,导致这些域名被劫持。在<span class="md-pair-s"><code>Linux</code><span class="md-plain">或者<span class="md-pair-s"><code>Mac</code><span class="md-plain">系统中,<span class="md-pair-s"><code>hosts</code><span class="md-plain">文件在<span class="md-pair-s"><code>/etc/hosts</code><span class="md-plain">,修改该文件也可以实现同样的目的</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">前两步都是在本机上完成的,所以没有在上面示例图上展示出来,从第三步开始,才正在地向远程DNS服务器发起解析域名的请求</span></p>
</blockquote>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">向本地域名解析服务系统发起域名解析的请求</span></p>
<p class="md-end-block md-p"><span class="md-plain">如果在本机上无法完成域名的解析,那么系统只能请求本地域名解析服务系统进行解析,本地域名系统<span class="md-pair-s"><code>LDNS</code><span class="md-plain">一般都是本地区的域名服务器,比如你连接的校园网,那么域名解析系统就在你的校园机房里,如果你连接的是电信、移动或者联通的网络,那么本地域名解析服务器就在本地区,由各自的运营商来提供服务。对于本地<span class="md-pair-s"><code>DNS</code><span class="md-plain">服务器地址,<span class="md-pair-s"><code>Windows</code><span class="md-plain">系统使用命令<span class="md-pair-s"><code>ipconfig</code><span class="md-plain">就可以查看,在<span class="md-pair-s"><code>Linux</code><span class="md-plain">和<span class="md-pair-s"><code>Mac</code><span class="md-plain">系统下,直接使用命令<span class="md-pair-s"><code>cat /etc/resolv.conf</code><span class="md-plain">来查看<span class="md-pair-s"><code>LDNS</code><span class="md-plain">服务地址。<span class="md-pair-s"><code>LDNS</code><span class="md-plain">一般都缓存了大部分的域名解析的结果,当然缓存时间也受域名失效时间控制,大部分的解析工作到这里就差不多已经结束了,<span class="md-pair-s"><code>LDNS</code><span class="md-plain">负责了大部分的解析工作</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">向根域名解析服务器发起域名解析请求</span></p>
<p class="md-end-block md-p"><span class="md-plain">本地<span class="md-pair-s"><code>DNS</code><span class="md-plain">域名解析器还没有完成解析的话,那么本地域名解析服务器将向根域名服务器发起解析请求</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">根域名服务器返回gTLD域名解析服务器地址</span></p>
<p class="md-end-block md-p"><span class="md-plain">本地<span class="md-pair-s"><code>DNS</code><span class="md-plain">域名解析向根域名服务器发起解析请求,根域名服务器返回的是所查域的通用顶级域(<span class="md-pair-s"><code>Generic top-level domain,gTLD</code><span class="md-plain">)地址,常见的通用顶级域有<span class="md-pair-s"><code>.com</code><span class="md-plain">、<span class="md-pair-s"><code>.cn</code><span class="md-plain">、<span class="md-pair-s"><code>.org</code><span class="md-plain">、<span class="md-pair-s"><code>.edu</code><span class="md-plain">等</span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">向gTLD服务器发起解析请求</span></p>
<p class="md-end-block md-p"><span class="md-plain">本地域名解析服务器向gTLD服务器发起请求</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">gTLD服务器接收请求并返回Name Server服务器</span></p>
<p class="md-end-block md-p"><span class="md-pair-s"><code>gTLD</code><span class="md-plain">服务器接收本地域名服务器发起的请求,并根据需要解析的域名,找到该域名对应的<span class="md-pair-s"><code>Name Server</code><span class="md-plain">域名服务器,通常情况下,这个<span class="md-pair-s"><code>Name Server</code><span class="md-plain">服务器就是你注册的域名服务器,那么你注册的域名的服务商的服务器将承担起域名解析的任务</span></span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">Name Server服务器返回IP地址给本地服务器</span></p>
<p class="md-end-block md-p"><span class="md-pair-s"><code>Name Server</code><span class="md-plain">服务器查找域名对应的<span class="md-pair-s"><code>IP</code><span class="md-plain">地址,将<span class="md-pair-s"><code>IP</code><span class="md-plain">地址连同<span class="md-pair-s"><code>TTL</code><span class="md-plain">值返回给本地域名服务器</span></span></span></span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">本地域名服务器缓存解析结果</span></p>
<p class="md-end-block md-p"><span class="md-plain">本地域名服务器缓存解析后的结果,缓存时间由<span class="md-pair-s"><code>TTL</code><span class="md-plain">时间来控制</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">返回解析结果给用户</span></p>
<p class="md-end-block md-p"><span class="md-plain">解析结果将直接返回给用户,用户系统将缓存该<span class="md-pair-s"><code>IP</code><span class="md-plain">地址,缓存时间由<span class="md-pair-s"><code>TTL</code><span class="md-plain">来控制,至此,解析过程结束</span></span></span></span></span></p>
</li>
</ol>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain md-expand">DNS报文结构</span></h2>
<p class="md-end-block md-p"><span class="md-plain">现在的DNS主要还是通过UDP来通讯,大小不超过1500个字节,结构如下:</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:python;gutter:true;">+--+--+--+--+--+--+--+
|      Header      |
+--+--+--+--+--+--+--+
|      Question      |
+--+--+--+--+--+--+--+
|      Answer      |
+--+--+--+--+--+--+--+
|      Authority   |
+--+--+--+--+--+--+--+
|      Additional    |
+--+--+--+--+--+--+--+</pre>
</div>
<p class="md-end-block md-p"><span class="md-plain">按格式来区分的话,可以分为三部分:头部Header,查询部分Question,应答部分:Answer,Authority,Additional</span></p>
<p>&nbsp;</p>
<h3><span class="md-plain"><span class="md-pair-s"><span class="md-plain"><span class="md-pair-s"><span class="md-plain">头部Header</span></span></span></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain md-expand">各字段作用</span></p>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">ID: 2个字节(16bit),标识字段,客户端会解析服务器返回的DNS应答报文,获取ID值与请求报文设置的ID值做比较,如果相同,则认为是同一个DNS会话</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">FLAGS: 2个字节(16bit)的标志字段。包含以下属性</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">QR: 0表示查询报文,1表示响应报文</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">opcode: 通常值为0(标准查询),其他值为1(反向查询)和2(服务器状态请求),保留值</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">AA: 表示授权回答(authoritative answer)– 这个比特位在应答的时候才有意义,指出给出应答的服务器是查询域名的授权解析服务器</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">TC: 表示可截断的(truncated)–用来指出报文比允许的长度还要长,导致被截断</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">RD: 表示期望递归(Recursion Desired) – 这个比特位被请求设置,应答的时候使用的相同的值返回。如果设置了RD,就建议域名服务器进行递归解析,递归查询的支持是可选的</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">RA: 表示支持递归(Recursion Available) – 这个比特位在应答中设置或取消,用来代表服务器是否支持递归查询</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">Z : 保留值,暂未使用</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">RCODE: 应答码(Response code) - 这4个比特位在应答报文中设置,代表的含义如下</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">0 : 没有错误</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">1 : 报文格式错误(Format error) - 服务器不能理解请求的报文</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">2 : 服务器失败(Server failure) - 因为服务器的原因导致没办法处理这个请求</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">3 : 名字错误(Name Error) - 只有对授权域名解析服务器有意义,指出解析的域名不存在</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">4 : 没有实现(Not Implemented) - 域名服务器不支持查询类型</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">5 : 拒绝(Refused) - 服务器由于设置的策略拒绝给出应答.比如,服务器不希望对某些请求者给出应答,或者服务器不希望进行某些操作(比如区域传送zone transfer)</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain"> : 保留值,暂未使用</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">QDCOUNT: 无符号16bit整数表示报文请求段中的问题记录数</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">ANCOUNT: 无符号16bit整数表示报文回答段中的回答记录数</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">NSCOUNT: 无符号16bit整数表示报文授权段中的授权记录数</span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain">ARCOUNT: 无符号16bit整数表示报文附加段中的附加记录数</span></p>
</li>
</ul>
<p>&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain md-expand">Question 查询字段</span></h3>
<div class="cnblogs_Highlighter">
<pre class="brush:python;gutter:true;">+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     ...                     |
|                  QNAME                      |
|                     ...                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  QTYPE                      |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  QCLASS                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+</pre>
</div>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">QNAME 8bit为单位表示的查询名(广泛的说就是:域名)</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">QTYPE 无符号16bit整数表示查询的协议类型</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">QCLASS 无符号16bit整数表示查询的类,比如,IN代表Internet</span></p>
</li>
</ul>
<p><span class="md-plain"><span class="md-pair-s"><span class="md-plain"><span class="md-pair-s"><span class="md-plain">&nbsp;</span></span></span></span></span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">应答部分Answer/Authority/Additional</span></h3>
<div class="cnblogs_Highlighter">
<pre class="brush:python;gutter:true;">+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  NAME                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  TYPE                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  CLASS                      |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  TTL                        |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  RDLENGTH                   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  RDATA                      |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+</pre>
</div>
<ul class="ul-list" data-mark="*">
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">NAME 资源记录包含的域名</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">TYPE 表示DNS协议的类型</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">CLASS 表示RDATA的类</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">TTL 4字节无符号整数表示资源记录可以缓存的时间。0代表只能被传输,但是不能被缓存</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">RDLENGTH 2个字节无符号整数表示RDATA的长度</span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">RDATA 不定长字符串来表示记录,格式根TYPE和CLASS有关。比如,TYPE是A,CLASS 是 IN,那么RDATA就是一个4个字节的ARPA网络地址</span></p>
</li>
</ul>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain md-expand">常见问题解析</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">域名劫持</span></h3>
<p class="md-end-block md-p"><span class="md-plain">域名劫持一直是困扰许多开发者的问题之一,其表现即域名A应该返回的DNS解析结果IP1被恶意替换为了IP2,导致A的访问失败或访问了一个不安全的站点。下面我们一起看看几种常见的域名劫持的场景</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain">一种可能的域名劫持方式即黑客侵入了宽带路由器并对终端用户的Local DNS进行篡改,指向黑客自己伪造的Local DNS,进而通过控制Local DNS的逻辑返回错误的IP信息进行域名劫持。另一方面,由于DNS解析主要是基于UDP协议,除了上述攻击行为外,攻击者还可以监听终端用户的域名解析请求,并在Local DNS返回正确结果之前将伪造的DNS解析响应传递给终端用户,进而控制终端用户的域名访问行为</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain">&nbsp;</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/6.png"><img src="https://qiniu-app.qtshe.com/6.png" width="413" height="380"></span></p>
<p class="md-end-block md-p"><span class="md-plain">上述攻击行为的影响面相对比较有限,另一种我们最常碰到的域名劫持现象是缓存污染。我们知道在接收到域名解析请求时,Local DNS首先会查找缓存,如果缓存命中就会直接返回缓存结果,不再进行递归DNS查询。这时候如果Local DNS针对部分域名的缓存进行更改,比如将缓存结果指向第三方的广告页,就会导致用户的访问请求被引导到这些广告页地址上</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/7.png"><img src="https://qiniu-app.qtshe.com/7.png" width="418" height="508"></span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain">对比第一种攻击,这类缓存污染往往能带来更明显的群体伤害,比如某个省份某个运营商的用户群可能因为该地区Local DNS的缓存污染而导致访问服务异常。这类缓存污染行为往往是间歇性、局部性发生的,没有明显的规律,导致开发者很难对其进行量化、评估、预防</span></p>
<p class="md-end-block md-p md-focus">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain md-expand">调度不精准</span></h3>
<p class="md-end-block md-p"><span class="md-plain">除了域名劫持问题,基于传统Local DNS的域名解析还会带来域名调度精准性的问题。对于类似CDN域名访问这类需要按地域、运营商进行智能解析调度的场景,精准调度的诉求是十分强烈的</span></p>
<p class="md-end-block md-p"><span class="md-plain">关于调度不精准的原因,我们主要可以从两个方面来探究一下。第一个常见的问题即解析转发</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/8.png"><img src="https://qiniu-app.qtshe.com/8.png" width="598" height="508"></span></p>
<p class="md-end-block md-p"><span class="md-plain">部分Local DNS供应商为了降低运营成本,会将请求到自己节点的域名解析请求转发给其他供应商的Local DNS节点,如上图所示。假如用户请求解析一个CDN域名<span class="md-pair-s"><code>cdn.aliyun.com</code><span class="md-plain">,用户分配到的Local DNS A为了节省成本,把该次请求转发给了另一运营商的Local DNS B,权威DNS在进行域名解析时会根据Local DNS的IP信息进行智能调度,即权威DNS会根据Local DNS B的IP<span class="md-pair-s"><code>78.29.29.1</code><span class="md-plain">进行调度,分配与<span class="md-pair-s"><code>78.29.29.1</code><span class="md-plain">相同运营商并且地理位置最近的CDN节点<span class="md-pair-s"><code>78.29.29.2</code><span class="md-plain">,然而这个CDN节点对于终端<span class="md-pair-s"><code>135.35.35.1</code><span class="md-plain">而言并不是最优的CDN节点,他们分属不同的运营商,并且地理位置上可能相隔很远。这类解析转发行为会严重影响域名解析的精准性并对用户业务访问延迟带来影响</span></span></span></span></span></span></span></span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">除了解析转发对调度精准性带来的影响外,Local DNS的布署情况同样影响着域名智能解析的精准性</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/9.png"><img src="https://qiniu-app.qtshe.com/9.png" width="584" height="472"></span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain">如上图所示,部分运营商Local DNS的布点受成本因素制约分布并不均匀,比如在东部地区部署比较密集,但在西部地区部署比较稀疏。这时候当一位西藏的用户准备访问CDN节点时,我们预期他应该会被调度到西藏的CDN节点A上以实现就近接入和访问加速。但由于Local DNS的资源有限,西部地区的终端用户被统一调度到青海的Local DNS B上,这时候权威DNS根据Local DNS B的IP进行CDN域名的智能解析,并将青海的CDN节点B返回给西藏用户,导致用户的网络访问延迟上升。另一种我们实际发现的情况是Local DNS的分配甚至并非遵循就近原则,比如有实际案例显示西藏的用户甚至被分配了北京的Local DNS节点C,导致西藏的用户在进行CDN资源访问时被调度到了北京的CDN节点C上,类似的由于调度精度的缺失带来的访问体验的影响是非常严重的</span></p>
<p class="md-end-block md-p md-focus">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">解析生效滞后</span></h3>
<p class="md-end-block md-p"><span class="md-plain">部分业务场景下开发者对域名解析结果变更的生效时间非常敏感(这部分变更操作是开发者在权威DNS上完成的),比如当业务服务器受到攻击时,我们需要最快速地将业务IP切换到另一组集群上,这样的诉求在传统域名解析体系下是无法完成的</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://qiniu-app.qtshe.com/10.png"><img src="https://qiniu-app.qtshe.com/10.png" width="598" height="497"></span></p>
<p class="md-end-block md-p"><span class="md-plain">Local DNS的部署是由各个地区的各个运营商独立部署的,因此各个Local DNS的服务质量参差不齐。在对域名解析缓存的处理上,各个独立节点的实现策略也有区别,比如部分节点为了节省开支忽略了域名解析结果的TTL时间限制,导致用户在权威DNS变更的解析结果全网生效的周期非常漫长,这类延迟生效可能直接导致用户业务访问的异常</span></p>
<p><span class="md-plain">&nbsp;</span></p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/zhazhanitian/p/13064607.html
頁: [1]
查看完整版本: 域名解析-DNS转化