关于我遇到的一个DNS问题

clipboard.png

最近遇到一个小问题,在某些用户的请求中会莫名其妙的出现重定向而后致使404,在这里分享下致使这种问题的缘由。

这里不会介绍DNS和CDN,若是想了解请google或百度,有好几斤的数据能够看,我也不必再说了。这篇文章主要是从关于客户端DNS解析和CDN服务解析的整个流程角度去解释我遇到的这个很幼稚的buglinux

DNS服务器能够部署在不少阶段

DNS对于大多数同窗来讲均可能知道是干吗的,可是深刻了解工做原理可能有些模糊,首先它它分布在不少个阶段,总体分为两大块:本地DNS服务,远端DNS服务。程序员

本地(Local Resolver)

每台电脑本地都会配置一个DNS解析文件,在Nginx上咱们能够在 /etc/resolv.conf 中查看,固然也能够从界面中查看。数据库

下面是我在CLI查看个人本地DNS服务配置,即DNS客户机配置(/etc/resolv.conf)
clipboard.png浏览器

下面是我在设置中查看DNS服务配置
clipboard.png缓存

你们会问,这两个同样吗?只不过一个是在文件系统查看一个是在GUI上查看,二者没区别吧?嗯,是的没区别。服务器

实际上,修改本地的DNS解析规则,在Nginx上有三个地方,分别是网络

hosts文件-->网卡配置文件-->DNS服务器地址配置文件

咱们刚才修改的只是系统的DNS服务器地址配置文件,固然GUI上也是对应的这个文件。前两个配置方式比较粗暴,在这里就不讲了,有伤大雅。app

分析一下配置文件中的字段(实际上还有不少,先说两个吧):dom

  1. domain提供一个基本的搜索域,解析失败的域名会和这个基本的搜索域拼接,再去作DNS解析,看我下面偷的这一句话,就明白它的做用了。例如,若是您指定搜索域为 apple.com,在您的网页浏览器中键入“store”将会前往 store.apple.com。或者,若是使用 campus.university.edu 做为搜索域,那么您能够在“访达”的“链接服务器”对话框中键入“server1”来链接到 server1.campus.university.edu。
  2. nameserver,也就是本地的DNS服务器列表,它的格式是IP地址,v4 v6 d均可以,远端或本地地址均可以,甚至这个地址能够填写一个本地的服务,而后咱们就能够自定义处理DNS解析服务了。

nameserver这个字段就太好玩了,一般家庭版的地址是192.168.0.1,也就是大多数路由器的IP地址,而后用户能够在本身的路由器设置页面配置DNS解析服务器的地址。belowsocket

clipboard.png

固然,你也能够不使用路由器来转发你的DNS解析,直接填写这个根DNS服务器地址,也就是图上面的222.*。

做为程序员,突发奇想,咱们还能够玩的更浪一些~~~,就好比:

添加一个本地域名解析服务,也就是添加一个127.0.0.1在你的DNS配置文件中,注意必定要添加在第一行,别忘了nameserver是in order的哦。

clipboard.png

而后在本地开一个UDP服务,监听53端口(为何是UDP为何是53端口,好奇同窗请trace here),你就会看到本地的DNS处理记录:

let dgram = require('dgram');
let socket = dgram.createSocket('udp4');
// 服务端监听一个端口 数据到来时 能够读出信息
socket.bind(53,'localhost',function(){
    //读取消息
    socket.on('message',function(data,rinfo){
        console.log(data.toString());
    })
});

下面这些乱七八糟的,就是DNS解析记录...

clipboard.png

咱们能够修改上面的代码来自定义解析后的信息,我不知道这个返回状态应该怎么设定,没事闲的同窗能够去查查怎么能够伪造这个信息,听起来很刺激... 不过我以为不太可能,53端口受特殊保护,就连监听和查看它的占用状况都须要提权,上述代码linux上出EACCES错的能够加上sudo,win提权太麻烦不说了。

说了 一大堆没用的,回正题,如今开始咱们假设本地DNS服务接受了一个软件的解析请求~~

咱们假设上述的 hosts文件-->网卡配置文件-->DNS服务器地址配置文件,前两个不作任何处理的状况下。如下顺序处理。

  1. 在DNS解析服务开始以前,系统会找到本地的这个DNS服务器列表,在我这是两个,10.10. and 10.120. 从第一个开始向这个DNS服务器发送域名解析请求。
  2. 若是第一个处理失败,或者查询不到,就用第二个找。也就是 10.120.*。
  3. 若是10.120.*也找不到(最后一个nameserver),那么使用这个domain来处理了。

