一文搞懂 DNS 基礎知識,收藏起來有備無患~

DNS(Domain Name System), 也叫網域名稱系統,是互聯網的一項服務。它實質上是一個 域名 和 IP 相互映射的分佈式數據庫,有了它,咱們就能夠經過域名更方便的訪問互聯網。git

DNS 有如下特色:github

  • 分佈式的數據庫

  • 協議支持 TCP 和 UDP,經常使用端口是 53後端

  • 每一級域名的長度限制是 63瀏覽器

  • 域名總長度限制是 253緩存

那麼,什麼狀況下使用 TCP,什麼狀況下使用 UDP 呢?安全

最先的時候,DNS 的 UDP 報文上限大小是 512 字節, 因此當某個 response 大小超過512 (返回信息太多),DNS 服務就會使用 TCP 協議來傳輸。後來 DNS 協議擴展了本身的UDP 協議,DNS client 發出查詢請求時,能夠指定本身能接收超過512字節的 UDP 包, 這種狀況下,DNS 仍是會使用 UDP 協議。服務器

分層的數據庫結構

DNS 的結構跟 Linux 文件系統很類似,像一棵倒立的樹。下面用站長之家的域名舉例:網絡

最上面的.是根域名,接着是頂級域名com,再下來是站長之家域名 chinaz 依次類推。使用域名時,從下而上。s.tool.chinaz.com. 就是一個完整的域名,www.chinaz.com. 也是。負載均衡

之因此設計這樣複雜的樹形結構, 是爲了防止名稱衝突。這樣一棵樹結構,固然能夠存儲在一臺機器上,但現實世界中完整的域名很是多,而且天天都在新增、刪除大量的域名,存在一臺機器上,對單機器的存儲性能就是不小的挑戰。另外,集中管理還有一個缺點就是管理不夠靈活。能夠想象一下,每次新增、刪除域名都須要向中央數據庫申請是多麼麻煩。因此現實中的 DNS 都是分佈式存儲的。

根域名服務器只管理頂級域,同時把每一個頂級域的管理委派給各個頂級域,因此當你想要申請com下的二級域名時,找 com 域名註冊中心就行了。例如你申請了上圖的 chinaz.com 二級域名,chinaz.com 再向下的域名就歸你管理了。當你管理 chinaz.com 的子域名時,你能夠搭建本身的 nameserver,在 .com 註冊中心把 chinaz.com 的管理權委派給本身搭建的nameserver。自建nameserver 和不自建的結構圖以下:

通常狀況下,能不自建就不要自建,由於維護一個高可用的 DNS 也並不是容易。據我所知,有兩種狀況須要搭建本身的 nameserver:

  1. 搭建對內的 DNS。公司內部機器衆多,經過 IP 相互訪問太過凌亂,這時能夠搭建對內的 nameserver,容許內部服務器經過域名互通

  2. 公司對域名廠商提供的 nameserver 性能不滿意。雖然頂級域名註冊商都有本身的nameserver,但註冊商提供的 nameserver 並不專業,在性能和穩定性上沒法知足企業需求,這時就須要企業搭建本身的高性能 nameserver,好比增長智能解析功能,讓不一樣地域的用戶訪問最近的 IP,以此來提升服務質量

歸納一下 DNS 的分佈式管理, 當把一個域委派給一個nameserver後,這個域下的管理權都交由此nameserver處理。這種設計一方面解決了存儲壓力,另外一方面提升了域名管理的靈活性 (這種結構像極了Linux File System, 能夠把任何一個子目錄掛載到另外一個磁盤,還能夠把它下面的子目錄繼續掛載出去)

頂級域名

像 com 這樣的頂級域名,由 ICANN 嚴格控制,是不容許隨便建立的。頂級域名分兩類:

  • 通用頂級域名

  • 國家頂級域名

通用頂級域名常見的如.com、.org、.edu等, 國家頂級域名如我國的.cn, 美國的.us。通常公司申請公網域名時,若是是跨國產品,應該選擇通用頂級域名;若是沒有跨國業務,看本身喜愛(能夠對比各家頂級域的服務、穩定性等再作選擇)。這裏說一下幾個比較熱的頂級域,完整的頂級域參見維基百科。

me
me頂級域實際上是國家域名, 是黑山共和國的國家域名,只不過它對我的開發申請,因此不少我的博主就用它做爲本身的博客域名(本博客也是這麼來的~)

io
不少開源項目經常使用io作頂級域名,它也是國家域名。由於io 與計算機中的 input/output 縮寫相同,和計算機的二機制10也很像,給人一種geek的感受。相較於.com域名,.io下的資源不少,更多選擇。

