DNS漫谈

前言

近期自建CDN X省下面的CDN节点(集群)带宽异常波动,因为第一层的CDN带宽是通过公网DNS负载均衡的,正常情况下各节点的带宽应该是大致均衡的,但实际上存在某个节点带宽远高于其他节点的情况,且并不是同一个节点,而是所有的节点带宽轮流的突发。最终查明的原因是该省运营商的递归DNS缓存策略造成的。

而这个问题也让小编重新认识了庞大互联网上DNS这微乎其微的,但又是无比重要的一环, 这也促进了《DNS漫谈》的产生。

小明是大学毕业,在家待业的理工男一枚。整天在家里无所事事,靠着父母养活也不是办法。看着新闻联播里报道的层出不穷的互联网新秀企业,小明灵机一动,决定也创建一个互联网企业,业务类型待定,盈利模式未知。既然搞的是互联网,那么首先得搞个网站,要搞个网站首先得有个域名。要什么域名呢,有了!就叫nb.com。

1. DNS概述

作为一个理工男,小明对于IT技术还是比较了解的。先买个域名,有了域名之后,再搞台带有外网IP的服务器。通过DNS设置下解析,而DNS不就是一个翻译器嘛,负责域名和IP(服务器)两者之间的转换翻译工作。

DNS一般有7大记录(A,CNAME,TXT,NS,AAAA,MX,SRV),最常用的有A记录,CNAME记录,NS记录和MX记录。

  • A记录:地址记录,用来指定域名的IPv4地址(如:119.147.15.13),如果需要将域名指向一个IP地址,就需要添加A记录。像小明就需要把www.nb.com的域名使用A记录指向服务器的外网IP。
  • CNAME: 如果需要将域名指向另一个域名,再由另一个域名提供ip地址,就需要添加CNAME记录。
  • NS:域名服务器记录,如果需要把子域名交给其他DNS服务商解析,就需要添加NS记录。
  • MX:如果需要设置邮箱,让邮箱能收到邮件,就需要添加MX记录。

Linux上可以通过nslookup和dig命令进行查询测试。

域名是在各域名注册局进行购买,不同的域名往往价格也不同。小明选了价格最低的注册局,交了3天的饭钱后(小明吃饭从来不小气),终于买了下这个域名。

然后小明又选择了一个域名托管商,例如xxxpod.com好像就挺不错的,用的人蛮多的。设置了nb.com的DNS服务器为DNS托管商提供的地址。

可以通过whois信息可以查看到设置的Name Server已经是ok的。不过有点奇怪,小明在xxpod.com添加域名后,依然会有提示“未能接管该域名”。仔细查看whois的结果后,发现域名的状态是serverHold(域名被注册局暂停)状态。网上搜了一下后发现工信部出了新的政策,所有国内注册的域名必须进行实名认证,否则域名会被注册局强制设置为serverHold状态,无法使用。

小明可是要成为合法企业CEO的人,连忙提交了实名认证信息进行审核,一周后域名终于可以正常使用了。

2. DNS架构

小明心想,搞了个域名折腾了这么久,总得了解下DNS是啥架构?一个域名完整的解析流程又是什么样子的?

原来全球的DNS是分级的,最顶层的是根服务器,全球一共有13台,主要负责管理顶级域名。而像mail.facai.nb.com这个域名,com为顶级域,nb.com为二级域名,facai.nb.com则为三级域名(或者叫子域),mail.facai.nb.com则是四级域名(或者叫主机名)

而一个域名又经历了那些步骤,最终解析到IP呢?

(1)用户向本地DNS(递归DNS,一般由运营商自动下发分配)提交了www.163.com的查询请求,本地DNS查询本地缓存后如果有缓存且未过期的话,则直接返回IP给用户。

 

(2)如果本地DNS没有命中的话,则向根服务器查询.com这个域名是谁管理的?根服务器收到请求后,给出响应,.com域名是由另外一台机器管理的。

 

(3)本地DNS向.com管理服务器发起请求,查询163.com是谁管理的。.com管理服务器给出响应,163.com是有另外机器管理的。

 

(4)最终本地DNS向163.com的授权服务器查询www.163.com的记录。163.com的授权服务器查询出具体的IP地址返回给本地DNS

 

(5)本地DNS收到响应缓存一份数据同时将查询的结果返回给用户。

