Osheep

时光不回头,当下最重要。

DNS通讯过程简介

网上有很多文章讲解DNS原理,很多写的很不错,但是有些太过宏观,有些又过于细节。但作为一个码农,不想止于宏观概念,又不想深陷实现细节,就想知道DNS通讯的过程。。。如果你也是一样的想法,你就来对了地方。

DNS通讯过程概要

首先请看一个典型的DNS通讯示意图(以访问www.qq.com为例)

《DNS通讯过程简介》

实际的DNS通讯过程非常复杂,比如上述⑦,因为有CDN加速可能有多次NS查询以返回最佳IP,又比如有DNS服务器为了安全会有反向查询(从IP查名称),还有DNSSEC相关查询,上图为了说明故意简化。

名词解释

user process:请求通过名称得到IP地址访问网络的用户程序,例如IE。

DNS Resolver:接受DNS查询,代理用户进程获取域名对应的IP地址。可以作为单独进程,也可作为用户进程的一部分。根据功能不同,又可分为Stub Server和Full-Service Resolver.

Stub Resolver:接受DNS查询,有缓存功能的,先在缓存查找,若命中直接返回,若没有命中,直接转发查询请求到Full-Service Resolver。如果没有缓存功能,就直接转发请求。Full-Service Resolver的地址是直接配置的。如下图

《DNS通讯过程简介》

10开头的是局域网DNS服务器,另外2个是运营商提供的DNS服务器(冗余备份作用),实际上只需要保留10开头的那个。另外完全可以自己指定比如8.8.8.8,还不用接受GW的域名审查。

Full-Service Resolver:接受DNS查询,先在缓存查找,若命中直接返回,若没有命中,就开始递归查询Authority Name Server(权威名称服务器),直到查询到目标地址或者超时,并且缓存查询结果。递归查询(Recursive Query)的起点根服务器(13台)的IP地址,是提前配置在服务器上。另外,还可以作为本地网络的权威名称服务器,自定义内部网络的名称和IP映射。

Authority Name Server:接受DNS查询,如果存在查询请求的答案则直接返回答案;如果是子域名查询,则返回子域名名称服务器地址;否则,直接拒绝。

验证一下

准备工作

首先在Ubuntu上安装bind9(bind9是功能全面的DNS服务器,通过配置可以作为Full-Service Resolver或者Authority Name Server)。

安装命令如下:

sudo apt install bind9

更改配置

sudo vi /etc/bind/named.conf.options

作为Full-Service Resolver

配置文件如下


options {

forwarders {

8.8.8.8;//如果没有命中缓存,则转发查询请求到8.8.8.8,那么8.8.8.8充当Full-Service Resolver(由此可知DNS查询可以转发请求,形成查询处理链)。如果没有配置转发,开始递归查询,如示意图所示。

};

dnssec-validation no;

auth-nxdomain no;    # conform to RFC1035

recursion yes;//允许递归查询,否则只能充当权威名称服务器,而权威名称服务器只返回自己管辖范围的主机或者子域名查询请求,其他直接拒绝。

};

启动bind9

sudo systemctl start bind9

验证是否启动成功

sudo systemctl status bind9

在windows(192.168.2.100)上,安装wireshark(免费,去baidu找一下),并启动监听。

在Ubuntu(192.168.2.106)上,输入下列命令,启动DNS通讯监控

sudo tcpdump -li any ‘udp port 53’

在windows命令行输入

nslookup – 192.168.2.106

为了简化通讯,接着输入

set retry=1

set type=A

开始查询,接着输入

www.qq.com

wireshark在windows上监控如下

《DNS通讯过程简介》

只有2个包通讯,一个请求,一个应答

Ubuntu监控如下

《DNS通讯过程简介》

查询请求转发给8.8.8.8(google-public-dns),接收应答并缓存,然后转发给DNS查询客户端(上述windows)

在windows上再次输入

www.qq.com

Ubuntu上监控如下

《DNS通讯过程简介》

有缓存,不再转发,直接返回缓存结果

作为权威名称服务器

更改配置文件如下

sudo vi /etc/bind/named.conf.options

options {

forwarders {

8.8.8.8;//recursion no的情况下转发无效

};

dnssec-validation no;

auth-nxdomain no;    # conform to RFC1035

recursion no;

};

编辑本地zone文件

sudo vi /etc/bind/named.conf.local

添加以下内容

zone “my.net” IN {

type master;

file “/etc/bind/db.mynet”;

};

添加mynet的配置文件

sudo vi /etc/bind/db.mynet

$TTL 7200

@ IN SOA ns admin (

2017060909

3600

900

604800

86400

)

@            IN NS ns

ns IN A  10.100.99.195

dav IN A 10.100.99.195

www IN A 10.100.99.195

simon IN A  10.100.99.221

重启bind9

sudo systemctl restart bind9

sudo systemctl status bind9

在windows上输入以下命令

nslookup – 192.168.2.106

set retry=1

set type=A

www.qq.com

wireshark监控如下

《DNS通讯过程简介》

只作为名称服务器,对于其他域的查询直接拒绝

Ubuntu监控如下

《DNS通讯过程简介》

只作为名称服务器,对于其他域的查询直接拒绝

作为Full-Service Resolver,但不设置转发的情形

没有做。。。

还有更多的pattern,请各位自己去试验啦。

总结

通过搭建DNS服务器以及包监控工具,验证了本文开始部分的DNS通讯示意图。实际的DNS通讯远比上述复杂。特别是DNS是明文通讯,为了确保DNS通讯安全,防止拦截,劫持,钓鱼,DNS通讯规范引入DNSSEC,一种类似数字签名的技术来确保DNS通讯安全。有兴趣的读者,可以继续调查。

参考

http://www.ruanyifeng.com/blog/2016/06/dns.html

http://www.ietf.org/rfc/rfc1123.txt

点赞