﻿# 釐清 DNS Client 查詢過程的異象 ( 當名稱伺服器停用遞迴時 )

記得在今年年初的時候我曾經遇到一個 DNS 查詢的疑問，百思不得其解，詢問了幾位專家但依然無法重現或解釋我所遇到的疑問，但昨天晚上不知為何突然開竅想通了，可能是最近在帶新進的 IT 同仁時傳授了許多與 DNS 相關的基礎知識，而在講授的過程中也讓自己的觀念更加的清晰，才會在昨天重新回想半年多前的疑問時靈光乍現，並快速的驗證這次釐清的 DNS 觀念，感覺真不錯。

之前的疑問是這樣的，我們公司有個合作夥伴用 Linux 架設了一台 DNS 名稱伺服器 (NS) 給我們客戶使用，該 NS 主要的用途是讓外面用來查詢客戶擁有的 Domain Name 相關紀錄之用，並不是供機房網路的主機設定為主要名稱伺服器之用，所以我會用這台 NS 查詢客戶的 DNS 紀錄是否設定正確 (如 A 紀錄)。

有一天心血來潮，我用 nslookup 工具查詢一個外部網域網址發現查詢時回傳的結果與我以往的查詢經驗並不相符，以我自己架設的 DNS 名稱伺服器來說，查詢時的回傳結果是這樣的：

```
C:\>nslookup -type=a microsoft.com 211.78.85.85 伺服器:  UnKnown Address:  211.78.85.85 *** UnKnown 找不到 microsoft.com: Query refused
```

為什麼會回應 Query refused 呢？那是因為我的 DNS 名稱伺服器並不提供遞迴查詢，也就是我的 DNS 名稱伺服器只能用來查詢在這台 NS 所管理的 Domain Name 而已，並且拒絕查詢任何其他的網址。

但是由我們合作夥伴所提供的 DNS 名稱伺服器查詢到的結果卻不是 Query refused，而是一堆 **根提示** ( [Root Hint](http://icannwiki.org/Root_hints) ) 的資料，如下執行結果：

```
C:\>nslookup -type=mx miniasp.com 203.xxx.xxx.xxx139.69.203.in-addr.arpa nameserver = ns3.idc.hinet.net139.69.203.in-addr.arpa nameserver = ns.idc.hinet.net139.69.203.in-addr.arpa nameserver = ns2.idc.hinet.netns.idc.hinet.net        internet address = 210.59.224.123ns2.idc.hinet.net       internet address = 210.59.231.120伺服器:  UnKnownAddress:  203.xxx.xxx.xxxcom     nameserver = j.gtld-servers.netcom     nameserver = k.gtld-servers.netcom     nameserver = l.gtld-servers.netcom     nameserver = m.gtld-servers.netcom     nameserver = a.gtld-servers.netcom     nameserver = b.gtld-servers.netcom     nameserver = c.gtld-servers.netcom     nameserver = d.gtld-servers.netcom     nameserver = e.gtld-servers.netcom     nameserver = f.gtld-servers.netcom     nameserver = g.gtld-servers.netcom     nameserver = h.gtld-servers.netcom     nameserver = i.gtld-servers.neta.gtld-servers.net      internet address = 192.5.6.30a.gtld-servers.net      AAAA IPv6 address = 2001:503:a83e::2:30b.gtld-servers.net      internet address = 192.33.14.30b.gtld-servers.net      AAAA IPv6 address = 2001:503:231d::2:30c.gtld-servers.net      internet address = 192.26.92.30d.gtld-servers.net      internet address = 192.31.80.30e.gtld-servers.net      internet address = 192.12.94.30f.gtld-servers.net      internet address = 192.35.51.30g.gtld-servers.net      internet address = 192.42.93.30h.gtld-servers.net      internet address = 192.54.112.30i.gtld-servers.net      internet address = 192.43.172.30j.gtld-servers.net      internet address = 192.48.79.30k.gtld-servers.net      internet address = 192.52.178.30l.gtld-servers.net      internet address = 192.41.162.30
```

  

當時就是卡在這裡，不懂為何會有這樣的差異。

昨天我比對了 Microsoft DNS 的管理介面的選項，這才瞭解原來 Linux 的 Bind 名稱伺服器可以設定當沒有轉寄站(Forwarder)或提供遞迴查詢時可以設定是否回應根提示，當 DNS Client 到 NS 查詢且在**快取**(DNS Cache)或遞迴查詢都查不到網址時就會回傳根提示，如下圖示：

![alt](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/5fd8870944ac03a14f8a-image_392.png "title")

由於我以前一直以來都是用 Linux 當做 DNS 名稱伺服器，也沒特別深入研究這之間的差異，但透過 GUI 的提示反倒能讓一些以往習得的經驗與理論更快速的得到證實。

**備註**: 在 Linux 下的 Bind 預設可以拒絕查詢所有遞迴查詢同時也停用回應根提示，但在 Microsoft DNS 我找不到相關設定!

**※ 額外補充 **※****

Microsoft DNS 若當成對外查詢的 DNS 伺服器時，記得要勾選 **停用遞迴 (同時停用轉寄站)** 這個伺服器選項，以避免遞迴查詢的額外增加了 DNS 伺服器本身的負載，如下圖示：

![alt](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/5690dc700fb583e83f74-image_393.png "title")

**相關連結**

-   [Root hints – ICANNWiki](http://icannwiki.org/Root_hints)
-   [What are root hints?](https://web.archive.org/web/20110916100424/http://www.ucertify.com:80/article/what-are-root-hints.html)
-   [DNS Root Hints in Windows 2003](https://www.computerperformance.co.uk/services/dns-root-hints/)
-   [DNS Conditional Forwarding in Windows Server 2003](http://www.windowsnetworking.com/articles_tutorials/DNS_Conditional_Forwarding_in_Windows_Server_2003.html)
-   [Setting up a Forwarding DNS Server (or DNS Proxy) with ISC BIND](http://gleamynode.net/articles/2267/)
-   [Troubleshooting DNS](http://technet.microsoft.com/en-us/library/bb726934.aspx)
-   nslookup 使用說明
