在上一篇文章中,咱們詳細解釋了 DNS 進行域名解析的過程:算法
全部這些請求都是經過無鏈接的 UDP 協議進行通訊,DNS 服務器識別是本身發出的數據包的惟一標準就是隨機的源端口號,若是端口號匹配則認爲是正確回覆。這樣一種簡單的方式在日益複雜的網絡結構下,可能會出現各類說不清道不明的問題。數據庫
既然 DNS 響應數據包的源 IP 地址很容易仿冒或僞造,天然就有不少人開始利用這一漏洞,僞造權威域名服務器的應答,把目標網站域名解析到錯誤的地址,從而達到讓用戶沒法訪問目標網站的目的,這就是「域名劫持」。api
這裏頗有表明性的例子就是防火長城(GFW)。咱們國家依法對互聯網進行管理和監控,爲了封堵國外的非法內容,GFW 會對 UDP 53 端口上的全部請求進行檢測,一經發現與黑名單關鍵詞相匹配的域名查詢請求,會立刻假裝成目標域名的解析服務器返回虛假的查詢結果。因爲一般的域名查詢沒有任何認證機制,並且基於無鏈接不可靠的 UDP 協議,查詢者只能接受最早到達的格式正確結果,並丟棄以後的結果。這樣一來,若是咱們直接訪問一些國外的「非法」網站,拿到的就會是一個假的 IP 地址。緩存
固然,也有一些黑客入侵致使的域名被劫持事件。黑客經過非法手段控制了域名管理密碼和域名管理郵箱,而後將該域名的 NS 記錄指向到黑客能夠控制的 DNS 服務器,而後經過在該 DNS 服務器上添加虛假域名記錄,從而全部到目標網站的流量所有導向黑客所指向的內容。2010 年 1 月 12 日針對百度的一次域名劫持事件在歷史上影響巨大。當天,百度被自稱是伊朗網軍(Iranian Cyber Army)的黑客組織入侵,致使其首頁癱瘓長達 8 小時,並隨後引起中國黑客對多個伊朗政府網站以及伊朗廣播大學網站的報復行爲。安全
其實相似的事件還發生過不少次,不光百度,谷歌和微軟他們的域名也曾經被劫持過,能夠說互聯網的背後一點都不像看起來風平浪靜的樣子。bash
若是沒有上游的欺騙和黑客的破壞,LocalDNS 拿到正確的結果以後,大致上是能夠正常服務的,但這裏也僅僅只能說是「大致」上。LocalDNS 會把從權威域名服務器接收到的結果數據進行緩存,以便加速後續的解析流程。例如在有效期內再有人問門衛王大爺「北海公園」的地址,王大爺只須要查一眼本身的筆記本,就能夠立刻給出回答。這一設計看似 feature,可是在現實生活中有時候它會失效,反而帶來危害。服務器
首先不少時候運營商的緩存時間都不太靠譜,他們不會遵照權威 DNS 提供的 ttl(存活時間),而是統一設置一個固定的時間,因此一般咱們改了一個域名的解析 IP 以後,會須要 0-48 小時(甚至更多)的時間才能讓全部的客戶端同步過來。並且但凡程序都會有 Bug,各運營商的運維水平也良莠不齊,有時候還會由於緩存故障影響大面積的用戶訪問。例如門衛王大爺在查找地址的時候也可能會看走眼,對此咱們也不能苛責;而更多的時候,在中國特點的互聯網環境中,王大爺還有本身的一些「小算盤」。網絡
咱們的互聯網看似四通八達,其實底層仍是幾個平行網絡在有限的幾個點鉸接而成的,運營商老是喜歡緩存 DNS 結果,還有一些經濟方面的考慮:運維
保證用戶訪問流量在本網內消化。國內的各互聯網接入運營商,他們的帶寬資源、網間結算費用、IDC 機房分佈、網內 ICP 資源分佈等存在較大差別,爲了保證網內用戶的訪問質量,同時減小跨網結算,運營商在網內搭建了內容緩存服務器,經過把域名強行指向內容緩存服務器的 IP 地址,就實現了把本地本網流量徹底留在了本地的目的;dom
推送廣告。有部分區域運營商會把某些域名解析結果指向本身的內容緩存,並替換或者插入第三方廣告聯盟的廣告,以此增長收入。。。
以上就是咱們常說的「域名緩存污染」,它會致使終端用戶訪問目標網站時產生各類訪問異常,或者夾雜莫名其妙的廣告,這種異常在無線網絡上更爲常見。
域名緩存是運營商「積極做爲」帶來的副問題,而運營商不做爲有時也會引來麻煩。運營商的 LocalDNS 有時候還會偷懶,自身不進行域名遞歸解析,而簡單把域名解析請求轉發到其它運營商的遞歸 DNS 上去。
例如北京市「道路諮詢局」有東西兩個大門(相隔較遠),分別由門衛王大爺和劉大爺把守,從道路諮詢局去北海公園也有東西兩條路。從東門進來的遊客,他們會諮詢王大爺,王大爺就會選擇便捷一點的東邊的路回覆遊客;從西門進來的遊客,他們會諮詢劉大爺,劉大爺會選擇西邊的路來回復遊客。可是忽然有一天,王大爺不想解答遊客的問題了,他找到了一個便捷的辦法,把全部問題都轉到劉大爺那裏去了,最後全部的遊客都會選擇從西邊的路去北海公園。對於本來在東門的遊客來講,可能就多走了一大段冤枉路。
實際的網絡拓撲結構是很複雜的,爲了儘量覆蓋更多用戶,一個網站會接入多條運營商線路,DNS 那裏則會根據請求者的特徵爲用戶來選擇最短訪問路徑(詳見前一篇文章裏的「DNS 智能解析」一節)。對這種轉發的狀況,可能最終的 DNS 會把轉發 DNS 的 IP 當成訪問者的來源 IP,這樣極有可能一個電信用戶最終訪問到了聯通的 IP,那麼終端的訪問速度可能就變慢了許多。還有一種解析錯誤是因爲 LocalDNS 本地出口 NAT 配置錯誤致使的,這裏再也不贅述。
以 LeanCloud 爲例,咱們以前使用的域名是 avoscloud.com,因爲這個域名存在敏感字符,因此某些區域解析常常出現問題,究其緣由基本上都是運營商的 LocalDNS 致使的,而要解決好這些問題,則須要不斷與運營商深度溝通或者找工信部投訴來解決,其流程之長和效率之低可想而知。這也就是咱們後來切換到 leancloud.cn 這一域名的緣由。換了域名以後,終端用戶的連通性好了不少,可是仍是不能 100% 解決全部網絡問題,這時候怎麼辦呢?
DNS 欺騙和污染的根本緣由就是缺少安全機制,因此自上世紀 90 年代起,人們就開始尋求這一問題的解決方案,最終 DNS 安全擴展 (DNS Security Extensions,DNSSEC) 應運而生。
DNSSEC 採用非對稱加密的方式對 DNS 數據進行加密,加解密算法與 HTTPS 相似,可是與 HTTPS 協議不一樣的是,DNSSEC 並不是對 DNS 查詢和響應的數據包進行加密,而僅僅只對 DNS 數據(A 記錄,CNAME 等等,統稱爲 Resource Record,縮寫爲 RR)進行簽名,因此 DNSSEC 能夠徹底兼容 DNS。
爲了支持非對稱加密算法,DNSSEC 中增長了一個區(zone)的概念。域名系統每一級的權威域名服務器就是一個 zone,他們都配置有一個公私密鑰對,這一點與 HTTPS 網站的 SSL 證書相似。權威域名服務器在返回應答數據的時候,除了一般的 Resource Record 以外,還會增長新的數據類型:
如此一來,DNSSEC 就能夠額外提供三層安全保護:
有興趣的讀者能夠參考這篇文章,以瞭解更多細節。
dig 是一個很是強大的 DNS 查詢工具,經過+dnssec
參數能夠驗證域名服務器和域名是否支持 DNSSec。例如,咱們使用國外的 DNS 解析,如8.8.8.8
,查詢域名 paypal.com
是否支持 DNSSec,能夠獲得以下結果:
$ dig @8.8.8.8 paypal.com +dnssec
; <<>> DiG 9.10.6 <<>> @8.8.8.8 paypal.com +dnssec
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6628
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; QUESTION SECTION:
;paypal.com. IN A
;; ANSWER SECTION:
paypal.com. 9 IN A 64.4.250.36
paypal.com. 9 IN A 64.4.250.37
paypal.com. 9 IN RRSIG A 5 2 300 20190923004132 20190824003218 11811 paypal.com. E21d1Jc/fCdZneT9oC3xWgQ1gPBdO1v29LPNJw7CtydJVhsy3z3bs4U8 7vBSGScEIpmCkmbZxChW1h3UlZ++hAmCCRx+eZV7VvhynpPW30mvwjrk wx5PVxWhPAKiTs07i5h4ZgTcWwp/ZEQbvU0DEkTKlBs2SuGU6AWNgmgL jgU=
複製代碼
這裏咱們能夠看到多出來的一條 RRSIG 記錄,就是 DNSSEC 的簽名數據。咱們換到 114.114.114.114
的 DNS 服務器來查詢 paypal.com
的域名,則獲得以下結果:
$ dig @114.114.114.114 paypal.com +dnssec
; <<>> DiG 9.10.6 <<>> @114.114.114.114 paypal.com +dnssec
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17708
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;paypal.com. IN A
;; ANSWER SECTION:
paypal.com. 36 IN A 64.4.250.37
paypal.com. 36 IN A 64.4.250.36
複製代碼
能夠看到 114 的 DNS 服務器並不支持 DNSSEC,並且咱們使用一樣的命令,來查詢 baidu.com
、taobao.com
和 qq.com
,就會發現他們都不支持 DNSSEC。爲何國內的大廠都不跟進這一功能呢?
DNSSEC 從原理上來講,可以比較理想的解決 DNS 上的安全問題,可是簽名和校驗 DNS 數據顯然會產生額外的開銷,從而影響網絡和服務器的性能:1)簽名和校驗的計算量很大,會對域名服務器的計算能力提出更高要求;2)簽名數據量比普通的 RR 大得多,會加劇網絡傳輸負擔;3)簽名和密鑰數據佔用的存儲空間也會比以前大一個數量級,會致使域名服務器的數據庫和管理系統都不得不進行升級和擴容。並且更重要的一點是,要想使用 DNSSEC,必須知足權威域名服務器和 LocalDNS 同時支持 DNSSec,這就須要現有的大量 DNS 解析服務的提供商對已有設備進行大範圍修改,這在異構且複雜的現實環境中實施的難度較大,因此整體推動很是緩慢。
那麼除了 DNSSEC 以外,咱們還有其餘辦法來解決 DNS 問題嗎?
2016 年,RFC 添加了 DNS-over-TLS 的標準,它相似於 HTTP-over-TLS(HTTPS),就是基於 TLS 來進行報文加密的 DNS 請求交互。區別於 DNSSEC,DNS-over-TLS 更側重於 DNS 交互報文的加密性,而 DNSSEC 更側重於 DNS 交互報文的完整一致性。阿里雲有作過 DNS over TLS 的嘗試,詳見這裏的介紹,最終也由於 DNS Server 的性能問題而束之高閣,取而代之的是 DNS-over-HTTP(S) 方案。
DNS over HTTP(S),顧名思義就是利用 HTTP(S) 協議與 DNS 服務器交互,繞開運營商的 LocalDNS,來防止域名劫持,提升域名解析效率。另外,因爲 DNS 服務器端獲取的是真實客戶端 IP 而非 LocalDNS IP,可以精肯定位客戶端地理位置和運營商信息,從而也能有效改進路由選擇的精確性。DNS over HTTP(S) 這一方案基於已經成熟並已普遍部署的 HTTP(S) 協議,客戶端調用也很是方便,沒有額外的成本負擔。
到目前爲止,有很多公共 DNS 已經支持 DNS over HTTPS,例如國外的 Cloudflare、Google Public DNS 支持 DNS over HTTPS,國內的 DNSPod 支持 DNS over HTTP,等等。如下即是 DNSPod 的 HttpDNS 請求流程圖:
LeanCloud 的 Java / Android SDK 擴展了 DNS 解析模塊,經過公共 DNS 的 http 請求獲取到域名解析結果,而後更新本地 DNS 緩存,這樣來避免客戶端的 LocalDNS 污染,效果仍是很明顯的。
從今年七月份開始,LeanCloud 已經開始支持應用綁定本身的訪問域名,以確保能長期穩定提供服務,這裏將咱們實踐中遇到的一些域名問題和解決辦法總結出來,但願對廣大開發者有所幫助。