在这个域名解析流程中还涉及到一些名词解析,需要特别留意下:

  • 正向解析: 查找域名对应IP的过程。
  • 反向解析: 查找IP对应域名的过程。
  • 权威DNS: 处于DNS服务器的一套系统,该系统保存了相应域名的权威信息。权威DNS即通俗上“这个域名我说了算”的服务器。
  • 递归DNS: 又叫local 。递归DNS,其核心功能一个是缓存、一个是递归查询。收到域名查询请求后其首先看本地缓存是否有记录,如果没有则一级一级的查询根、顶级域、二级域……直到获取到结果然后返回给用户。日常上网中运营商分配的DNS一般是这里所说的递归DNS。
  • 公共DNS: 公共DNS属于递归DNS。其典型特征为对外一个IP,为所有用户提供公共的递归查询服务,114.114.114.114就是广为人知的公共DNS。

3. DNS负载均衡

3.1 普通多记录负载均衡

小明域名也购买了,拉了几个同样在家待业的程序员将网站也搭建起来了,甚至连手机端的APP也开发完毕,正式对外访问。没想到网站特别的受欢迎,很快原先的一台机器承载不了这么大的访问量了。如何承载更大的用户访问,成了迫在眉睫上的难题。

这个小明知道解决办法,可以直接使用DNS负载均衡,www.nb.com 设置多个A记录。用户解析域名时,会同时反馈多个IP。而包括浏览器在内的应用程序一般都是默认取第一个响应的IP来进行请求访问。DNS服务器在响应查询的时候,每次响应的IP顺序都是不同的,用户连接的IP也是不同的,这样就实现了请求的负载均衡和承载能力的水平扩展。

3.2 HTTPDNS

由于DNS的架构复杂,请求的流程也较多,因此也比较容易发生各种意外的事情,经常有用户保障电脑访问不聊站点或者手机端APP打开空白的情况。小明烦不胜烦,难道就没有更好的域名到IP的对应方案了吗?

搜索之后,还真让小明找到了解决方案,现在各大云厂商都在大力推广一种名为httpdns的技术。

httpdns,顾名思义,将原本走udp 53到递归dns的查询,改为走http协议,由http服务器直接返回对应的ip。并且httpdns可以精准的获取用户的ip,返回更精准的服务器IP给用户。

#直接向HTTPDNS提供的IP地址请求解析域名,就可以得到该域名下到用户的最优IP
curl  -s http://119.29.29.29/d?dn=www.163.com
114.80.143.193;101.227.66.207

不过这个技术有个瑕疵,传统的浏览器并未添加对httpdns的支持。所以只能在自己可以控制的客户端中使用。小明跟同事讨论后,觉得还是可以尝试一下的。移动APP添加了httpdns后,果然少了好多解析的问题。

3.3 DNS多线路智能解析

现在一切蒸蒸日上。唯一甜蜜的烦恼,就是用户的量越来越大,即使多台服务器有点承载不住。小明干脆将服务器进行了动静态分离,将静态资源的加载全部剥离出来,通过DNS的分线路功能,每个省份都设置了多台服务器来专门服务静态资源的加载。

在使用DNS进行用户就近解析(智能调度)的时候,小明了解到目前国内的DNS托管商的智能调度并不是那么精确。

问题在于国内的大部分递归DNS都不支持EDNS(详情可以查看之前文章),没办法将用户的真实IP传递给权威服务器。因此权威服务器只能将就着使用递归DNS的服务器ip来进行就近查询。一般情况下用户的递归DNS和用户IP是同个运营商同个区域的。但是也经常存在用户乱设置DNS或者小区网络管理员乱设的情况。导致权威DNS返回的服务器IP不是最优的。

这种情况,移动端可以通过httpdns绕过递归dns来杜绝,但是浏览器就有点无能为力了,谁让问题是发生在用户端的网络呢。

4. 递归DNS缓存

4.1 递归DNS篡改缓存记录的TTL

最近覆盖X省的几台服务器节点,整天轮流带宽告警。其他省份下面的各CDN节点的带宽大致是差不多的,而X省则是一台机器的带宽是其他机器的数倍,且过一段时间后,带宽就降下去了,轮到其他节点带宽增高。

刚开始小明以为是地区网络连通性的问题,可能是其中某个机器的网络质量比较好,所以用户访问这台机器速度好,带宽的冲的更高。但是这种情况下,会一直是某台机器带宽一致高,而不是每台机器都轮流着跑高。

小明想起之前使用“网速通”全区DNS功能测试域名的时候,记录的TTL设置的明明是10,但是部分地区查询出来的TTL却是300。也就是说部分地区的运营商为了降低递归DNS的压力强制增大了域名的TTL 。

正常情况下即使运营商强制增加了DNS记录的缓存时间也不应该会造成带宽过大的波动,顶多故障切换的时间更慢些(故障的IP需要等TTL到期才能更新)。除非递归DNS将权威DNS的响应顺序也一定缓存起来,每次响应给用户的也都是同一顺序,这样会导致在TTL内,用户访问的始终是某一个CDN节点。可能会导致节点带宽轮流飙高的情况。