DNS 解析流程

聊完了 DNS 的基本概念,咱們再來聊一聊 DNS 的解析流程。當咱們經過瀏覽器或者應用程序訪問互聯網時,都會先執行一遍 DNS 解析流程。標準 glibc 提供了 libresolv.so.2 動態庫,咱們的應用程序就是用它進行域名解析(也叫 resolving)的, 它還提供了一個配置文件/etc/nsswitch.conf 來控制 resolving 行爲,配置文件中最關鍵的是這行:

 
  •  
hosts: files dns myhostname

它決定了 resolving 的順序,默認是先查找 hosts 文件,若是沒有匹配到,再進行 DNS 解析。默認的解析流程以下圖:

上圖主要描述了 client 端的解析流程,咱們能夠看到最主要的是第四步請求本地 DNS 服務器去執行 resolving,它會根據本地 DNS 服務器配置,發送解析請求到遞歸解析服務器(稍後介紹什麼是遞歸解析服務器), 本地 DNS 服務器在 /etc/resolv.conf 中配置。下面咱們再來看看服務端的 resolving 流程:

咱們分析一下解析流程:

  1. 客戶端向本地DNS服務器(遞歸解析服務器) 發出解析tool.chinaz.com域名的請求

  2. 本地dns服務器查看緩存,是否有緩存過tool.chinaz.com域名,若是有直接返回給客戶端;

    若是沒有執行下一步

  3. 本地dns服務器向根域名服務器發送請求,查詢com頂級域的nameserver 地址

  4. 拿到com域名的IP後,再向com nameserver發送請求,獲取chinaz域名的nameserver地址

  5. 繼續請求 chinaz 的nameserver,獲取 tool 域名的地址,最終獲得了tool.chinaz.com 的 IP,本地 dns 服務器把這個結果緩存起來,以供下次查詢快速返回

  6. 本地dns服務器把把結果返回給客戶端

遞歸解析服務器 vs 權威域名服務器

咱們在解析流程中發現兩類 DNS 服務器,客戶端直接訪問的是 遞歸解析服務器, 它在整個解析過程當中也最忙。它的查詢步驟是遞歸的,從根域名服務器開始,一直詢問到目標域名。

遞歸解析服務器經過請求一級一級的權威域名服務器,得到下一目標的地址,直到找到目標域名的權威域名服務器

簡單來講:遞歸解析服務器是負責解析域名的,權威域名服務器是負責存儲域名記錄的

遞歸解析服務器通常由 ISP 提供,除此以外也有一些比較出名的公共遞歸解析服務器, 如谷歌的 8.8.8.8,聯通的 114,BAT 也都有推出公共遞歸解析服務器,但性能最好的應該仍是你的ISP提供的,只是可能會有 DNS劫持的問題

緩存

因爲整個解析過程很是複雜,因此 DNS 經過緩存技術來實現服務的魯棒性。當遞歸nameserver 解析過 tool.chianaz.com 域名後,再次收到 tool.chinaz.com 查詢時,它不會再走一遍遞歸解析流程,而是把上一次解析結果的緩存直接返回。而且它是分級緩存的,也就是說,當下次收到的是 www.chinaz.com 的查詢時, 因爲這臺遞歸解析服務器已經知道 chinaz.com 的權威 nameserver,因此它只須要再向 chinaz.com nameserver 發送一個查詢 www 的請求就能夠了。

根域名服務器遞歸解析服務器是怎麼知道根域名服務器的地址的呢?根域名服務器的地址是固定的,目前全球有13個根域名解析服務器,這13條記錄持久化在遞歸解析服務器中:

爲何只有 13 個根域名服務器呢,不是應該越多越好來作負載均衡嗎?以前說過 DNS 協議使用了 UDP 查詢, 因爲 UDP 查詢中能保證性能的最大長度是 512 字節,要讓全部根域名服務器數據能包含在512字節的UDP包中, 根服務器只能限制在13個, 並且每一個服務器要使用字母表中單字母名

智能解析

智能解析,就是當一個域名對應多個 IP 時,當你查詢這個域名的 IP,會返回離你最近的 IP。

因爲國內不一樣運營商之間的帶寬很低,因此電信用戶訪問聯通的IP就是一個災難,而智能 DNS 解析就能解決這個問題。

智能解析依賴 EDNS 協議,這是 google 起草的 DNS 擴展協議, 修改比較簡單,就是在 DNS 包裏面添加 origin client IP, 這樣 nameserver 就能根據 client IP 返回距離 client 比較近的 server IP 了

