DNS基礎知識

DNS 是什麼

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

DNS有如下特色:後端

  • 分佈式的
  • 協議支持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 都是分佈式存儲的。markdown

根域名服務器只管理頂級域,同時把每一個頂級域的管理委派給各個頂級域,因此當你想要申請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-checkconfnamed-checkzone 兩個命令來check咱們的配置文件有沒有問題, 以後就能夠啓動bind服務了:

$> service named start
Redirecting 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.4
www     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.comb.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.com
ns.a.hello.com      IN      A        xx.xx.xx.xx (自建nameserver的IP)複製代碼

這樣當解析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吧,這裏只作一個簡單介紹 :)

好用的公共遞歸解析DNS服務器

見: 公共DNS哪家強

延伸

如何用樹莓派打造家用DNS

d71b0cd7ce9bde3025133b6e6
相關文章
相關標籤/搜索