文/段海新
DNSSEC原理、配置與部署
文/段海新
DNSSEC是為解決DNS欺騙和緩存污染而設計的一種安全機制。本文概要介紹DNSSEC的背景、工作原理以及在BIND上的配置,最后介紹它在國際上的部署情況和可能對互聯網安全機制的影響。本刊將分兩期刊載。

域名系統(Domain Name System,DNS)是一些“太單純、太幼稚”的互聯網先驅者設計的,它像互聯網的其他協議或系統一樣,在一個可信的、純凈的環境里可以運行得很好。但是今天的互聯網環境異常復雜,充斥著各種欺詐、攻擊,DNS協議的脆弱性也就浮出水面。對DNS的攻擊可能導致互聯網大面積的癱瘓,這種事件在國內外都屢見不鮮。
DNS作為互聯網最重要的基礎設施之一,它的安全問題一直被互聯網研究和工程領域廣為關注,但是有一種普遍存在的攻擊卻始終沒有解決,即DNS的欺騙和緩存污染問題。DNS安全擴展(DNS Security Extension, 即DNSSEC)主要是為了解決這一問題而提出的。因此,在介紹DNSSEC的原理之前有必要簡單介紹DNS欺騙和緩存污染攻擊的原理。
DNS欺騙攻擊和緩存污染
用戶在用域名訪問某一個網站時,用戶的計算機一般會通過一個域名解析服務器(Resolver Server,也稱遞歸服務器(Recursive Server))把域名轉換成IP地址。解析服務器一般需要查詢根域名服務器(root)、頂級域名服務器(TLD)、 權威域名服務器(Authoritative Server),通過遞歸查詢的方式最終獲得目標服務器的IP地址,然后交給用戶的計算機(如圖1所示)。
在上述任何一個請求/應答的過程中,攻擊者都可以假冒應答方(根、頂級域、權威域或解析服務器)給請求方發送一個偽造的響應,其中包含一個錯誤的IP地址。發送請求的用戶計算機或者解析服務器很天真地接受了偽造的應答,導致用戶無法訪問正常網站,甚至可以把IP重定向到一個偽造的網站上去。由于正常的DNS解析使用UDP協議而不是TCP協議,偽造DNS的響應報文比較容易。如果攻擊者可以監聽上述過程中的任何一個通信鏈路,這種攻擊就易如反掌。
更加糟糕的是,由于DNS緩存(Cache)的作用,這種錯誤的記錄可以存在相當一段時間(比如幾個小時甚至幾天),期間所有使用該域名解析服務器的用戶都無法訪問真正的服務器。
DNSSEC的目標、歷史和意義
上述攻擊能夠成功的原因是DNS 解析的請求者無法驗證它所收到應答信息的真實性。DNSSEC給解析服務器提供了防止受騙的武器,即一種可以驗證應答信息真實性和完整性的機制。利用密碼技術,域名解析服務器可以驗證它所收到的應答(包括域名不存在的應答)是否來自于真實的服務器,或者是否在傳輸過程中被篡改過。
盡管從原理上來說DNSSEC并不復雜,但是從1997年第一個有關DNSSEC的標準RFC 2065發布至今已經十多年了,直到最近一兩年才有了一定的進展。1999年IETF對DNSSEC標準進行了修訂,并推出RFC 2535,但這次修訂很快被證明是失敗的。直到2005年,一個可用的DNSSEC標準才制定出來RFC 4033-4035,目前主流域名服務軟件(如BIND )實現的也是這一版本。2008年,IETF又發布了一個NSEC3 RFC5155標準,以提高DNSSEC隱私保護能力。 隨著DNSSEC的推廣,也許還會有一些新的問題和新的修訂,DNSSEC標準仍在發展過程中。
盡管DNSSEC的目標僅限于此(即不保護DNS信息的保密性和服務的可用性),但是DNSSEC的成功部署對互聯網的安全還有其他好處,比如提高電子郵件系統的安全性,甚至可以把DNS作為一個公鑰基礎設施(PKI)。
本文所介紹的DNSSEC工作原理基于RFC 4033-4035,關于DNS工作原理、配置和數字簽名技術超出了本文的范圍,感興趣的讀者可以參考。