國內最新支持 EDNS 的就是 DNSPod 了,DNSPod 是國內比較流行的域名解析廠商,不少公司會把域名利用DNSPod 加速, 它已經被鵝廠收購

域名註冊商

通常咱們要註冊域名,都要須要找域名註冊商,好比說我想註冊 hello.com,那麼我須要找com域名註冊商註冊hello域名。com的域名註冊商不止一家, 這些域名註冊商也是從ICANN 拿到的註冊權, 參見如何申請成爲.com域名註冊商

那麼,域名註冊商 和 權威域名解析服務器  有什麼關係呢?

域名註冊商都會自建權威域名解析服務器,好比你在狗爹上申請一個.com下的二級域名,你並不須要搭建nameserver, 直接在godaddy控制中內心管理你的域名指向就能夠了, 緣由就是你新域名的權威域名服務器默認由域名註冊商提供。固然你也能夠更換,好比從godaddy申請的境外域名,把權威域名服務器改爲DNSPod,一方面加快國內解析速度,另外一方面還能享受DNSPod 提供的智能解析功能

用 bind 搭建域名解析服務器

因爲網上介紹bind搭建的文章實在太多了,我就再也不贅述了, 喜歡動手的朋友能夠網上搜一搜搭建教程,一步步搭建一個本地的nameserver 玩一玩。這裏主要介紹一下bind 的配置文件吧

bind 的配置文件分兩部分: bind配置文件 和 zone配置文件

bind 配置文件

bind 配置文件位於 /etc/named.conf,它主要負責 bind 功能配置,如 zone 路徑、日誌、安全、主從等配置

其中最主要的是添加zone的配置以及指定zone配置文件。recursion 開啓遞歸解析功能, 這個若是是no, 那麼此bind服務只能作權威解析服務,當你的bind服務對外時,打開它會有安全風險,如何防護不當,會讓你的nameserver 被hacker 用來作肉雞

zone 配置文件

zone 的配置文件在 bind 配置文件中指定,下圖是一份簡單的 zone 配置:

zone的配置是 nameserver 的核心配置, 它指定了 DNS 資源記錄,如 SOA、A、CNAME、AAAA 等記錄,各類記錄的概念網上資料太多,我這裏就不重複了。其中主要講一下 SOA 和 CNAME 的做用。

SOA記錄

SOA 記錄表示此域名的權威解析服務器地址。上文講了權威解析服務器和遞歸解析服務器的差異, 當全部遞歸解析服務器中有沒你域名解析的緩存時,它們就會回源來請求此域名的SOA記錄,也叫權威解析記錄

CNAME

CNAME 的概念很像別名,它的處理邏輯也如此。一個server 執行resloving 時,發現 name 是一個 CNAME, 它會轉而查詢這個 CNAME 的A記錄。通常來講,能使用CNAME的地方均可以用A記錄代替, 那麼爲何還要發明 CNAME 這樣一個東西呢?它是讓多個域名指向同一個 IP 的一種快捷手段, 這樣當最低層的 CNAME 對應的IP換了以後,上層的 CNAME 不用作任何改動。就像咱們代碼中的硬編碼,咱們總會去掉這些硬編碼,用一個變量來表示,這樣當這個變量變化時,咱們只須要修改一處

配置完以後能夠用 named-checkconf  named-checkzone 兩個命令來check咱們的配置文件有沒有問題, 以後就能夠啓動 bind 服務了:

 
  •  
  •  
$> service named startRedirecting to /bin/systemctl restart named.service

咱們用 netstat -ntlp 來檢查一下服務是否啓動:

53 端口已啓動,那麼咱們測試一下效果, 用 dig 解析一下 www.hello.com 域名,使用127.0.0.1 做爲遞歸解析服務器

咱們看到 dig 的結果跟咱們配置文件中配置的同樣是 1.2.3.4,DNS 完成了它的使命,根據域名獲取到 IP,但咱們這裏用來作示範的IP明顯是個假IP:)

用 DNS 實現負載均衡

一個域名添加多條A記錄,解析時使用輪詢的方式返回隨機一條,流量將會均勻分類到多個A記錄。

 
  •  
  •  
www IN A 1.2.3.4www IN A 1.2.3.5

