DNS (Domain Name System), 也叫網域名稱系統,是互聯網的一項服務。它實質上是一個 域名 和 IP 相互映射的分佈式數據庫,有了它,咱們就能夠經過域名更方便的訪問互聯網。數據庫
DNS有如下特色:後端
那麼,什麼狀況下使用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:負載均衡
歸納一下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解析流程。標準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流程:
咱們分析一下解析流程:
遞歸解析服務器 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搭建的文章實在太多了,我就再也不贅述了, 喜歡動手的朋友能夠網上搜一搜搭建教程,一步步搭建一個本地的nameserver 玩一玩。這裏主要介紹一下bind 的配置文件吧
bind 的配置文件分兩部分: bind配置文件
和 zone配置文件
bind配置文件位於/etc/named.conf
,它主要負責bind功能配置,如zone路徑、日誌、安全、主從等配置
其中最主要的是添加zone的配置以及指定zone配置文件。 recursion
開啓遞歸解析功能, 這個若是是no, 那麼此bind服務只能作權威解析服務,當你的bind服務對外時,打開它會有安全風險,如何防護不當,會讓你的nameserver 被hacker 用來作肉雞
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 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:)
一個域名添加多條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層作負載均衡有如下特色:
真實場景中,還須要根據需求選擇相應的負載均衡策略
咱們從.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, 這個轉交管理權的行爲,就叫 子域受權
子域受權分兩部操做:
第一步咱們在用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記錄,就會繼續遞歸向下解析
OPS 經常使用的DNS調試工具備: host, nslookup, dig
這三個命令都屬於 bind-utils 包, 也就是bind工具集, 它們的使用複雜度、功能 依次遞增。 關於它們的使用, man 手冊和網上有太多教程,這裏簡單分析一下dig命令的輸出吧:
dig 的參數很是多, 功能也不少,詳細使用方法你們自行man吧
DNS 放大攻擊屬於DoS攻擊的一種,是經過大量流量佔滿目標機帶寬, 使得目標機對正經常使用戶的請求拒絕鏈接從而掛掉。
思路
正常的流量攻擊,hack機向目標機創建大量request-response, 但這樣存在的問題是須要大量的hack機器。 由於服務器通常的帶寬遠大於家用網絡, 若是咱們本身的家用機用來作hack機器,還沒等目標機的帶寬佔滿,咱們的帶寬早超載了。
原理
DNS 遞歸解析的流程比較特殊, 咱們能夠經過幾個字節的query請求,換來幾百甚至幾千字節的resolving應答(流量放大)
, 而且大部分服務器不會對DNS服務器作防護。 那麼hacker們只要能夠假裝DNS query包的source IP, 從而讓DNS 服務器發送大量的response到目標機,就能夠實現DoS攻擊。
但通常經常使用的DNS服務器都會對攻擊請求作過濾,因此找DNS服務器漏洞也是一個問題。 詳細的放大攻擊方法你們有興趣自行google吧,這裏只作一個簡單介紹 :)
見: 公共DNS哪家強