本地DNS服务的任务就是接受计算机软件的DNS解析服务,去向根DNS服务器发送请求,得到最终的IP地址。

若是本地有 DNS resolver 的话,也是能够缓存你的DNS解析的,什么是Resover?就是我们刚才创建在53端口的服务,它就是一个Resolver。

// 验证是否存在 resolver
sduo lsof -i:53
// or 查看 /etc/resolv.conf

resolver 有可能缓存上一次DNS解析结果。若是碰到恶意的resolver,看谁不顺眼就能够筛选全部某站的主域名(好比竞争对手的...嘿嘿)返回一个不存在的ip地址,而后这个域名在那台电脑上就over了,除非技术手动撤销这个resolver,不然卸载重装,重启,通通很差使。

因此,友情提醒:尽可能不要使用本地的DNS resolver。

根DNS(Root DNS)

接着从上面的本地DNS服务开始说,它把解析请求发送给 20.20.* 服务器,这个服务器就是根DNS,全部DNS解析请求都通过它来转发
根DNS服务器免费的没有几个,国内的114.114*比较快一点,国外的Google的4个8或者4个1,都是广泛使用的。那么又一个问题,世界上这么多电脑才这么几个服务器,并且每台电脑的DNS解析请求是很是频繁的,这几个服务器受得住吗?

首先,它确实是接受全部的请求的,但它不负责处理这个解析,只负责分类并返回子DNS服务器IP。而后LocalDNS接收到这个子DNS服务器IP后,再去向子DNS迭代查询。

这个阶段,若是你本地有DNS缓存服务的话,它会记住某个域名与它所属的子DNS的IP地址,下次请求直接去子DNS地址,而不用通过ROOT DNS处理。

顶级 DNS(TLD DNS)

子DNS分不少区,这个分类其实就是根据域名的后缀来的,好比,有 COM DNS 服务器,它只负责 com这个后缀的域名解析。固然还有其余类型的,好比 .cn .net。固然,不可能每一个后缀都来一台服务器,流量较少的的后缀应该被分在一个区里。

子DNS接到LocalDNS请求以后,查询此域名以后发现它已经交给专属DNS服务器(也就是你购买域名时设置的域名解析服务器)处理

子DNS的做用就是帮助RootDNS减小不少查库和处理请求的时间。

自定义DNS服务器

服务器DNS属于咱们域名下的专属DNS服务器,咱们可使用本身的DNS服务器配置到你的域名上(申请DNS服务器须要到国内注册局申请办理)。

若是是本地内网搭建,就没那么多规则,可使用Bind ((Berkeley Internet Name Domain))。

一般,咱们在阿里云购买的域名绑定上域名解析就能够了,默认使用的是万网的DNS服务器,若是你有本身的DNS服务器的话,能够在域名管理中配置。

最后来张图通一通。以我司客户端为例:

  1. LocalDNS 接收到一个客户端发送的域名解析请求,看看本地有没有上次缓存的现成的hetao101域下的DNS服务器。若是没有,取出第一个nameserver(也就是根DNS服务器),进行迭代查询。若是有,直接跳到第5步。
  2. 根DNS解析咱们的www.hetao101.com地址属于 com 区,而后把 com 区的子DNS服务器的IP返回给LocalDNS处理。
  3. LocalDNS收到子DNS的IP,而后再次发送迭代查询向子DNS
  4. 子DNS查询数据库,找到www.hetao101.com这个域名对应的服务器DNS地址,而后把地址返回给LocalDNS
  5. LocalDNS发送请求到www.hetao101.com的DNS 服务器,而后返回给它域名对应的IP地址。
  6. LocalDNS拿到IP后很是鸡冻(来回串了这么多服务器终于拿到了),赶忙握握手亲热亲热,而后开始了创建网络通道(e.g TCP)。

注意,以上的递归查询和迭代查询的区别,递归查询的是:我向A请求,A你必须得给我一个结果,不到黄河不死心。而迭代查询是,我向A请求,A有可能没有这个东西,它把B返回给你,让你和B问...

clipboard.png

CDN服务器

网络就是数个灯泡中间的导线,电线长了,电流抵达的速度也就慢了,灯泡亮的速度就慢了。。。

因此,咱们在导线的中间加上了一个继电器式的资源服务器。也就是CDN服务器。保证资源快速响应给局部用户。