4.2 递归DNS缓存记录的顺序

通过手机app上报的日志,小明筛选出了该省份的递归DNS,验证发现,该省份的递归DNS除了增大了域名的TTL外,还将响应IP的顺序也一起缓存起来了。导致一段时间内该递归DNS下的所有用户始终连接到是某个IP。

由于问题是发生在运营商的递归DNS,也没有太好的解决办法,小明也只能临时给这个省的节点加强了机器配置,增大了上联带宽或者也可以推行LVS的架构,进行二次负载均衡。

5. DNS的其他玩法

现在小明对DNS的了解也比较深了,除了日常跟同事会议讨论公司的事情,闲暇时也会了解和学习DNS一些好玩的功能。比较有趣的是利用DNS实现的两个功能。

5.1 DNS tunnel

DNS tunnel,顾名思义就是通过DNS查询建立的网络隧道。在各种方式(http,icmp,ssh等)实现的隧道中。DNS tunnel也算是一股清流,它是通过将数据封装在dns查询请求中,数据通过DNS的请求流程最终会转发到目的权威DNS服务器。

而权威DNS服务器是经过特殊设计的,可以解密dns查询封装的数据,实现隧道的功能。

转发的方式分为直连和中继两种。

  • 直连:客户端直接和指定的权威dns服务器连接,直接将数据编码在DNS协议中通信。
  • 中继:通过运营商的递归DNS进行数据中转,最终发送到权威dns服务器

直连的方式应用范围较小,因为大部分的网络环境,是只允许指定的几台DNS server连接外网,是根据IP来放行网络访问而非根据协议来放行网络访问。

(图片转自网络,侵删。)

软件:http://code.kryo.se/iodine/

服务器端参数

iodined  [options] <tunnel_ip> <topdomain>

tunnel_ip:指定server在TUN接口上的IP,客户端的TUN接口IP会和服务端在同一子网内
topdomain:用来构造域名的上级域,也就是我们ns记录中的指定域名

Options:

-D:指定调试级别,-DD指第二级,‘D’随等级增加

客户端参数

iodine [options] <topdomain>

Options:

-r:采用DNS中继模式传输数据
-M:指定上行主机名大小
-m:调节最大下行分片大小
-T:指定所使用的DNS请求类型,可选有NULL,PRIVATE,TXT,SRV,MX,CNAME,A
-O: 指定数据编码规范
-L:是否使用懒惰模式,默认开启
-I:指定请求间的时间间隔
公用Options
-f: 前台运行
-P password:指定一个password进行认证,如果不指定,后续会提示

测试

##服务器发送文件给客户端,iodine是虚拟建立了网卡
##有些递归DNS不支持默认的配置,需要调整参数
#服务端
iodined  IP  Domain
nc -l 34567  < data.txt
#会提示输入密码

#客户端
iodine -f -P Password Domain  -r
nc x.x.x.x  34567  > data.txt

5.2 DNS 反射放大攻击

反射放大攻击是近年来频发的一种攻击方式,最流行的当属NTP反射放大攻击和DNS反射放大攻击。放大攻击,不管是何种类型的方式,基于的原理主要是下面两点。

  • 回复包一定比请求包大
  • 伪造请求包的源IP地址,将应答包引向被攻击的目标

这其中有个放大比的概念,回复包的数据跟请求包的比例越大,攻击效果越好。颇有四两千斤的意味。对于DNS的放大攻击来讲,EDNS能够让DNS回复超过512字节并且仍然使用UDP,可以让攻击者轻轻松松的放大几十倍。再加上互联网上众多未加防范的IOT设备,更是让反射放大攻击如鱼得水。

国内运营商的众多递归DNS迟迟不肯支持EDNS,除了技术层面的问题,安全方面也是有所考虑。

6. 结语

DNS对整个互联网起着翻译的功能,可以说是全球互联网的大门也不为过。而这道大门却经常被人忽视,直到造成了严重的故障后才会正视它。

盘点近几年的重大DNS故障:

  • 2009年5月19日 暴风DNS受攻击导致电信递归DNS大规模的阻塞,全国大范围断网
  • 2010年1月12日 百度域名被劫持事件,百度域名被伊朗黑客劫持,域名更换到雅虎域名服务器。造成百度全球范围的服务异常。
  • 2014年1月21日DNS域名根服务器故障,造成全国网络访问异常。
  • 2015年3月13日 苹果内部DNS故障,致使iTunes 商店、App Store无法登陆,中断时间长达11小时。
END
赞(0)
未经允许不得转载:运维军团 » DNS漫谈

评论 抢沙发

*

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址