最近在做网络安全方面的相关工作,涉及到域名dns解析、暴力破解等,这个过程中深入学习了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协议
  • 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查询包。

  • 13个根域名服务器的由来

  • 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)。

  • DNS查询测试
  • A记录,设置a.ranshy.com为A记录,指向ip地址121.42.153.188。服务器查询时间381ms,为A记录,都能很清晰地显示出来。

    root [~] dig a.ranshy.com

    ; <<>> 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里面有两条记录。

    root [~] dig cname.ranshy.com

    ; <<>> 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,从结果可以看到,有点递归的意思。

    root [~] dig cname2.ranshy.com

    ; <<>> 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记录,指向了万网提供的服务器而已。

    root [~] dig dominant.ranshy.com      

    ; <<>> 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命令。