簡單的說,DNSSEC依靠數字簽名保證DNS應答報文的真實性和完整性。權威域名服務器用自己的私有密鑰對資源記錄(Resource Record, RR)進行簽名,解析服務器用權威服務器的公開密鑰對收到的應答信息進行驗證。如果驗證失敗,表明這一報文可能是假冒的,或者在傳輸過程、緩存過程中被篡改了。 RFC 4033概要介紹了DNSSEC所提供的安全功能并詳細介紹了相關的概念,下面通過一個簡化的實例介紹DNSSEC的工作原理 。
如圖2所示,一個支持DNSSEC的解析服務器(RFC4033中Security-Aware Resolver)向支持DNSSEC的權威域名服務器(Security-Aware Name Server)請求域名www.test.net.時,它除了得到一個標準的A記錄(IP地址)以外,還收到一個同名的RRSIG記錄,其中包含test.net這個授權域的數字簽名,它是用test.net.的私有密鑰來簽名的。為了驗證這一簽名的正確性,解析服務器可以再次向test.net的域名服務器查詢響應的公開密鑰,即DNSKEY資源記錄。然后解析服務器就可以用其中的公鑰驗證上述記錄的真實性與完整性。
解析服務器如何保證它所獲得的test.net.返回的公開密鑰(DNSKEY記錄)是真實的而不是假冒的呢?盡管test.net.在返回公開密鑰記錄的同時,也返回對這個公鑰的數字簽名,但是,攻擊者同樣可以同時偽造公開密鑰和數字簽名兩個記錄而不被解析者發現。
與基于X509的PKI體系一樣,DNSSEC也需要一個信任鏈,必須有一個或多個開始就信任的公鑰(或公鑰的散列值),在RFC 4033中稱這些初始信任的公開密鑰或散列值為“信任錨(Trust anchors)”。信任鏈中的上一個節點為下一個節點的公鑰散列值進行數字簽名,從而保證信任鏈中的每一個公鑰都是真實的。理想的情況下(DNSSEC全部部署),每個解析服務器只需要保留根域名的服務器的DNSKEY就可以了。
在上面的例子中,假設解析服務器開始并不信任test.net.的公開密鑰, 它可以到test.net.的上一級域名服務器net.那里查詢test.net.的DS(Delegation Signer, 即DS RR)記錄,DS RR中存儲的是test.net. 公鑰的散列值(比如用MD5算法計算得到的128比特數據,再用base64編碼得到的一個字符串)。假設解析服務器由管理員手工配置了.net的公鑰(即Trust Anchor),它就可以驗證test.net.公鑰(DNSKEY)的正確與否了。
DNSSEC的資源記錄
為了實現資源記錄的簽名和驗證,D N S S E C增加了四種類型的資源記錄:RRSIG(Resource Record Signature)、DNSKEY(DNS Public Key)、DS(Delegation Signer)、NSEC(Next Secure)。前三種記錄已經在上面的實例中提到了,NSEC記錄是為響應某個資源記錄不存在而設計的。具體的說明參見RFC 4034,本文概要介紹如下。
DNSKEY記錄
DNSKEY資源記錄存儲的是公開密鑰,下面是一個DNSKEY的資源記錄的例子:

其中256是標志字段(flag),它是一個16比特的數,如果第7位(左起為第0位。這一位是區密鑰(Zone Key)標志, 記為ZK)為1,則表明它是一個區密鑰,該密鑰可以用于簽名數據的驗證,而且資源記錄的所有者(example.com.)必須是區的名字。第十五稱為安全入口點(Security Entry Point,SEP)標志,將在下面介紹。
下一個字段“3”是協議(protocol)字段,它的值必須是3,表示這是一個DNSKEY,這是為了與以前版本DNSSEC兼容而保留下來的。其他的值不能用于DNSSEC簽名的驗證。
下一個字段“5”是算法(Algorithm)字段,標識簽名所使用的算法的種類。其中常用的幾種:1:RSA/MD5; 3:DSA/SHA-1; 5 RSA/SHA-1。
最后括號中的是公開密鑰(Public Key)字段,它的格式依賴于算法字段。
在實踐中,權威域的管理員通常用兩個密鑰配合完成對區數據的簽名。一個是Zone-Signing Key(ZSK),另一個是Key-Signing Key(KSK)。ZSK用于簽名區數據,而KSK用于對ZSK進行簽名。這樣做的好處有二:
(1)KSK的密鑰簽名的數據量很少,被破解(即找出對應的私鑰)概率很小,因此可以設置很長的生存期。這個密鑰的散列值作為DS記錄存儲在上一級域名服務器中而且需要它的數字簽名,較長的生命周期可以減少密鑰更新的工作量。
(2)ZSK簽名的數據量比較大,因而破解的概率較大,其生存期應該小一些。因為有了KSK的存在,ZSK可以不必放到上一級的域名服務中,減少了管理的開銷。
RRSIG記錄
為保證模擬結果的可靠性,對光滑管從0.5~2.0m/s的入口流速進行模擬,由于研究流體為無相變流體在光滑管管內作強制流動,可將模擬得到的摩擦系數fA與Blasius公式計算理論值對比[9],從而判定模擬結果的可靠性。結果如表2所示。
RRSIG資源記錄存儲的是對資源記錄集合(RRSets)的數字簽名。下面是對一個A記錄簽名后得到的RRSIG記錄:

