2015-03-03 15:27:39
Linux 用戶認證方法簡介
當今 IT 環(huán)境中,任何計算機系統(tǒng)都要充分考慮設計、使用和運行過程中的安全性。所以在目前主流操作系統(tǒng)的各個環(huán)節(jié)當中都增加了很多安全方面的功能和特性,而在眾多的安全特性和功能中有相當多的技術是確保用戶鑒別和身份認證方面的安全性的。
所謂用戶鑒別,就是用戶向系統(tǒng)以一種安全的方式提交自己的身份證明,然后由系統(tǒng)確認用戶的身份是否屬實的過程。換句話說,用戶鑒別是系統(tǒng)的門戶,每個用戶進入到系統(tǒng)之前都必須經(jīng)過鑒別這一道關。 而所謂認證安全,簡而言之就是計算機系統(tǒng)確認了用戶是經(jīng)過授權的合法用戶之后才能允許訪問。安全認證常用的方式是比對用戶輸入和預存于數(shù)據(jù)庫中的密碼。
不過在用戶進行身份鑒別和安全認證的過程中,肯定會涉及幾個核心問題。例如:
上述這些問題都是在設計鑒別和認證程序過程中需要充分考慮和精心設計的。而在 Linux 類的操作系統(tǒng)中,這些問題的處理實際上有一套完整的流程和機制。
在 Linux 類的操作系統(tǒng)中,初用戶鑒別過程就像各種 Unix 操作系統(tǒng)一樣:系統(tǒng)管理員為用戶建立一個帳號并為其指定一個口令,用戶用此指定的口令登錄之后重新設置自己的口令,這樣用戶就具有了一個只有它自己知道的口令或者密碼。一般情況下,用戶的身份信息在 Linux 系統(tǒng)中存放在/etc/passwd 文件當中,這實際上是一個擁有簡單格式的數(shù)據(jù)庫表,通過":"作為分隔符分隔出多個字段,其中包括用戶的名稱、用戶 ID、組 ID、用戶說明、主目錄和登錄使用的 shell 等相關信息。而用戶口令經(jīng)過加密處理后存放于/etc/shadow 文件中。也是一個格式類似的數(shù)據(jù)庫表,除了用戶名和經(jīng)過加密之后的密碼之外,還包括多個對密碼有效期進行定義的字段,包括密碼有效時間、密碼報警時間等。
用戶登錄的時候,登錄服務程序提示用戶輸入其用戶名和口令,然后將口令加密并與/etc/shadow 文件中對應帳號的加密口令進行比較,如果口令相匹配,說明用戶的身份屬實并允許此用戶訪問系統(tǒng)。這種思想基于只有用戶自己知道它的口令,所以輸入的口令是正確的話,那么系統(tǒng)就認定它是所聲稱的那個人。
在 Linux 類操作系統(tǒng)中,定義用戶信息和密碼信息的字段和格式都需要符合標準的 Linux Naming Service Switch 定義,即 NSS 定義。因此用戶信息只要保證滿足 NSS 規(guī)范,就可以來源于本地 passwd 和 shadow 之外的其它信息數(shù)據(jù)庫和認證源。所以在此基礎上還派生出一些其它認證解決方案。例如 NIS、LDAP 等,都可作為存放用戶信息的數(shù)據(jù)庫,而存放用戶口令或者鑒別用戶身份的數(shù)據(jù)庫,可以采用專用于網(wǎng)絡環(huán)境的 Kerberos 以及智能卡鑒別系統(tǒng)等方式。
這一整套的鑒別和認證方案貌似無懈可擊,但是將這種解決方案真正應用到操作系統(tǒng)中的話就會發(fā)現(xiàn)一些問題:
先進,在操作系統(tǒng)上所包含的認證不僅僅只涉及到系統(tǒng)登錄和訪問,在系統(tǒng)外圍往往提供了眾多的應用程序,相當多的應用程序在訪問過程中是有認證需求的。那么是否需要針對每一個應用程序都得加入認證和鑒別的功能?如果要,那么無論從程序的開發(fā)和使用管理角度來講,工作量都將成倍增加;如果不要,則系統(tǒng)級的用戶鑒別和安全認證與應用程序沒有任何關系,意味著不管用戶是否需要登錄系統(tǒng),但是對應用程序的訪問都將缺乏基本的安全性。
第二,如果針對每一個應用程序都開發(fā)用戶鑒別和認證的功能,那么一旦發(fā)現(xiàn)所用的算法存在某些缺陷或想采用另一種鑒別和認證方法時,開發(fā)者或者用戶都將不得不重寫(修改或替換)應用程序,然后重新編譯原程序。
所以,尤其是當實現(xiàn)鑒別功能的代碼以通常方法作為應用程序一部分一起編譯的時候,上述問題將十分突出。很明顯,傳統(tǒng)的身份鑒別和用戶認證方式一旦整合到實際的操作系統(tǒng)中,在實用當中缺乏靈活性。
鑒于以上原因,Linux 操作系統(tǒng)的開發(fā)者和設計人員開始尋找一種更佳的替代方案:一方面,將鑒別功能從應用中獨立出來,單獨進行模塊化的設計,實現(xiàn)和維護;另一方面,為這些鑒別模塊建立標準的應用程序接口即 API,以便眾多的應用程序能方便地使用它們提供的各種功能;同時,鑒別機制對上層用戶(包括應用程序和終用戶)要求一定要是透明的,這樣可以對使用者隱藏其中比較復雜的實現(xiàn)細節(jié)。
可插拔認證模塊 PAM 的基本概念
事實上直到 1995 年的時候,SUN 的研究人員才提出了一種滿足以上需求的方案,這就是可插拔認證模塊(Pluggable Authentication Module--PAM)機制,并首次在其操作系統(tǒng) Solaris 2.3 上部分實現(xiàn)。
可插拔認證模塊(PAM)機制采用模塊化設計和插件功能,使用戶可以輕易地在應用程序中插入新的認證模塊或替換原先的組件,同時不必對應用程序做任何修改,從而使軟件的定制、維持和升級更加輕松。因為認證和鑒別機制與應用程序之間相對獨立。所以應用程序可以通 PAM API 來方便地使用 PAM 提供的各種鑒別功能而不必了解太多的底層細節(jié)。此外 PAM 的易用性也較強,主要表現(xiàn)在它對上層屏蔽了鑒別和認證的具體細節(jié),所以用戶不必被迫學習各種各樣的鑒別方式,也不必記住多個口令;又由于它實現(xiàn)了多鑒別認證機制的集成問題,所以單個程序可以輕易集成多種鑒別機制,如 Kerberos 和 Diffie - Hellman 等認證機制,但用戶仍可以用同一個口令登錄而且感覺不到采取了各種不同的鑒別方法。
在廣大開發(fā)人員的努力下,各版本的 UNIX 系統(tǒng)陸續(xù)增加和提供了對 PAM 應用的支持。其中 Linux-PAM 是專門為 Linux 操作系統(tǒng)實現(xiàn)的,眾多的 Linux 操作系統(tǒng)包括 Caldera、Debian、Turbo、Red Hat、SuSE 及它們的后續(xù)版本都提供對 PAM 的支持。而 FreeBSD 從3.1版本也開始支持 PAM。而且除了具體實現(xiàn)方法上多少有些不同外,各種版本 Unix 系統(tǒng)上 PAM 的框架是相同的。所以我們在這里介紹的 Linux 的 PAM 框架知識具有相當?shù)钠毡樾?,而且在下文介紹其框架過程中可以看到,我們并沒有刻意區(qū)分 Unix PAM 與 Linux PAM 這兩個技術術語。
PAM 的分層體系結構
PAM 為了實現(xiàn)其插件功能和易用性,采取了分層設計思想。就是讓各鑒別模塊從應用程序中獨立出來,然后通過 PAM API 作為兩者聯(lián)系的紐帶,這樣應用程序就可以根據(jù)需要靈活地在其中"插入"所需要的鑒別功能模塊,從而真正實現(xiàn)了在認證和鑒別基礎上的隨需應變。實際上,這一思路也非常符合軟件設計中的"高內(nèi)聚,低耦合"這一重要思想。
PAM 的體系如下簡圖所示:
從上面的結構圖可以看出,PAM 的 API 起著承上啟下的作用,它是應用程序和認證鑒別模塊之間聯(lián)系的紐帶和橋梁:當應用程序調用 PAM API 時,應用接口層按照 PAM 配置文件的定義來加載相應的認證鑒別模塊。然后把請求(即從應用程序那里得到的參數(shù))傳遞給底層的認證鑒別模塊,這時認證鑒別模塊就可以根據(jù)要求執(zhí)行具體的認證鑒別操作了。當認證鑒別模塊執(zhí)行完相應的操作后,再將結果返回給應用接口層,然后由接口層根據(jù)配置的具體情況將來自認證鑒別模塊的應答返回給應用程序。
上面描述了 PAM 的各個組成部分以及整體的運作機理。下面將對 PAM 中的每一層分別加以介紹。
先進層:模塊層。模塊層處于整個 PAM 體系結構中的底層,它向上為接口層提供用戶認證鑒別等服務。也就是說所有具體的認證鑒別工作都是由該層的模塊來完成的。對于應用程序,有些不但需要驗證用戶的口令,還可能要求驗證用戶的帳戶是否已經(jīng)過期。此外有些應用程序也許還會要求記錄和更改當前所產(chǎn)生的會話類的相關信息或改變用戶口令等。所以 PAM 在模塊層除了提供鑒別模塊外,同時也提供了支持帳戶管理、會話管理以及口令管理功能的模塊。當然,這四種模塊并不是所有應用程序都必需的,而是根據(jù)需要靈活取舍。比如雖然 login 可能要求訪問上述所有的四種模塊,但是 su 可能僅僅需要使用到鑒別模塊的功能即可。至于如何取舍則涉及到接口層的 PAM API 和配置文件,這部分內(nèi)容將在后文中加以介紹。
第二層:應用接口層。應用接口層位于 PAM 結構的中間部分,它向上為應用程序屏蔽了用戶鑒別等過程的具體細節(jié),向下則調用模塊層中的具體模塊所提供的特定服務。由上圖可以看出,它主要由 PAM API 和配置文件兩部分組成,下面將逐一介紹。
PAM API 可以分為兩類:一類是用于調用下層特定模塊的接口,這類接口與底層的模塊相對應,包括:
第二類接口通常并不與底層模塊一一對應,它們的作用是對底層模塊提供支持以及實現(xiàn)應用程序與模塊之間的通信等。具體如下:
由于 PAM 模塊隨需加載,所以各模塊始化任務在先進次調用時完成。如果某些模塊的清除任務必須在鑒別會話結束時完成,則它們應該使用 pam_set_data()規(guī)定清除函數(shù),這些執(zhí)行清除任務的函數(shù)將在應用程序調用 pam_end()接口時被調用。
以上介紹了 Linux 可插拔認證模塊 PAM 的基本概念和分層體系結構,在后續(xù)文章里,將會介紹常見的 PAM 模塊應用以及相關實例。