CDN服务器一般包括一个源站和子节点(其余区域的资源服务器),上传文件到CDN服务器首先到达源站,而后源站分发给子节点。而后当客户端请求时候经过它们本身的DNS服务器解析请求IP(地理位置因素),而后返回不一样的子节点地址。

若是源站的资源被替换或者删除,子节点也会与它同步。

简单的打了个比方,具体使用场景及原理,能够自行Goog,很少说了废话了,下面简单说下我遇到那个问题。

最近遇到一个小问题,在更新资源文件后,在某些用户的请求中会莫名其妙的出现 302而后重定向地址是404,在这里分享下致使这种问题的缘由。

上下文:这个请求是阿里云OSS的,客户是河北沧州移动运营商,重定向后的IP地址后面添加相比源路径多了不少层路径,位置是河北石家庄的移动网络。

我一开始的分析是,本地DNS服务或运营商缓存了DNS解析(阿里云DNS解析后的IP是能够根据客户端的区域分配就近节点的,因此应该被分到了石家庄节点),而后当我更新这个文件时,因为ISP缓存没有到期(假定是ISP,还有多是本地DNS Resolver),而后更新文件后,继续请求上次的解析后的地址(地址上是有文件的hash的),致使资源404(hash值被更新)。

仔细想一下是不对的,首先DNS解析只会返回域名区段,不会给你添加路径。第二若是是阿里云子节点在上传文件到源站的时候,就会同步到各个子节点,因此不会出现404的状况。

那么,若是这个重定向的IP地址不是阿里云的,难道是运营商本身的,它把响应文件缓存起来,而后放到本身的缓存服务器,若是请求在缓存期内就从运营商本身的缓存服务器里取?我估计这个也不可能,由于,条件是每次在阿里云OSS上更新文件时,才会出现这个问题,因此,有两种可能:

  1. 由于资源是和阿里云源站同步的,因此,可断定这个地址并非运营商的地址(是阿里云的)。
  2. DNS劫持,劫持和缓存同样,区别是前者以攻击为目的,给你返回指望以外的IP,后者是给你目标IP。

而当我分析上面说的302返回的重定向地址时,我不太确信这是一个DNS劫持,由于这地址看起来太正经,如:

http://111.**.135.171/files/317200004364C385/***.oss-cn-beijing.aliyuncs.com/***.zip

第一段 IP,后面的的路径很是有规律,files下面的file hash,而后是源站的下载地址。

这么正经的IP不多是被劫持吧,那么再说回去,若是302是运营商的DNS缓存致使的,302后的地址也就是这个地址,它是怎么来的呢??

我分别测试了山东和杭州的网络,DNS解析***.oss-cn-beijing.aliyuncs.com这个源下载地址并无返回动态子节点IP,实际上仍是beijing区的源站IP,这说明DNS解析是没有动态返回节点的。

不是运营商也不是阿里云,到底是什么?

愁了我一个星期,在阿里云栖社区问了此问题,也没有收到特别准确的回答,由于用户的问题已经使用其余方式修复,因此没有办法再次肯定问题,目前只能认为是

  1. DNS劫持
  2. 运营商的DNS缓存,DNS缓存阿里云的OSS地址解析后的IP,但是并不起做用,由于阿里的OSS使用的是虚拟站点,用DNS后的ip+路径 和 地址+路径是不同的, 。

DNS解析后的IP是不能直接替换域名的,DNS是为了取IP,而IP是在创建链接层之根基,可是链接层上还有写一层,一些服务器上的httpserver,好比Apach或者Nginx会提供一个叫作虚拟站点的功能,简单来讲根据你请求的host(域名)来分拨出不一样的文件路径,也就是说一台服务器是能够享有多个域名的。固然不只是分拨路径,中间还能够去向其余服务请求(有点像proxy,可是根据域名来判断的proxy分拨),想了解更多请搜索 虚拟站点

如何解决?

一切恶果毋庸置疑终究是运营商酿造的,可是想绕过它却不现实。

  1. 请求地址换成IP,避免DNS解析缓存。
  2. 若是是资源文件,为资源文件名加盐

若是你对于个人问题有其余见解,请评论。若是你以为我说的不对,请纠正(有悬赏)。若是你想跳槽,请看个人我的资料右上角。若是你觉还有点帮助,请使劲儿点个赞。若是你以为这篇文章浪费了你的时间,没啥干货,请私聊喷我一顿。

相关文章
相关标签/搜索