網際網路廣泛用以名稱解析用途的網域名稱系統(Domain Name System, DNS)原是一個缺乏安全性設計的分散式架構,所以歷年來存在著各種轉稼(Pharming)、偽裝(Spoofing)、快取下毒(Cache Poison)與阻絕服務(Denial of Service)等攻擊手法
,其中涵蓋著DNS區域傳送的安全性問題、動態更新的安全性問題,偽裝資料和快取記錄污染等問題,所以IETF 為了解決DNS服務本身設計所帶來的各種安全性問題,從九零年代後期就陸續研究並發表了一連串的安全性保護機制,其中較重要的RFC相關文件為:DNS | DNSSEC | ||
1034, 1035 | 定義 DNS | 2535 | DNSSEC初始建議 (AD, CD 標頭位元)),解決DNS通訊或傳輸資訊的驗證與完整性的問題 |
2671 | EDNS0 支援長封包(DNSEC需使用) | 4033, 4034, 4035 | 定義DNSSEC (NSEC),取代 RFC 2535 |
3833 | DNS的威脅分析 | 3757 | Key Signing Keys (KSKs) 和 Zone Signing Keys (ZSKs) |
2845 | TSIG,用以確保DNS名稱伺服器的交易安全性 | 5155 | 定義 NSEC3,雜湊不存在記錄的驗證 |
2931 | SIG(0),提出了請求及交易簽章,雖未被廣泛使用,但適合用以解決動態更新的安全性問題 | 4641 | DNSSEC作業指引 |
5074 | DNSSEC Lookaside Validation (DLV),用以發佈DNSSEC預設委派鏈(Delegation chain)以外的信任起源(Trust anchors) |
DNSSEC 乃是透過一種延伸的方法來達成DNS安全性的目的,並沒有修改現存DNS 的運作模式,亦即既有的 DNS查詢與回應的處理流程並沒有任何變更,只是在每一種運作下新增了資料驗證機制,本文將著重說明如何透過DNSSEC來加強既有DNS服務的安全性保護之內涵與技術。
DNSSEC 的安全目標
DNSSEC雖然是DNS服務的安全性加強與延伸機制,但並非如萬靈丹一般可以解決所有DNS服務目前所面臨的有安全性問題,DNSSEC的設計乃是透過數位簽章(Digital Signature)的技術來冀望達成下列的安全性目標為:
- 驗證DNS資料來源的真確性 (origin authentication of DNS data) :
- 完整性的確保 (Integrity assurance)
- 不存在的驗證 (authenticated denial of existence)
另一方面,DNSSEC 並無法提供下列二項安全性服務:
- 私密性 (Confidentiality):DNS 請求與回應的資料無法避免被竊聽
- 可用性 (Availability):阻絕服務(Denial of Service)的攻擊仍可能有效
總之,DNSSEC這項技術僅不過著重於允許用戶端驗證DNS回應資料的真確與完整性。
數位簽章 (Digital Signature)
想要理解DNSSEC技術運作,您必需先從認識公開金鑰加密技術、數位簽章的產生與確認技術以及信任鏈的概念開始,因為數位簽章可說是DNSSEC的關鍵技術。
數位簽章是目前最重要的數位資料防偽技術,電子簽章(electronic signature)可取代傳統的簽名或蓋章,但須確保資料在網路傳輸過程中未被竄改,並且能夠鑑別傳輸者之身分,防止其事後否認傳輸之事實。目前網路電子簽章的使用皆是植基於數位簽章(digital signature),而數位簽章早已廣泛應用於電子公文、電子契約、電子支票、軟體防偽、網路報稅等各種網路交易平台中。
換言之,利用數位簽章的技術,可提供三項安全性服務與目的:
- 驗證傳送的來源 (authenticate)
- 完整性 (integrity) :確保資料不被竄改
- 來源的不可否認性 (non-repudiation of origin)
數位簽章的產生與檢驗需用到兩種密碼學演算法:單向雜湊函數演算法(Hash:MD5、SHA-1)與公開金鑰演算法(RSA),做法是先將電子文件以雜湊演算法計算以產生一固定長度之摘要值(Digest),然後再以簽署人之私密金鑰(Private key)對其加密,形成電子簽章,並得以日後公開金鑰(public key)加以驗證者。
詳言之,產生數位簽章的一般過程或步驟如下:
1. 將原始訊息利用雜湊演算法(例如 MD5、SHA)計算予以濃縮成一個不可反逆且固定長度的摘要值。
2. 利用傳送者的私密金鑰並使用公開金鑰演算法(例RSA)並將上一步驟所算出的摘要值予以加密而產生簽章。
3. 將原始訊息和二層加密所得的簽章經由網路一併傳送給接收者。
由上述的步驟過程可知,數位簽章是由二層加密(雜湊與非對稱性演算法)技術所產生的,產生的過程如下圖示。
另一方面,一旦接收者收到訊息與數位簽章後,如何験證數位簽章的真偽,做法及步驟為:
1. 首先取出原始傳送的訊息,並利用相同的雜湊演算法計算出文件的摘要值。
2. 取出簽章並利用傳送者的公開金鑰還原原傳送者所計算的摘要值。
3. 將步驟一接收端所自行計算的摘要值與還原的傳送者所計算的摘要值作一比較,若二者相同則驗證了文件並未被篡改過且傳送的來源具備不可否認性。
由上述的步驟過程可知,接收者是利用傳送者的公開金鑰驗證其真偽。
一般數位簽章的使用均會透過PKI架構,由可信賴憑證管理中心簽發的憑證來做為公開金鑰信任的來源,利用電子郵件所使用的S/MIME,報稅所使用的自然人憑證均是,但DNSSEC並不使用PKI,所以數位簽章與公開金鑰等資料以及金鑰的信任鏈就必需由DNS區域內的特殊記錄類型來建立。
DNSSEC 相關資源記錄
為了讓DNS用戶端可以驗證DNS回應資料的真確與完整性,用來保護用戶端免於受到偽造或竄改的DNS資料相關的攻擊,所以DNSSEC的回應採用了數位簽章(Digital Signature)技術,透過數位簽章可讓用戶端檢查收到的訊息是否完整及正確的授權來源,不過為了確保公開金鑰的正確性,還需要建立完整階層式的信任鏈(chain of trust),而這整個設計的核心就是必需在DNS區域內新增了一些可用來存放金開金鑰與簽章的特殊資源記錄類型,這即是 RRSIG、DNSKEY、NSEC以及DS等記錄,此外,DNSSEC還新增了 AD與CD這二個位元旗標來決定是否執行DNSSEC資料確認。
下表說明了這些特殊的資源記錄類型的功能和在信任鏈中所扮演的角色。
RRSIG | 存放資源記錄(Resource Record)利用雜湊和私密金鑰所建立的數位簽章 | www.example. 3600 RRSIG A 5 2 3600 20040509183619 ( 20040409183619 38519 example. OMK8rAZlepfzLWW75Dxd63jy2wswESzxDKG2 f9AMN1CytCd10cYISAxfAdvXSZ7xujKAtPbc tvOQ2ofO7AZJ+d01EeeQTVBPq4/6KCWhqe2X TjnkVLNvvhnc0u28aoSsG0+4InvkkOHknKxw 4kX18MMR34i8lC36SR5xBni8vHI= ) |
DNSKEY | 存放區域的數位簽章所使用的公開金鑰資訊,用戶端可透過此公開金鑰來驗證收到的資源記錄是否來自正確來源且沒有被篡改過 | example.com. 86400 IN DNSKEY 256 3 5 ( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== ) |
DS (Delegation Signer) | 存放在父層的區域,提供父層對子層的 DNSKEY 驗證,確認DNSKEY的正確性,確保不會被偽裝與與篡改,因此DS記錄負責建立起DNSSEC的信任鏈(chain of trust),它通常將下層的公開金鑰利用雜湊函數計算的摘要值來呈現,而DS記錄也被簽署 | dskey.example.com. 86400 IN DS 60485 5 1 ( 2BB183AF5F22588179A53B0A 98631FAD1A292118 ) |
NSEC | 為了銜接區域中每筆資源記錄的空隙使其形成一個環狀的排列方式,可避免區域資料被攻擊者插入不正確的資料記錄,換言之,NSEC記錄指向區域內下一個有效的名稱,藉以用來提供用戶請求的名稱並不存在的證明( authenticated denial of existence) | b.example.com. 86400 IN NSEC d.example.com. (A RRSIG NSEC) |
NSEC3 | 為NSEC記錄的雜湊版本,用以避免列舉區域記錄的攻擊 | q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG ) |
因此如果將這些新增的DNSSEC資源記錄整合入原來的DNS遞迴查詢過程中,一部DNSSEC用戶端查詢主機記錄時,伺服器就需要在每一層的解析查詢過程中回覆更多用來驗證簽章所的這些資源記錄,如下圖顯示為了提供回覆資料簽章驗證能力,所以DNSSEC伺服器需要比傳統的DNS回覆時新增驗證所需的DNSKEY、RRSIG和DS記錄:
驗證的信任鏈
驗證資源記錄數位簽章過程時,需要使用到DNSKEY的公開金鑰,但問題是當用戶端從網路上取得傳回的公開金鑰時,如何確認這是一把正確沒有問題的公開金鑰,而非有心人士假造或篡改的金鑰,這就牽涉到信任鏈的建立過程,整個DNSSEC信任鏈的設計途徑是先由根名稱伺服器的DS記錄來確認第一層 DNSKEY的真偽,再由第一層的DS記錄來確認第二層的DNSKEY的真偽,最後第二層的DNSKEY再確認用戶所收到的記錄數位簽章是否正確無誤,亦即最終確保用戶端所收到的記錄正確無誤,而絕非有心人士篡改或偽造的記錄。
簡單而言,上層DS指向下層的DNSKEY為信任鏈的基礎 (如下圖所示)
完整的信任鏈將會由DNS階層式結構的根網域利用DS記錄來指向第一層的公開金鑰開始,再到第二層域DS指向第三層的DNSKEY,第三層………,依此類推,如下圖所示,Root 網域根據下層的.com、.net、.org….第一層網域管理員登錄的公開金鑰來建立DS記錄指向其DNSKEY,而第一層的.com網域又根據下層的d1.com、d2.com…..網域管理員登錄的公開金鑰來建立DS記錄指向其更下層的DNSKEY。
總而言之,DNSSEC信任鏈的建立並不使用大家所熟知的公開金鑰基礎結構(PKI),信任鏈乃是由緊鄰的父層區域到子層區域,亦即只有區域的父層可以擔保他的金鑰正確無誤。
DNSSEC的金鑰對 -ZSK 與 KSK
前面已說明了DS記錄主要是用來驗證下層的DNSKEY是否正確無誤,而DS記錄乃是由下層的管理人員向上層遞交DNSKEY而產生的,但一把金鑰不可能永遠使用,因為金鑰使用太久,易遭受破解,所以使用一段時間後必需加以更新,但是當金鑰更新時,又必需同時向上層重新遞交新的金鑰來產生新的 DS 記錄,如果你的上層管理單位,下層只有五個下層區域那還可以管理,但如如果是類似第一層的網域伺服器管理者, 如.com, .net等網域,其下層的網域豈只有成千上萬個網域,一旦每個子網域的金鑰更新頻繁,那幾乎難以管理維護。
為了解決這個問題,就需要有二組的金鑰對 - ZSK、KSK
- ZSK (Zone Signing Key ) (較短期使用): ZSK私密金鑰用來簽署區域內的資源記錄
- KSK (Key Signing key) (較長期使用) :KSK私密金鑰用來對ZSK公開金鑰進行簽署,並且需由父層區域使用DS指向子層區域的KSK,一旦變更KSK意謂著需要向父層更新DS。
一旦採用了二組金鑰對ZSK和KSK後,上下層的信任鏈關係就如下圖所示,由父層的DS指向子層的KSK來達成。
舉例而言,為何用戶端最後執行DNS解析所取得伺服器回覆的www.abc.com主機的IP位址是正確無誤,絕對不會是被駭客假造或修改過的資料呢?因為利用整個區域階層的RRSIG、DNSKEY和DS 等特定的資源記錄所形成的層層驗證信任鏈,如下圖所示,下層的可以確認用戶端所收到的www.abc.com回應的A記錄確實是由授權的來源所送出且無被修改過。
Key Rollovers
更新金鑰對並不如直覺上的簡單,若直接將先前的金鑰刪除,然後再新增金鑰則可能引發無法驗證的問題,這是因為網際網路上的名稱伺服器和用戶端均會維護快取資料,即使您已經刪除舊金鑰的使用,但仍然可能有機器會將舊的公開金鑰存放在快取區一段相當時間,因此一旦直接移移除舊金鑰而逕行使用一把新的私密金鑰來重新簽署所有記錄後,那些仍被快取的舊公開金鑰將不再能夠驗證任何主機記錄直到快取資料過期。
為了避免此一問題,一項稱為Key Rollovers機制將被使用,Key Rollers過程將涉及到新增區域的公開金鑰時需與舊的金鑰同時運作一段時間,等到維持在名稱伺服器的快取時間(TTL)過期後,讓其快取重新查詢而取得新的公開金鑰存放在快取區之後,才能將區域內的舊公開金鑰移除並使用新的金鑰來簽署記錄。
NSEC 與 NSEC3
NSCE為DNSSEC中設計來處理負面快取(Negative Caching)的資料是否正確的方式,在傳統DNS中若解析失敗會使用NXDOMAIN錯誤訊息來提供負面回應(Negative Responses)以表示網域名稱不存在,但這種負面回應的錯訊息無法簽署,因此用戶端無法判斷其真偽,是否是由有心人士送出的假造負面回應,所以必需想出一個方法可以利用密碼學技術來驗證一筆不存在的記錄,這個答案就是NSEC,DNSSEC利用NSCE資源記錄來解決負面回應的G簽章和驗證問題,做法是DNSSEC在簽署網域的同時會將所有網域名稱加以排序,然後建立NSEC記錄,利用NSEC記錄來回應不存在的查詢,因為一筆NSEC會提供已排序的存在網域名稱的上一個與下一個記錄,而介在排序後的二者間的資料則是表示不存在的名稱,底下以例子來說明NSCE如何處理不存在的記錄
假設test.com的原始區域內容為:
test.com. SOA ns.test.com. root.test.com. ( 2012041500 1h 10m 30d 1d ) NS ns.test.com. A 221.38.0.1 MX 10 mail.test.com. ns A 221.38.0.1 mail A 221.38.0.2 www A 221.38.0.3 ftp CNAME www.test.com. west NS ns.west.test.com. ns.west A 221.38.0.5 east NS ns.east.test.com. ns.east A 221.38.0.6 |
NSEC會先對記錄由右到左排序,而形成:
test.com. SOA ns.test.com. root.test.com. (2012041500 1h 10m 30d 1d ) test.com. NS ns.test.com. test.com. A 221.38.0.1 test.com. MX 0 mail.test.com. east.test.com. NS ns.east.test.com. ns.east.test.com. A 221.38.0.6 ftp.test.com. CNAME www.test.com. mail.test.com. A 221.38.0.2 ns.test.com. A 221.38.0.1 west.test.com. NS ns.west.test.com. ns.west.test.com. A 221.38.0.5 www.test.com. A 221.38.0.3 |
然後新增NSEC記錄,每一筆記錄用前後二個欄位分別指出上筆存在的記錄與下一筆存在的記錄並於最後列出記錄類型,而最後一筆記錄的下一筆則會繞回第一筆記錄,此外,每一筆NSEC記錄將有一筆對應的RRSIG簽署記錄。
test.com. SOA ns.test.com. root.test.com. (2012041500 1h 10m 30d 1d ) test.com. NS ns.test.com. test.com. A 221.38.0.1 test.com. MX 0 mail.test.com. test.com. NSEC east.test.com. A NS SOA MX NSEC east.test.com. NS ns.east.test.com. east.test.com. NSEC ns.east.test.com. NS NSEC ns.east.test.com. A 221.38.0.6 ns.east.test.com. NSEC ftp.test.com. A NSEC ftp.test.com. CNAME www.test.com. ftp.test.com. NSEC mail.test.com. CNAME NSEC mail.test.com. A 221.38.0.2 mail.test.com. NSEC ns.test.com. A NSEC ns.test.com. A 221.38.0.1 ns.test.com. NSEC west.test.com. A NSEC west.test.com. NS ns.west.test.com. west.test.com. NSEC ns.west.test.com. NS NSEC ns.west.test.com. A 221.38.0.5 ns.west.test.com. NSEC www.test.com. A NSEC www.test.com. A 221.38.0.3 www.test.com. NSEC test.com. A NSEC |
由上面的例子可知如果有某一個用戶端向區域查詢north.test.com主機,這是一個不存在的主機,所以將得到回應 "mail.test.com.! NSEC ns.test.com. A NSEC" 及其RRSIG,代表並沒有主機名稱介於mail.test.com與ns.test.com之間,如果用戶端向本區域查詢 TXT類型的 mail.test.com主機,也將得到回應 "mail.test.com.! NSEC ns.test.com. A NSEC",而這回代表著涵義為沒有TXT類型的mail.test.com的主機存在,只有A與NSEC類型存在。
在NSEC的設計中是利用上下筆的網域名稱來驗證某網域主機確實不存在,但這可能會造成一個嚴重的安全性問題,因為有心人士只要透過一直不斷地查詢不存的在網域名稱,就可以收集取得整個網域的資料,效果等同非經授權的區域傳送,可作為下一步攻擊的依據。為了解決這個問題,RFC 5155 (DNSSEC Hashed Authenticated Denial of Existence)定義了NSEC 3 將原本NSEC 的排序方式改用雜湊函數(Hash)加密後再加以排序,如下例說明:
計算網域名稱的SHA雜湊值: Hash(a.test.com)= 96f7e437faa5a7fce15d1ddcb9eaeaea377667b8.test.com Hash(b..test.com)= e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98.test.com Hash(c.test.com)= 84a516841ba77a5b4648de2cd0dfcb30ea46dbb4.test.com 使用 NSEC (不需計算雜湊) a.test.com. NSEC b.test.com. b.test.com. NSEC c.test.com. 使用 NSEC3 (需計算雜湊) 84a516841ba77a5b4648de2cd0dfcb30ea46dbb4.test.com. NSEC3 96f7e437faa5a7fce15d1ddcb9eaeaea377667b8.test.com. 96f7e437faa5a7fce15d1ddcb9eaeaea377667b8.test.com. NSEC3 e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98.test.com. |
EDNS0、AD和CD位元
使用DNSSEC時還需要另一項協定-- EDNS0 的支援,定義於RFC 2671的EDNS(Extension Mechanisms for DNS)用來移除DNS訊息大小的限制 (傳統DNS的訊息大小限制為512位元),因為DNSSEC需要透過EDNS0用以支援較大的DNS訊息大小(讓UDP封包能擴展到 4096 位元組)和DNSSEC OK (DO) EDNS標頭位元,否則將無法傳送如 RRSIG此種資料記錄類型。
當一部DNS用戶端想要使用DNSSEC機來驗證DNS訊息時,將會送出 DNSSEC OK (DO)位元為1的查詢請求,而一旦啟用DNSSEC功能的DNS伺服器收到請求後,將會使用本機存放或收到的RRSIG記錄來驗證DNS訊息的真確性,驗證後將使用Authenticated Data (AD)位元回應結果,如果AD=1代表資料的真實性,AD=0則表示驗證結果失敗。
如果您需要診斷驗證失敗或是自行驗證資料,則可以在啟用AD位元外,再設定 Checking Disabled (CD) 這個旗標以提供有用的判斷和自行驗證的訊息,因為CD=1將通知遞迴解析的DNSSEC用戶停用RR的簽章驗證,若查詢結果為NOERROR(成功),其傳回結果將包括RR類型和其RRSIG RR,若結果為失敗,則可具此判斷何種原因導致
DNSSEC 負面衝擊
儘管DNSSEC 利用了公開金鑰和數位簽章技術解決了DNS資料偽裝和污染快取等問題,提升了DNS服務的安全性,但是卻也衝擊了DNS服務的效能並且提高了管理的複雜度與負載量,因為實現DNSSEC技術會帶來下列的負面影響:
- 膨脹數倍的區域檔案 (Larger Zone Files)
- 增加回應訊息的大小 (Larger Responses)
- 較多的查詢 (More Queries)
- 用戶端負載加重 (Higher Client Overhead)
- 伺服端負載加重 (Higher Server Overhead)
- 增多DNS區域管理上的錯誤 (Increased Zone Administration Errors)
就安全性而言,DNSSEC雖然可以防範各種DNS偽裝、假造、轉稼與下毒等攻擊威脅,但由於DNSSEC與EDNS0功能會擴大回應記錄,這恐怕會提升DNS 放大攻擊(DNS Amplification Attacks)的風險。
結語
DNSSEC 協定延伸了DNS的安全性,利用數位簽章的技術來確保用戶端收到正確無誤的DNS資料,設計用來防範DNS常見的偽裝假造((forged or manipulated))、轉稼(pharming)與快取下毒(cache poisoning)等驗證及完整性不完備的問題,不過DNSSEC的複雜度較高,再加以會明顯得影響到DNS查詢效率與流量,故使用與導入之前需仔細評估。
後續的文章將開始探討BIND DNS伺服器和微軟的DNS伺服器如何支援DNSSEC以及其實務作業與步驟。
相關文章