关于 DNS 这块,TCP/IP协议详解 有专门一章讲解,入门非常合适。这里再补充一些其它方面的。

首先看下 DNS 首部结构图,图片来至 http://www.troyjessup.com (这个网站好像无法打开了,从其它站点找到的图):

DNS HEADER

例1:

$ dig tankywoo.com @114.114.114.114 A

; <<>> DiG 9.10.3-P2 <<>> tankywoo.com @114.114.114.114 A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12839
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 11

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;tankywoo.com.                  IN      A

;; ANSWER SECTION:
tankywoo.com.           496     IN      A       192.168.1.100

;; AUTHORITY SECTION:
tankywoo.com.           86370   IN      NS      f1g1ns2.dnspod.net.
tankywoo.com.           86370   IN      NS      f1g1ns1.dnspod.net.

;; ADDITIONAL SECTION:
f1g1ns1.dnspod.net.     3928    IN      A       180.163.19.15
f1g1ns1.dnspod.net.     3928    IN      A       182.140.167.166
...

;; Query time: 3 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Mon Aug 28 08:43:08 UTC 2017
;; MSG SIZE  rcvd: 271

DNS 包的 Flags

具体可以看看 RFC 1035Header section format 部分。

常见的如:

也可以看看 DNS, Domain Name System

递归(Recursive)和迭代(Iterative)

迭代,即非递归(Non-Recursive)。

如上例1中 ;; flags: qr rd ra;,一般的 dns 请求工具如 dig,默认都是期望递归(rd),并且一般我们直接请求的 ns 服务器也支持递归请求(ra)。

如下这幅图,图片来源

Recursive and Iterative

可以看到 1, 8 这个过程是递归查询,其余是非递归查询。一般我们直接请求的 ns 服务器承担了递归、转发(forward)、缓存的作用。

如果查询的域名没有在缓存和zone中,则向根域请求,根域是非递归服务器,会告诉请求ns需要向哪个ns服务器作查询,然后迭代直到查到记录并返回给用户。

直接执行 dig 可以获取所有根域服务器。

如果不想递归请求,针对 dig 可以:

dig +norecurse tankywoo.com A @114.114.114.114

再比如 DNS 服务器使用 bind 的话,可以设置 recursion no 使 NS 服务器作为一个非递归服务器,这时 dig 查询可以看到没有 ra 这个标记。

权威(Authoritative) DNS

权威DNS就是管理域名zone记录的DNS服务器,DNS查询最终会到权威DNS并返回记录。

比如DNSPOD提供的NS服务,我们可以将域名放到DNSPOD上解析,在权威上可以设置,修改,删除该区域内的解析记录,而非权威DNS只能是查询。

具体可以可以看维基百科 Authoritative name server

如下这幅图,图片来源

Authoritative DNS

可以看到,中间经过递归查询,最终查询到权威服务器,然后返回记录。

例1中的 ;; AUTHORITY SECTION: 就是授权DNS部分。

通过 nslookup 命令也可以看:

# 直接查询的 dns 是非授权服务器
root ~ % nslookup tankywoo.com 114.114.114.114
Server:         114.114.114.114
Address:        114.114.114.114#53

Non-authoritative answer:   // <- 注意这个说明
Name:   tankywoo.com
Address: 192.168.1.100

# 直接查询的 dns 是授权服务器
root ~ % nslookup tankywoo.com f1g1ns2.dnspod.net.
Server:         f1g1ns2.dnspod.net.
Address:        182.140.167.188#53

Name:   tankywoo.com
Address: 192.168.1.100

Bind 中的转发与递归

在 Bind 中,转发是通过 forwardforwarders 来配置的,比如配置 forward only 则此 DNS 服务器只将请求转到 forwarders 列表中,而不请求到 root server。

通过抓包也可以看到,比如A记录查询,在 first first 时会只向 forwarders 请求 A 记录;而后者则会同时请求 A 记录,如果没有则向 root server 请求。

这两者本身来说没有什么关联性,递归是一种查询/响应的方式,而转发则是对查询请求的处理方式。

一个常见的使用尝试就是个人部署一个只做转发的DNS缓存服务器。

扩展阅读:

扩展阅读