通過修改 glibc 支持 DNS 加密
從某種意義上來說,這個問題多年以前就解決了,我們可以配置一個本地域名服務實現完整的 DNSSEC 校驗 並允許應用程序通過 glibc 函數來使用該服務。DNSSEC 甚至還可以用於提高其他領域的安全性,比如,它可以攜帶 SSH 或 TLS 密鑰指紋,讓應用程序可以確認其在與正確的伺服器對話。不過,當我們希望確認這條自稱帶有 DNSSEC 校驗的 DNS 結果是不是真的已通過認證的時候 - 也就是說,當我們想依賴 DNSSEC 所承諾的安全的時候,事情變得有點複雜。
/etc/resolv.conf 問題
從 glibc 的角度來看,這個問題一部分是因為 glibc 本身並沒有做 DNSSEC 校驗,而是引用 /etc/resolv.conf 文件,從該文件里讀出的伺服器來做解析以及校驗,再將結果返回給應用程序。如果應用程序使用底層 res_query() 介面,那結果中將會包含「 已認證數據 」(AD)標識(如果域名伺服器設定了的話)以表示 DNSSEC 校驗已經成功。但是 glibc 卻完全不知道提供這些結果的域名伺服器的信用,所以它其實並不能告訴應用程序結果是否真的可靠。
由 glibc 的維護者 Carlos O'Donell 提出的建議是在 resolv.conf 文件里增加一個選項(dns-strip-dnssec-ad-bit)告訴 glibc 無條件移除 AD 標識。這個選項可以由各發行版設定,表示 DNSSEC 級別的 DNS 查詢結果並不可靠。而一旦建立好合適的環境可以獲得可靠的查詢結果後,再移除這個選項。這樣一來,雖然問題還沒有完全解決,至少應用程序有依據來評價從 glibc 獲取的 DNS 查詢結果的可靠性。
一個可靠的環境配置應該是什麼樣?標準情況應該和這個差不太多:有一個本地域名伺服器,通過 環路 介面訪問,作為訪問 /etc/resolv.conf 文件的唯一條目。這個域名伺服器應該配置來做校驗,而在校驗失敗後就只是簡單地不返回任何結果。絕大多數情況下,應用程序就不再需要關心 AD 標識,如果結果不可靠,應用程序就根本看不到。一些發行版已經傾向於這種模型,不過情況仍然不像一些人所設想的那麼簡單。
其中一個問題是,這種方式將 /etc/resolv.conf 文件放到整個系統可信任度的中心。但是,在一個典型的 Linux 系統里,有無數的 DHCP 客戶端、網路腳本以及其他更多的程序可以修改這個文件。就像 Paul Wouters 所指出的,在短時間內鎖定這個文件是不可能的。有時候這種修改是必須的:在一個無盤系統啟動的時候,在自身的域名伺服器啟動之前也是需要域名服務的;一個系統的整個 DNS 環境也會根據所連接的網路不同而有所改變;運行在容器里的系統也最好是配置成使用宿主機的域名伺服器;等等。
所以,現在一般認為,現有系統里的 /etc/resolv.conf 文件並不可信。於是有人提出增加另一個配置文件(/etc/secure-resolv.conf 或其他什麼),但這並沒有從根本上解決問題。除此之外,有些參與者覺得就算有一個運行在環路介面上的域名伺服器也不是真正可靠,比如 Zack Weinberg 甚至建議系統管理員可以有意禁用 DNSSEC 確認 。
既然當前系統里的配置不足以信任,那可以這樣推斷,在情況有改善能夠取得可信的結果後,glibc 需要有一種方式來通知應用程序。可以是上面討論的屏蔽 AD 標識的方式(或者與之相反,增加一個顯示的「此域名伺服器可以信任」選項);當然,這都需要一定程度上鎖定系統以免 /etc/resolv.conf 受到任何不可預計的修改。按 Petr Spacek 的建議,還有一種引申方式,就是提供一種途徑允許應用程序查詢 glibc 當前通訊的是不是本地域名伺服器。
在 glibc 里來處理?
另一種方式是不管域名伺服器,而是讓 glibc 本身來做 DNSSEC 確認。不過,把這麼大一坨加密相關代碼放進 glibc 也是有很大阻力。這樣將增加庫本身的大小,從而感覺會增加使用它的應用程序的受攻擊可能性。這個方向再引申一下,由 Zack 提出的建議,可以把確認相關代碼放到域名服務緩衝守護進程(nscd)里。因為 nscd 也是 glibc 的一部分,由 glibc 開發人員維護,因此在一定程度上可以相信能正確執行 DNSSEC 確認。而且 nscd 的通訊 socket 所在位置也是公開的,所以可以不考慮 /etc/resolv.conf 問題。不過,Carlos 擔心這種方式不能讓那些不想使用 nscd 緩存功能的用戶所接受;在他看來,基本可以排除 nscd 的方式。
所以,至少近期內,glibc 不太可能全部執行 DNSSEC 確認了的整個查詢過程。這意味著,如果一個有安全考慮的應用要使用 glibc 庫來查詢域名,該庫將需要提供一個標識來評價從獨立域名伺服器返回的結果有多大程度的可靠性。這幾乎肯定需要發行版或系統管理員做出一些明確的改動。就像 Simo Sorce 說的那樣:
如果 glibc 不使用明確的配置選項來通知應用程序它所用的域名解析是可信的,不會有什麼用……不改一下還有很大弊端,因為應用程序開發者將馬上認識到他們不能信任從 glibc 獲取的任何信息,從而在處理 DNSSEC 相關信息時就簡單地不用它。
要配置一個系統能正常使用 DNSSEC 需要改動該系統的很多組件 - 這是一個發行版範圍的問題,需要時間來完全解決。在這個轉變過程中 glibc 所扮演的角色很可能會比較小,但是很重要的一部分:如果應用程序不實現一套自己的域名解析代碼,glibc 很可能是保證 DNS 結果可信的唯一方式。在一個系統中運行多個 DNSSEC 實現方式看起來不像是一種安全的方式,所以最好還是把事情做對了。
glibc 項目目前並沒有確定用哪種方式來做這個事情,雖然從 /etc/resolv.conf 文件里的某些標記看上去快好了。這種改動應該需要發布新版本;考慮到 glibc 開發的保守天性,很可能來不及加入預計二月份發布的 2.23 版本了。所以 glibc 中暫時還不會有更高安全性的 DNSSEC ,不過在這個方向上也有一些進展了。
via: https://lwn.net/Articles/664776/
作者:Jonathan Corbet 譯者:zpl1025 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive