DNSSEC的工作原理

網域名稱系統 (DNS) 如同網際網路的電話簿;它告訴電腦要去哪裡存取資料。然而不幸的是,它接受任何位置的回應,不經過任何驗證。

電子郵件伺服器使用 DNS 路由它們的信件,這意味著它們在安全上處於弱勢。2014 年 9 月, CMU 的研究人員發現發送給Yahoo!、Gmail的郵件經過了不明的伺服器。攻擊者利用一個已經存於DNS系統幾十年的老漏洞—— 它並不會進行任何檢查就接受結果。

而解決這問題的最終方案是DNSSEC,它藉由提交驗證資訊在上級域名伺服器;例如當一個DNS要求解析blog.cloudflare.com時 .com 會負責驗證它是正確的被指向cloudflare,然後Cloudflare會負責驗證它正確地被指向blog。而 .com的驗證是交由根伺服器(事實上,所有頂級域都是由根伺服器解析)進行,這是通過了一個公開的安全審核(一般來說,我們無條件相信root伺服器),這是經過了DNSSEC簽約儀式(The DNSSEC Root Signing Ceremony)。

DNSSEC的簡介:

DNSSEC 所建立的安全網域名稱系統通過將加密簽名添加到現有的 DNS 記錄中。這些數位簽章與A、AAAA等常見的紀錄一同存在DNS系統中;經由檢查這些簽名,可以確保來自根伺服器的回應沒有被任何人竄改。

為了方便驗證,DNSSEC建立了數種新的DNS紀錄類型:

  • RRSIG:包含加密的簽名
  • DNSKEY:包含公用簽名金鑰
  • DS:包含DNSKEY 記錄的雜湊值
  • NSEC和NSEC3:用於明確拒絕不存在的一個DNS記錄
  • CDNSKEY和CDS:用於授權子域的DNS

關於這些紀錄的關係,以及它們是如何工作的,我們會在稍後解釋。

RRsets

使用DNSSEC保護區域的第一步是將具有相同類型的所有記錄分組到資源記錄集(RRset)中。例如,如果您的區域中有三個AAAA記錄,則它們都將捆綁到單個AAAA RRset中。

實際上的簽名是對整個RRsets,而非單條DNS紀錄。當然,這也代表你必須同時驗證所有相同類型的紀錄,而非僅僅一個。

ZSK(Zone-Signing Keys)域簽名用金鑰

ZSK用來對RRsets進行簽屬,由下級DNS伺服器進行簽署,用來證明”這是我的紀錄,來自我的伺服器”,這些簽署會被儲存為RRSIG紀錄。

KSK(Key-Signing Keys)金鑰簽名用金鑰

前面的金鑰是指ZSK,前面提到,DNS是由上級DNS提供驗證,然而一個上級伺服器會有許多的下級域名,而下級們也有他們的下級,若是其中一個紀錄發生改變,則金鑰全部都要更新的話那根本無法維護(不要忘了DNS還有緩存…)。所以使用KSK對ZSK進行簽名的話,上級DNS伺服器中的KSK雜湊值就不用改變了,下級有更新只要重新簽署ZSK再用KSK再簽署就可以了。而這個簽名本身是以DNSKEY的紀錄儲存的。

簽章授權紀錄(DS)

DNSSED是層層下去的信任機制,所以我們現在來看看他們是如何協同工作的。DS記錄負責將上級伺服器的授權傳達給其他人,亦即其他人透過DS紀錄來確保下級伺服器是否真的有權利代表這個網。DS紀錄是對KSK亦即DNSKEY的雜湊值,這個紀錄會提交給上級伺服器進行發布。

每次DNS查詢時,也會檢索上級DNS伺服器的DS紀錄,若是與下級DNS伺服器的紀錄相符,我們可以知道這個上級伺服器信任這台下級伺服器中的所有區域,並且沒有遭到竄改。這簡單解釋了DNSSEC的信任鏈是如何被建立的。

值得注意的是KSK大約一年左右必須進行更新,這是一個多個步驟的過程,若是沒有處理好會造成解析中斷(別忘記DNS是有緩存的,亦即所有更新都不會立即生效),在更新時我們必須要建立一個新的KSK與DS紀錄並且先上傳至上級DNS伺服器,等待舊的DS紀錄的TTL過期後我們才可以將其刪除,並且更新下級DNS伺服器的KSK。這就是為什麼我們要同時使用KSK與ZSK的緣故,顯然ZSK比較容易進行更新(所有操作都在本機完成)。

明確拒絕不存在的一個DNS記錄

如果你使用DNS詢問一個不存在的域,它將會返回依個空的答案,然而這種答案無法驗證,如果你想要驗證這個答案的話,要使用NSEC和NSEC3記錄類型來解決此問題。他們都允許認證不存在的域。
假設abc.com有aaa、ccc的子域,而你請求bbb子域,伺服器將會回應包含ccc的NSEC記錄,亦即是下一個存在的子域,因為這是依照順序排序的,所以可以推的bbb並不存在,而NSEC記錄以簽名,所以可以像RRset一樣驗證其對應的RRSIG。

信任鏈

好的,所以我們有一種方法在區域內建立信任,並將其連接到其父區域,但我們如何相信DS記錄?DS記錄像任何其他RRset一樣被簽名,這意味著它在父代中具有相應的RRSIG。整個驗證過程重複,直到我們得到上級的公共KSK。要驗證這一點,我們需要轉到該上級的DS記錄,然後我們就會向上查詢信任鏈。

但是,當我們最終到達根DNS區域時,我們有一個問題:沒有要驗證的父DS記錄。這就是我們看到全球互聯網的一個非常人性化的一面。
在根簽約儀式(The DNSSEC Root Signing Ceremony)中,來自世界各地的幾個選定的個人走到一起,並簽署根 DNSKEY RRset 非常公開和高度審核的方式在典禮上產生可以用於驗證根名稱伺服器公共 KSK 和 ZSK RRSIG 記錄。而不是信任公共 KSK 父的 DS 記錄,因為我們假設它是有效的,因為我們信任訪問私人 KSK 周圍的安全程式。
父和子領域之間建立信任關係的能力是 DNSSEC 的整體組成部分。如果鏈中的任何部分壞了,我們不能相信我們要求,因為中間人中可能會改變記錄到任何 IP 位址。


參考資料與感謝:

傲笑紅塵路: 簡介DNSSEC (Introduction to DNS Security Extensions)
Cloudflare:How DNSSEC Works
維基百科:域名系統安全擴展
Ithome
Bind DNS DNSSEC 實作

One Trackback

  • By Cloudflare深入介紹 - 吾輩乃程序猿 on 2017-02-25 at 15:53:18

    […] 比較特別的功能是DNSSEC,可以確保用戶是連接至授權的DNS伺服器,關於這個可以看看我的另一篇文章:DNSSEC的工作原理。 […]

Post a Comment

Your email is never published nor shared. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*
*