從第五個字段(“A”)開始各字段的含義如下:
類型覆蓋(The Type Covered Field):表示這個簽名覆蓋什么類型的資源記錄,本例中是A。
算法:數字簽名算法,同DNSKEY記錄的算法字段;本例中5表示RSA/SHA-1。
標簽數量(The Labels Field):被簽名的資源域名記錄所有者(host.example.com.)中的標簽數量,如本例中為3,*.example.com.為2,“.”的標簽數量為0。
接下來的幾個字段分別是被簽名記錄的TTL、有效期結束時間、開始時間。
2642是密鑰標簽(Key Tag),它是用對應公鑰數據簡單疊加得到的一個16比特整數。如果一個域有多個密鑰時(如一個KSK、一個ZSK),Key Tag可以和后面的簽名者字段(example.com.)共同確定究竟使用哪個公鑰來驗證簽名。
DS(Delegation Signer)記錄存儲DNSKEY的散列值,用于驗證DNSKEY的真實性,從而建立一個信任鏈。不過,與DNSKEY存儲在資源記錄所有者所在的權威域的區文件中不同,DS記錄存儲在上級域名服務器(Delegation)中,比如example.com的DS RR存儲在.com的區中。
下面是一個DS記錄的實例:

DS 之后的字段依次是密鑰標簽(Key Tag)、算法和散列算法(1代表 SHA-1)。后面括號內的內容是dskey.example.com.密鑰SHA-1計算結果的16進制表示。Example.com必須為這個記錄數字簽名,以證實這個DNSKEY的真實性。
NSEC記錄
NSEC記錄是為了應答那些不存在的資源記錄而設計的。為了保證私有密鑰的安全性和服務器的性能,所有的簽名記錄都是事先(甚至離線)生成的。服務器顯然不能為所有不存在的記錄事先生成一個公共的“不存在”的簽名記錄,因為這一記錄可以被重放(Replay);更不可能為每一個不存在的記錄生成獨立的簽名,因為它不知道用戶將會請求怎樣的記錄。
在區數據簽名時,NSEC記錄會自動生成。比如在vpn.test.net和xyz.test.net之間會插入下面的這樣兩條記錄:

其中NSEC記錄包括兩項內容:排序后的下一個資源記錄的名稱(xyz.test.net.)以及vpn.test.net.這一名稱所有的資源記錄類型(A、RRSIG、NSEC),后面的RRSIG記錄是對這個NSEC記錄的數字簽名。
在用戶請求的某個域名在vpn和xyz之間時,如www.test.net.,服務器會返回域名不存在,并同時包括 vpn.test.net的NSEC記錄。
DNSSEC對現有DNS協議的修改
由于新增DNS資源記錄的尺寸問題,支持D N S S E C的域名服務器必須支持EDNS0(RFC2671),即允許DNS報文大小必須達到1220字節(而不是最初的512字節),甚至可以是4096字節。
DNSSEC在報文頭中增加了三個標志位:
(1)DO(DNSSEC OK, 參見RFC3225):支持DNSSEC的解析服務器在它的DNS查詢報文中,必須把DO標志位置1,否則權威域服務器認為解析器不支持DNSSEC就不會返回RRSIG等記錄。
(2)AD (Authentic Data):AD是認證數據標志,如果服務器驗證了DNSSEC相關的數字簽名,則置AD位為1,否則為0。這一標志位一般用于自己不做驗證的解析器(non-validating security-aware resolvers)和它所信任的遞歸解析服務器(securityaware recursive name server)之間,用戶計算機上的解析器自己不去驗證數字簽名,遞歸服務器給它一個AD標志為1的響應,它就接受驗證結果。這種場景只有在它們之間的通信鏈路比較安全的情況下才安全,比如使用了IPSEC和TSIG。
(3)CD (Checking Disabled): 關閉檢查標志位用于支持DNSSEC驗證功能的解析器(validating security-aware resolver)和遞歸域名服務器之間,解析器在發送請求時把CD位置1,服務器就不再進行數字簽名的驗證而把遞歸查詢得到的結果直接交給解析器,由解析器自己驗證簽名的合法性。
最后,支持驗證的DNSSEC 解析器對它所收到的資源記錄的簽名(RRSIG),必須能夠區分以下四種結果:
(1)安全的(secure):解析器能夠建立到達資源記錄簽名者的信任鏈,并且可以驗證數字簽名的結果是正確的。
(2)不安全的(insecure):解析器收到了一個資源記錄和它的簽名,但是它沒有到達簽名者的信任鏈,因而無法驗證。
(3)偽造的(Bogus):解析器有一個到資源記錄簽名者的信任鏈,但是簽名驗證是錯的。可能是因為受到攻擊了,也可能是管理員配置錯誤。
(4)不確定(Indeterminate):解析器無法獲得足夠的DNSSEC 資源記錄,因而不能確定用戶所請求的資源記錄是否應該簽名。(待續)
(作者單位為清華大學信息網絡工程研究中心)