複製代碼上面的配置中,咱們給 www 域添加了兩條A記錄, 這種作法叫 multi-homed hosts, 它的效果是:當咱們請求 nameserver 解析 www.hello.com 域名時,返回的IP會在兩個IP中輪轉(默認行爲,有些智能解析 DNS 會根據 IP 判斷,返回一個離client近的IP,距離 請搜索 DNS 智能解析)。

其實每次DNS解析請求時,nameserver都會返回所有IP,如上面配置,它會把1.2.3.4 和1.2.3.5 都返回給client端。那麼它是怎麼實現RR的呢?nameserver 只是每次返回的IP排序不一樣,客戶端會把response裏的第一個IP用來發請求。

DNS負載均衡 vs LVS專業負載均衡

和 LVS 這種專業負載均衡工具相比,在DNS層作負載均衡有如下特色:

  1. 實現很是簡單

  2. 默認只能經過RR方式調度

  3. DNS 對後端服務不具有健康檢查

  4. DNS 故障恢復時間比較長(DNS 服務之間有緩存)

  5. 可負載的 rs 數量有限(受 DNS response 包大小限制)

真實場景中,還須要根據需求選擇相應的負載均衡策略

子域受權

咱們從 .com 域下申請一個二級域名 hello.com 後, 發展到某一天咱們的公司擴大了,須要拆分兩個事業部A和B, 而且公司給他們都分配了三級域名  a.hello.com 和 b.hello.com, 域名結構以下圖:

再發展一段時間,A部門和B部門內部業務太多,須要頻繁的爲新產品申請域名, 這個時候他們就想搭建本身的 namserver,而且須要上一級把相應的域名管理權交給本身,他們指望的結構以下:

注意第一階段和第二階段的區別:第一階段,A 部門想申請 a.hello.com 下的子域名,須要向上級申請,整個 a.hello.com 域的管理都在總公司;第二階段,A 部門先本身搭建 nameserver,而後總公司把 a.hello.com 域管理權轉交給自建的 nameserver, 這個轉交管理權的行爲,就叫子域受權

子域受權分兩部操做:

  1. A部門自建 nameserver,而且在 zone 配置文件中指定 a.hello.com 的權威解析服務器爲本身的 nameserver 地址

  2. 總公司在 nameserver 上增長一條 NS 記錄, 把 a.hello.com 域受權給 A 部門的 nameserver

第一步咱們在用 bind 搭建域名解析服務器裏講過, 只要在 zone 配置文件裏指定SOA記錄就好:

 
  •  
@ IN SOA ns.a.hello.com admin.a.hello.com. (……)複製代碼

第二步,在 hello.com 域的 nameserver 上添加一條NS記錄:

 
  •  
  •  
a.hello.com IN NS ns.a.hello.comns.a.hello.com IN A xx.xx.xx.xx (自建nameserverIP)複製代碼

這樣當解析 xx.a.hello.com 域名時,hello.com nameserver 發現配置中有 NS 記錄,就會繼續遞歸向下解析

DNS 調試工具

OPS 經常使用的 DNS 調試工具備:host,nslookup,dig

這三個命令都屬於 bind-utils 包, 也就是 bind 工具集,它們的使用複雜度、功能 依次遞增。關於它們的使用, man 手冊和網上有太多教程,這裏簡單分析一下dig命令的輸出吧:

dig 的參數很是多, 功能也不少,詳細使用方法你們自行man吧

其餘

DNS 放大攻擊

DNS 放大攻擊屬於DoS攻擊的一種,是經過大量流量佔滿目標機帶寬, 使得目標機對正經常使用戶的請求拒絕鏈接從而掛掉。

思路

正常的流量攻擊,hack 機向目標機創建大量 request-response,但這樣存在的問題是須要大量的 hack 機器。由於服務器通常的帶寬遠大於家用網絡, 若是咱們本身的家用機用來作 hack 機器,還沒等目標機的帶寬佔滿,咱們的帶寬早超載了。

原理

DNS 遞歸解析的流程比較特殊, 咱們能夠經過幾個字節的 query 請求,換來幾百甚至幾千字節的 resolving 應答(流量放大), 而且大部分服務器不會對DNS服務器作防護。那麼 hacker 們只要能夠假裝 DNS query 包的 source IP, 從而讓 DNS 服務器發送大量的 response 到目標機,就能夠實現 DoS 攻擊。

但通常經常使用的 DNS 服務器都會對攻擊請求作過濾,因此找 DNS 服務器漏洞也是一個問題。詳細的放大攻擊方法你們有興趣自行 google 吧,這裏只作一個簡單介紹 :)


原文連接:http://github.crmeb.net/u/defu

相關文章
相關標籤/搜索