DNS(Domain Name System), 也叫网域名称系统,是互联网的一项服务。它实质上是一个 域名 和 IP 相互映射的分布式数据库,有了它,咱们就能够经过域名更方便的访问互联网。git
DNS 有如下特色:github
-
分布式的数据库
-
协议支持 TCP 和 UDP,经常使用端口是 53后端
-
每一级域名的长度限制是 63浏览器
-
域名总长度限制是 253缓存
那么,什么状况下使用 TCP,什么状况下使用 UDP 呢?安全
最先的时候,DNS 的 UDP 报文上限大小是 512 字节, 因此当某个 response 大小超过512 (返回信息太多),DNS 服务就会使用 TCP 协议来传输。后来 DNS 协议扩展了本身的UDP 协议,DNS client 发出查询请求时,能够指定本身能接收超过512字节的 UDP 包, 这种状况下,DNS 仍是会使用 UDP 协议。服务器
分层的数据库结构
DNS 的结构跟 Linux 文件系统很类似,像一棵倒立的树。下面用站长之家的域名举例:网络
最上面的.是根域名,接着是顶级域名com,再下来是站长之家域名 chinaz 依次类推。使用域名时,从下而上。s.tool.chinaz.com. 就是一个完整的域名,www.chinaz.com. 也是。负载均衡
之因此设计这样复杂的树形结构, 是为了防止名称冲突。这样一棵树结构,固然能够存储在一台机器上,但现实世界中完整的域名很是多,而且天天都在新增、删除大量的域名,存在一台机器上,对单机器的存储性能就是不小的挑战。另外,集中管理还有一个缺点就是管理不够灵活。能够想象一下,每次新增、删除域名都须要向中央数据库申请是多么麻烦。因此现实中的 DNS 都是分布式存储的。
根域名服务器只管理顶级域,同时把每一个顶级域的管理委派给各个顶级域,因此当你想要申请com下的二级域名时,找 com 域名注册中心就行了。例如你申请了上图的 chinaz.com 二级域名,chinaz.com 再向下的域名就归你管理了。当你管理 chinaz.com 的子域名时,你能够搭建本身的 nameserver,在 .com 注册中心把 chinaz.com 的管理权委派给本身搭建的nameserver。自建nameserver 和不自建的结构图以下:
通常状况下,能不自建就不要自建,由于维护一个高可用的 DNS 也并不是容易。据我所知,有两种状况须要搭建本身的 nameserver:
-
搭建对内的 DNS。公司内部机器众多,经过 IP 相互访问太过凌乱,这时能够搭建对内的 nameserver,容许内部服务器经过域名互通
-
公司对域名厂商提供的 nameserver 性能不满意。虽然顶级域名注册商都有本身的nameserver,但注册商提供的 nameserver 并不专业,在性能和稳定性上没法知足企业需求,这时就须要企业搭建本身的高性能 nameserver,好比增长智能解析功能,让不一样地域的用户访问最近的 IP,以此来提升服务质量
归纳一下 DNS 的分布式管理, 当把一个域委派给一个nameserver后,这个域下的管理权都交由此nameserver处理。这种设计一方面解决了存储压力,另外一方面提升了域名管理的灵活性 (这种结构像极了Linux File System, 能够把任何一个子目录挂载到另外一个磁盘,还能够把它下面的子目录继续挂载出去)
顶级域名
像 com 这样的顶级域名,由 ICANN 严格控制,是不容许随便建立的。顶级域名分两类:
-
通用顶级域名
-
国家顶级域名
通用顶级域名常见的如.com、.org、.edu等, 国家顶级域名如我国的.cn, 美国的.us。通常公司申请公网域名时,若是是跨国产品,应该选择通用顶级域名;若是没有跨国业务,看本身喜爱(能够对比各家顶级域的服务、稳定性等再作选择)。这里说一下几个比较热的顶级域,完整的顶级域参见维基百科。
me
me顶级域实际上是国家域名, 是黑山共和国的国家域名,只不过它对我的开发申请,因此不少我的博主就用它做为本身的博客域名(本博客也是这么来的~)
io
不少开源项目经常使用io作顶级域名,它也是国家域名。由于io 与计算机中的 input/output 缩写相同,和计算机的二机制10也很像,给人一种geek的感受。相较于.com域名,.io下的资源不少,更多选择。
DNS 解析流程
聊完了 DNS 的基本概念,咱们再来聊一聊 DNS 的解析流程。当咱们经过浏览器或者应用程序访问互联网时,都会先执行一遍 DNS 解析流程。标准 glibc 提供了 libresolv.so.2 动态库,咱们的应用程序就是用它进行域名解析(也叫 resolving)的, 它还提供了一个配置文件/etc/nsswitch.conf
来控制 resolving 行为,配置文件中最关键的是这行:
hosts: files dns myhostname
它决定了 resolving 的顺序,默认是先查找 hosts 文件,若是没有匹配到,再进行 DNS 解析。默认的解析流程以下图:
上图主要描述了 client 端的解析流程,咱们能够看到最主要的是第四步请求本地 DNS 服务器去执行 resolving,它会根据本地 DNS 服务器配置,发送解析请求到递归解析服务器(稍后介绍什么是递归解析服务器), 本地 DNS 服务器在 /etc/resolv.conf 中配置。下面咱们再来看看服务端的 resolving 流程:
咱们分析一下解析流程:
-
客户端向本地DNS服务器(递归解析服务器) 发出解析tool.chinaz.com域名的请求
-
本地dns服务器查看缓存,是否有缓存过tool.chinaz.com域名,若是有直接返回给客户端;
若是没有执行下一步
-
本地dns服务器向根域名服务器发送请求,查询com顶级域的nameserver 地址
-
拿到com域名的IP后,再向com nameserver发送请求,获取chinaz域名的nameserver地址
-
继续请求 chinaz 的nameserver,获取 tool 域名的地址,最终获得了tool.chinaz.com 的 IP,本地 dns 服务器把这个结果缓存起来,以供下次查询快速返回
-
本地dns服务器把把结果返回给客户端
递归解析服务器 vs 权威域名服务器
咱们在解析流程中发现两类 DNS 服务器,客户端直接访问的是 递归解析服务器, 它在整个解析过程当中也最忙。它的查询步骤是递归的,从根域名服务器开始,一直询问到目标域名。
递归解析服务器经过请求一级一级的权威域名服务器,得到下一目标的地址,直到找到目标域名的权威域名服务器
简单来讲:递归解析服务器是负责解析域名的,权威域名服务器是负责存储域名记录的
递归解析服务器通常由 ISP 提供,除此以外也有一些比较出名的公共递归解析服务器, 如谷歌的 8.8.8.8,联通的 114,BAT 也都有推出公共递归解析服务器,但性能最好的应该仍是你的ISP提供的,只是可能会有 DNS劫持的问题
缓存
因为整个解析过程很是复杂,因此 DNS 经过缓存技术来实现服务的鲁棒性。当递归nameserver 解析过 tool.chianaz.com 域名后,再次收到 tool.chinaz.com 查询时,它不会再走一遍递归解析流程,而是把上一次解析结果的缓存直接返回。而且它是分级缓存的,也就是说,当下次收到的是 www.chinaz.com 的查询时, 因为这台递归解析服务器已经知道 chinaz.com 的权威 nameserver,因此它只须要再向 chinaz.com nameserver 发送一个查询 www 的请求就能够了。
根域名服务器递归解析服务器是怎么知道根域名服务器的地址的呢?根域名服务器的地址是固定的,目前全球有13个根域名解析服务器,这13条记录持久化在递归解析服务器中:
为何只有 13 个根域名服务器呢,不是应该越多越好来作负载均衡吗?以前说过 DNS 协议使用了 UDP 查询, 因为 UDP 查询中能保证性能的最大长度是 512 字节,要让全部根域名服务器数据能包含在512字节的UDP包中, 根服务器只能限制在13个, 并且每一个服务器要使用字母表中单字母名
智能解析
智能解析,就是当一个域名对应多个 IP 时,当你查询这个域名的 IP,会返回离你最近的 IP。
因为国内不一样运营商之间的带宽很低,因此电信用户访问联通的IP就是一个灾难,而智能 DNS 解析就能解决这个问题。
智能解析依赖 EDNS 协议,这是 google 起草的 DNS 扩展协议, 修改比较简单,就是在 DNS 包里面添加 origin client IP, 这样 nameserver 就能根据 client IP 返回距离 client 比较近的 server IP 了
国内最新支持 EDNS 的就是 DNSPod 了,DNSPod 是国内比较流行的域名解析厂商,不少公司会把域名利用DNSPod 加速, 它已经被鹅厂收购
域名注册商
通常咱们要注册域名,都要须要找域名注册商,好比说我想注册 hello.com,那么我须要找com域名注册商注册hello域名。com的域名注册商不止一家, 这些域名注册商也是从ICANN 拿到的注册权, 参见如何申请成为.com域名注册商
那么,域名注册商 和 权威域名解析服务器 有什么关系呢?
域名注册商都会自建权威域名解析服务器,好比你在狗爹上申请一个.com下的二级域名,你并不须要搭建nameserver, 直接在godaddy控制中内心管理你的域名指向就能够了, 缘由就是你新域名的权威域名服务器默认由域名注册商提供。固然你也能够更换,好比从godaddy申请的境外域名,把权威域名服务器改为DNSPod,一方面加快国内解析速度,另外一方面还能享受DNSPod 提供的智能解析功能
用 bind 搭建域名解析服务器
因为网上介绍bind搭建的文章实在太多了,我就再也不赘述了, 喜欢动手的朋友能够网上搜一搜搭建教程,一步步搭建一个本地的nameserver 玩一玩。这里主要介绍一下bind 的配置文件吧
bind 的配置文件分两部分: bind配置文件 和 zone配置文件
bind 配置文件
bind 配置文件位于 /etc/named.conf
,它主要负责 bind 功能配置,如 zone 路径、日志、安全、主从等配置
其中最主要的是添加zone的配置以及指定zone配置文件。recursion 开启递归解析功能, 这个若是是no, 那么此bind服务只能作权威解析服务,当你的bind服务对外时,打开它会有安全风险,如何防护不当,会让你的nameserver 被hacker 用来作肉鸡
zone 配置文件
zone 的配置文件在 bind 配置文件中指定,下图是一份简单的 zone 配置:
zone的配置是 nameserver 的核心配置, 它指定了 DNS 资源记录,如 SOA、A、CNAME、AAAA 等记录,各类记录的概念网上资料太多,我这里就不重复了。其中主要讲一下 SOA 和 CNAME 的做用。
SOA记录
SOA 记录表示此域名的权威解析服务器地址。上文讲了权威解析服务器和递归解析服务器的差异, 当全部递归解析服务器中有没你域名解析的缓存时,它们就会回源来请求此域名的SOA记录,也叫权威解析记录
CNAME
CNAME 的概念很像别名,它的处理逻辑也如此。一个server 执行resloving 时,发现 name 是一个 CNAME, 它会转而查询这个 CNAME 的A记录。通常来讲,能使用CNAME的地方均可以用A记录代替, 那么为何还要发明 CNAME 这样一个东西呢?它是让多个域名指向同一个 IP 的一种快捷手段, 这样当最低层的 CNAME 对应的IP换了以后,上层的 CNAME 不用作任何改动。就像咱们代码中的硬编码,咱们总会去掉这些硬编码,用一个变量来表示,这样当这个变量变化时,咱们只须要修改一处
配置完以后能够用 named-checkconf
和 named-checkzone
两个命令来check咱们的配置文件有没有问题, 以后就能够启动 bind 服务了:
$> service named startRedirecting to /bin/systemctl restart named.service
咱们用 netstat -ntlp
来检查一下服务是否启动:
53 端口已启动,那么咱们测试一下效果, 用 dig 解析一下 www.hello.com 域名,使用127.0.0.1 做为递归解析服务器
咱们看到 dig 的结果跟咱们配置文件中配置的同样是 1.2.3.4,DNS 完成了它的使命,根据域名获取到 IP,但咱们这里用来作示范的IP明显是个假IP:)
用 DNS 实现负载均衡
一个域名添加多条A记录,解析时使用轮询的方式返回随机一条,流量将会均匀分类到多个A记录。
www IN A 1.2.3.4www IN A 1.2.3.5
复制代码上面的配置中,咱们给 www 域添加了两条A记录, 这种作法叫 multi-homed hosts, 它的效果是:当咱们请求 nameserver 解析 www.hello.com 域名时,返回的IP会在两个IP中轮转(默认行为,有些智能解析 DNS 会根据 IP 判断,返回一个离client近的IP,距离 请搜索 DNS 智能解析)。
其实每次DNS解析请求时,nameserver都会返回所有IP,如上面配置,它会把1.2.3.4 和1.2.3.5 都返回给client端。那么它是怎么实现RR的呢?nameserver 只是每次返回的IP排序不一样,客户端会把response里的第一个IP用来发请求。
DNS负载均衡 vs LVS专业负载均衡
和 LVS 这种专业负载均衡工具相比,在DNS层作负载均衡有如下特色:
-
实现很是简单
-
默认只能经过RR方式调度
-
DNS 对后端服务不具有健康检查
-
DNS 故障恢复时间比较长(DNS 服务之间有缓存)
-
可负载的 rs 数量有限(受 DNS response 包大小限制)
真实场景中,还须要根据需求选择相应的负载均衡策略
子域受权
咱们从 .com 域下申请一个二级域名 hello.com 后, 发展到某一天咱们的公司扩大了,须要拆分两个事业部A和B, 而且公司给他们都分配了三级域名 a.hello.com 和 b.hello.com, 域名结构以下图:
再发展一段时间,A部门和B部门内部业务太多,须要频繁的为新产品申请域名, 这个时候他们就想搭建本身的 namserver,而且须要上一级把相应的域名管理权交给本身,他们指望的结构以下:
注意第一阶段和第二阶段的区别:第一阶段,A 部门想申请 a.hello.com 下的子域名,须要向上级申请,整个 a.hello.com 域的管理都在总公司;第二阶段,A 部门先本身搭建 nameserver,而后总公司把 a.hello.com 域管理权转交给自建的 nameserver, 这个转交管理权的行为,就叫子域受权
子域受权分两部操做:
-
A部门自建 nameserver,而且在 zone 配置文件中指定 a.hello.com 的权威解析服务器为本身的 nameserver 地址
-
总公司在 nameserver 上增长一条 NS 记录, 把 a.hello.com 域受权给 A 部门的 nameserver
第一步咱们在用 bind 搭建域名解析服务器里讲过, 只要在 zone 配置文件里指定SOA记录就好:
@ IN SOA ns.a.hello.com admin.a.hello.com. (……)复制代码
第二步,在 hello.com 域的 nameserver 上添加一条NS记录:
a.hello.com IN NS ns.a.hello.comns.a.hello.com IN A xx.xx.xx.xx (自建nameserver的IP)复制代码
这样当解析 xx.a.hello.com 域名时,hello.com nameserver 发现配置中有 NS 记录,就会继续递归向下解析
DNS 调试工具
OPS 经常使用的 DNS 调试工具备:host,nslookup,dig
这三个命令都属于 bind-utils 包, 也就是 bind 工具集,它们的使用复杂度、功能 依次递增。关于它们的使用, man 手册和网上有太多教程,这里简单分析一下dig命令的输出吧:
dig 的参数很是多, 功能也不少,详细使用方法你们自行man吧
其余
DNS 放大攻击
DNS 放大攻击属于DoS攻击的一种,是经过大量流量占满目标机带宽, 使得目标机对正经常使用户的请求拒绝链接从而挂掉。
思路
正常的流量攻击,hack 机向目标机创建大量 request-response,但这样存在的问题是须要大量的 hack 机器。由于服务器通常的带宽远大于家用网络, 若是咱们本身的家用机用来作 hack 机器,还没等目标机的带宽占满,咱们的带宽早超载了。
原理
DNS 递归解析的流程比较特殊, 咱们能够经过几个字节的 query 请求,换来几百甚至几千字节的 resolving 应答(流量放大), 而且大部分服务器不会对DNS服务器作防护。那么 hacker 们只要能够假装 DNS query 包的 source IP, 从而让 DNS 服务器发送大量的 response 到目标机,就能够实现 DoS 攻击。
但通常经常使用的 DNS 服务器都会对攻击请求作过滤,因此找 DNS 服务器漏洞也是一个问题。详细的放大攻击方法你们有兴趣自行 google 吧,这里只作一个简单介绍 :)