最近在做网络安全方面的相关工作,涉及到域名dns解析、暴力破解等,这个过程中深入学习了dns相关知识。很多知识以前不了解、了解的不够深入,所以决定写一篇较为完整的dns知识汇总。
DNS——Domain Name System,中文的意思是域名系统。
在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析系统来完成,DNS就是进行域名解析的系统。而我们在平时讨论的DNS,其实就是在讨论DNS解析。
全球共有13台根逻辑域名服务器。这13台逻辑根域名服务器中名字分别为“A”至“M”,真实的根服务器在2014年1月25日的数据为386台,分布于全球各大洲。根域名服务器是架构因特网所必须的基础设施。在国外,许多计算机科学家将根域名服务器称作“真理”(TRUTH),足见其重要性。换句话说——攻击整个因特网最有力、最直接,也是最致命的方法恐怕就是攻击根域名服务器了。
在根域名服务器中虽然没有每个域名的具体信息,但储存了负责每个域(如.com, .cn, .ren, .top等)的解析的域名服务器的地址信息,如同通过北京电信你问不到广州市某单位的电话号码,但是北京电信可以告诉你去查020114。世界上所有互联网访问者的浏览器都将域名转化为IP地址的请求(浏览器必须知道数字化的IP地址才能访问网站)理论上都要经过根服务器的指引后去该域名的权威域名服务器(authoritative domain name server) ,当然现实中提供接入服务的ISP的缓存域名服务器上可能已经有了这个对应关系(域名到IP地址)的缓存。
DNS的协议设计比较特殊,同时占用UDP和TCP端口53,那么DNS分别在什么情况下使用这两种协议呢。
我们知道,UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同,TCP是一种可靠的网络协议,而UDP是一种不可靠的网络协议,不过在有些情况下UDP协议非常有用。
UDP:速度优势。
TCP:稳定优势。
DNS的规范规定了2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone transfer)。
DNS在进行区域传输的时候使用TCP协议,其它时候则使用UDP协议。
具有TCP所望尘莫及的速度优势。虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。
区域传送时使用TCP,主要有一下两点考虑:
1. 辅域名服务器会定时(一般时3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用TCP而不是UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。
2.TCP是一种可靠的连接,保证了数据的准确性。
域名解析时使用UDP协议:
客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向DNS服务器查询的时候使用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
UDP查询和响应中能保证正常工作的最大长度是512字节。
要让所有的根服务器数据能包含在一个512字节的UDP包中,根服务器只能限制在13个,而且每个服务器要使用字母表中的单个字母命名,这也是根服务器是从A到M命名的原因。
具体如何算出13,不在这里深入讨论,具体可参考http://www.root-servers.org/,这个网站给出了详细的根节点说明。
最常用的查询类型是A类型,表示期望获得查询名的IP地址。一个PTR查询则请求获得一个IP地址对应的域名,这是一个指针查询。
A: IP地址
NS: 名字服务器
CNAME: 规范名称
PTR: 指针记录,即IP到域名的反向查询
HINFO: 主机信息
MX: 邮件交换记录
AXFR: 区域传送请求
*/ANY: 对所有记录的请求
这里以万网的设置为例,域名持有者可以做如下设置:
A记录:将域名指向一个IPv4地址(例如:10.10.10.10),需要增加A记录。
CNAME记录:如果将域名指向一个域名,实现与被指向域名相同的访问效果,需要增加CNAME记录。
MX记录:建立电子邮箱服务,将指向邮件服务器地址,需要设置MX记录。
NS记录:域名解析服务器记录,如果要将子域名指定某个域名服务器来解析,需要设置NS记录。
TXT记录:可任意填写(可为空),通常用做SPF记录(反垃圾邮件)使用。
AAAA记录:将主机名(或域名)指向一个IPv6地址(例如:ff03:0:0:0:0:0:0:c1),需要添加AAAA记录。
SRV记录:记录了哪台计算机提供了哪个服务。格式为:服务的名字.协议的类型(例如:_example-server._tcp)。
显性URL:将域名指向一个http(s)协议地址,访问域名时,自动跳转至目标地址(例如:将www.net.cn显性转发到www.hichina.com后,访问www.net.cn时,地址栏显示的地址为:www.hichina.com)。
隐性URL:与显性URL类似,但隐性转发会隐藏真实的目标地址(例如:将www.net.cn隐性转发到www.hichina.com后,访问www.net.cn时,地址栏显示的地址仍然为:www.net.cn)。
A记录,设置a.ranshy.com为A记录,指向ip地址121.42.153.188。服务器查询时间381ms,为A记录,都能很清晰地显示出来。
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6 <<>> a.ranshy.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54963
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;a.ranshy.com. IN A
;; ANSWER SECTION:
a.ranshy.com. 599 IN A 121.42.153.188
;; Query time: 381 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Sep 26 22:00:40 2016
;; MSG SIZE rcvd: 46
CNAME,那么我们接下来设置一个cname.ranshy.com,指向a.ranshy.com。再次查询,会发现ANSWER里面有两条记录。
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6 <<>> cname.ranshy.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17530
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;cname.ranshy.com. IN A
;; ANSWER SECTION:
cname.ranshy.com. 600 IN CNAME a.ranshy.com.
a.ranshy.com. 600 IN A 121.42.153.188
;; Query time: 417 msec
;; SERVER: 74.82.42.42#53(74.82.42.42)
;; WHEN: Mon Sep 26 22:04:35 2016
;; MSG SIZE rcvd: 66
继续追加CNAME,从结果可以看到,有点递归的意思。
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6 <<>> cname2.ranshy.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58274
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;cname2.ranshy.com. IN A
;; ANSWER SECTION:
cname2.ranshy.com. 599 IN CNAME cname.ranshy.com.
cname.ranshy.com. 599 IN CNAME a.ranshy.com.
a.ranshy.com. 599 IN A 121.42.153.188
;; Query time: 1046 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Sep 26 22:08:13 2016
;; MSG SIZE rcvd: 87
DNS协议不鼓励指向CNAME的CNAME,因为这样会导致cname loop,同时会增加解析时间。
万网设置中,除了常见的A/CNAME等,还有的设置是显性url和隐性url,也进行测试。
显性URL:将域名指向一个http(s)协议地址,访问域名时,自动跳转至目标地址(例如:将www.net.cn显性转发到www.hichina.com后,访问www.net.cn时,地址栏显示的地址为:www.hichina.com)。
隐性URL:与显性URL类似,但隐性转发会隐藏真实的目标地址(例如:将www.net.cn隐性转发到www.hichina.com后,访问www.net.cn时,地址栏显示的地址仍然为:www.net.cn)。
如图所示,我分别设置了两个域名指向,均指向www.baidu.com,不过一个是显性一个是隐性。
用dig进行查询,会发现是A记录,而且是一个我不知道的ip地址。也就是说,显/隐性url实际上就是一个A记录,指向了万网提供的服务器而已。
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6 <<>> dominant.ranshy.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19322
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;dominant.ranshy.com. IN A
;; ANSWER SECTION:
dominant.ranshy.com. 599 IN A 42.156.141.13
;; Query time: 293 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Sep 26 22:13:05 2016
;; MSG SIZE rcvd: 53
#结果一模一样,都是A记录
root [~] dig recessive.ranshy.com
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6 <<>> recessive.ranshy.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38623
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;recessive.ranshy.com. IN A
;; ANSWER SECTION:
recessive.ranshy.com. 599 IN A 42.156.141.13
;; Query time: 306 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Sep 26 22:18:24 2016
;; MSG SIZE rcvd: 54
不过,通过浏览器访问,会发现都会访问到baidu页面,一个url地址变成了baidu,一个url地址没有变化,通过curl就知道原因了:
root [~] curl dominant.ranshy.com -i
HTTP/1.1 302 Found
Server: Tengine
Date: Tue, 27 Sep 2016 02:13:21 GMT
Content-Type: text/html;charset=utf8
Content-Length: 0
Connection: close
Location: http://www.baidu.com
#查看隐性
root [~] curl recessive.ranshy.com -i
HTTP/1.1 200 OK
Server: Tengine
Date: Tue, 27 Sep 2016 02:22:57 GMT
Content-Type: text/html;charset=utf8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding
<frameset rows="100%">
<frame src="http://www.baidu.com">
<noframes>
请点击下面链接: <a href="http://www.baidu.com">link</a>
</noframes>
</frameset>
发现问题在哪里了吧。
最后,对于dns查询,建议多学一下dig命令。
Leave a Reply