您好,登錄后才能下訂單哦!
一、什么是Linux-PAM
為安全起見,計算機(jī)系統(tǒng)只有經(jīng)過授權(quán)的合法用戶才能訪問,在這里如何正確鑒別用戶的真實身份是一個關(guān)鍵的問題。所謂用戶鑒別,就是用戶向系統(tǒng)以一種安全的方式提交自己的身份證明,然后由系統(tǒng)確認(rèn)用戶的身份是否屬實的過程。換句話說,用戶鑒別是系統(tǒng)的門戶,每個用戶進(jìn)入到系統(tǒng)中都必須經(jīng)過鑒別這一道關(guān)。
最初,Linux系統(tǒng)的用戶鑒別過程就像各種Unix系統(tǒng)的一樣:系統(tǒng)管理員為用戶建立一個帳號并為其指定一個口令,用戶用此指定的口令登錄后重新設(shè)置自己的口令,這樣用戶就具有了一個只有他自己知道的秘密口令。一般情況下,用戶的口令經(jīng)過加密處理后存放于 /etc/passwd 文件中。用戶登錄時,登錄服務(wù)程序提示用戶輸入其用戶名和口令,然后將口令加密并與 /etc/passwd 文件中對應(yīng)帳號的加密口令進(jìn)行比較,如果口令相匹配,說明用戶的身份屬實并允許此用戶訪問系統(tǒng)。這種思想基于只有用戶自己知道他的口令,所以輸入的口令是正確的話,那么系統(tǒng)就認(rèn)定他是所聲稱的那個人。
后來,還采用了許多其他的鑒別用戶的方法,如用于網(wǎng)絡(luò)環(huán)境的 Kerberos 以及基于智能卡的鑒別系統(tǒng)等。但是這些鑒別方案有一個通病:實現(xiàn)鑒別功能的代碼通常作為應(yīng)用程序的一部分而一起編譯,這樣問題就來了------如果發(fā)現(xiàn)所用算法存在某些缺陷或想采用另一種鑒別方法時,用戶不得不重寫(修改或替換)然后重新編譯原程序。很明顯,我們原先的鑒別方案缺乏靈活性,這里的牽一發(fā)而動全身的情形很是讓人惱火。
鑒于以上原因,人們開始尋找一種更佳的替代方案:一方面,將鑒別功能從應(yīng)用中獨立出來,單獨進(jìn)行模塊化設(shè)計,實現(xiàn)和維護(hù);另一方面,為這些鑒別模塊建立標(biāo)準(zhǔn) API,以便各應(yīng)用程序能方便的使用它們提供的各種功能;同時,鑒別機(jī)制對其上層用戶(包括應(yīng)用程序和最終用戶)是透明的。直到 1995 年,SUN 的研究人員提出了一種滿足以上需求的方案--插件式鑒別模塊(PAM)機(jī)制并首次在其操作系統(tǒng) Solaris 2.3 上部分實現(xiàn)。插件式鑒別模塊(PAM)機(jī)制采用模塊化設(shè)計和插件功能,使得我們可以輕易地在應(yīng)用程序中插入新的鑒別模塊或替換原先的組件,而不必對應(yīng)用程序做任何修改,從而使軟件的定制、維持和升級更加輕松--因為鑒別機(jī)制與應(yīng)用程序之間相對獨立。應(yīng)用程序可以通過 PAM API 方便的使用 PAM 提供的各種鑒別功能,而不必了解太多的底層細(xì)節(jié)。此外,PAM的易用性也較強(qiáng),主要表現(xiàn)在它對上層屏蔽了鑒別的具體細(xì)節(jié),所以用戶不必被迫學(xué)習(xí)各種各樣的鑒別方式,也不必記住多個口令;又由于它實現(xiàn)了多鑒別機(jī)制的集成問題,所以單個程序可以輕易集成多種鑒別機(jī)制如 Kerberos 鑒別機(jī)制和 Diffie - Hellman 鑒別機(jī)制等,但用戶仍可以用同一個口令登錄而感覺不到采取了各種不同鑒別方法。
在廣大開發(fā)人員的努力下,各版本的 UNIX 系統(tǒng)陸續(xù)提供對 PAM 的支持。其中,Linux-PAM 是專門為 Linux 機(jī)器實現(xiàn)的,包括 Caldera 1.3、2.2、Debian 2.2、Turbo Linux 3.6、Red Hat 5.0 以及 SuSE 6.2 及它們的后續(xù)版本都提供對 PAM 的支持。FreeBSD 從 3.1 版開始支持 PAM。需要注意的是,除了具體實現(xiàn)不同外,各種版本 Unix 系統(tǒng)上的 PAM 的框架是相同的,所以我們在這里介紹的 Linux-PAM 框架知識具有普遍性。因此在下文介紹其框架的過程中可以看到,我們并沒有刻意區(qū)分 PAM 與 Linux-PAM 這兩個術(shù)語。
二、PAM 的分層體系結(jié)構(gòu)
PAM 為了實現(xiàn)其插件功能和易用性,它采取了分層設(shè)計思想:讓各鑒別模塊從應(yīng)用程序中獨立出來,然后通過PAM API作為兩者聯(lián)系的紐帶,這樣應(yīng)用程序就可以根據(jù)需要靈活地在其中"插入"所需鑒別功能模塊,從而真正實現(xiàn)了"鑒別功能,隨需應(yīng)變"。實際上,這一思路非常符合軟件設(shè)計中的"高內(nèi)聚,低耦合"這一重要思想,PAM 的體系如下簡圖所示:
圖1 PAM體系結(jié)構(gòu)
從上圖可以看出,PAM API 起著承上啟下的作用,它是應(yīng)用程序和鑒別模塊之間聯(lián)系的紐帶:當(dāng)應(yīng)用程序調(diào)用 PAM API 時,應(yīng)用接口層按照配置文件 pam.conf 的規(guī)定,加載相應(yīng)的鑒別模塊。然后把請求(即從應(yīng)用程序那里得到的參數(shù))傳遞給底層的鑒別模塊,這時鑒別模塊就可以根據(jù)要求執(zhí)行具體的鑒別操作了。當(dāng)鑒別模塊執(zhí)行完相應(yīng)操作后,將結(jié)果返回給應(yīng)用接口層,然后由接口層根據(jù)配置的具體情況將來自鑒別模塊的應(yīng)答返回給應(yīng)用程序。
上面描述了 PAM 的各個組成部分,以及它們作為整體的運作機(jī)理。下面將對 PAM 的關(guān)鍵的低二層分別加以介紹。
三、第一層:模塊層
模塊層處于整個結(jié)構(gòu)的最底層,它向上為接口層提供用戶鑒別等服務(wù),也就是說所有具體的鑒別工作都是由該層的模塊來完成的。對于應(yīng)用程序,有些不但需要驗證用戶的口令,還可能要求驗證用戶的帳戶是否已經(jīng)過期。此外,有些應(yīng)用程序也許還會要求記錄當(dāng)前會話的有關(guān)信息或改變口令等,所以 PAM 在模塊層除了提供鑒別模塊外,同時提供了支持帳戶管理、會話管理以及口令管理功能的模塊。當(dāng)然,這四種模塊并不是所有應(yīng)用程序所必需的,而是根據(jù)需要靈活取舍,比如雖然 login 可能要求訪問所有四種模塊,但是 su 可能僅僅需要使用鑒別組件即可。至于如何取舍則涉及到接口層的 PAM API和配置文件,這部分內(nèi)容將在下文中加以介紹。
四、第二層:應(yīng)用接口層
應(yīng)用接口層位于 PAM 結(jié)構(gòu)的中間部分,它向上為應(yīng)用程序屏蔽了用戶鑒別等過程的具體細(xì)節(jié),向下調(diào)用模塊層中的具體模塊所提供的特定服務(wù)。由圖1可以看出,它主要由 PAM API 和配置文件兩部分組成,下面將逐一介紹。
PAM API 可以分為兩類,一類是用于調(diào)用下層特定模塊的接口,這類接口與底層的模塊相對應(yīng):
1. 鑒別類接口:pam_authenticate()用于鑒別用戶,pam_setcred()用于修改用戶的秘密信息。
2. 帳號類接口:pam_acct_mgmt()檢查受鑒別的用戶所持帳戶是否有權(quán)登陸系統(tǒng),以及該帳戶是否已過期等。
3. 會話類接口:包括用于會話管理和記帳的 pam_open_session()和 pam_close_session()函數(shù)。
4. 口令類接口:包括用于修改用戶口令的 pam_chauthtok()。
第二類接口通常并不與底層模塊一一對應(yīng),它們的作用是對底層模塊提供支持以及實現(xiàn)應(yīng)用程序與模塊之間的通信等。具體如下:
1. 管理性接口
每組 PAM 事務(wù)從 pam_start()開始,結(jié)束于 pam_end()函數(shù)。接口 pam_get_item()和 pam_set_item()用來讀寫與 PAM 事務(wù)有關(guān)的狀態(tài)信息。同時,能夠用 pam_str()輸出 PAM 接口的出錯信息。
2. 應(yīng)用程序與模塊間的通訊接口
在應(yīng)用程序初始化期間,某些諸如用戶名之類的數(shù)據(jù)可以通過 pam_start()將其存放在PAM接口層中,以備將來底層模塊使用。另外,底層模塊還可以使用 pam_putenv()向應(yīng)用程序傳遞特定的環(huán)境變量,然后應(yīng)用程序利用 pam_getenv() 和 pam_getenvlist() 讀取這些變量。
3. 用戶與模塊間的通訊接口
pam_start()函數(shù)可以通過會話式的回調(diào)函數(shù),讓底層模塊通過它們讀寫模塊相關(guān)的鑒別信息,比如以應(yīng)用程序所規(guī)定的方式提示用戶輸入口令。
4. 模塊間通訊接口
盡管各模塊是獨立的,但是他們?nèi)匀荒軌蛲ㄟ^ pam_get_item()和 pam_set_item()接口共享某些與鑒別會話有關(guān)的公用信息,諸如用戶名、服務(wù)名、口令等。此外,這些API還可以用于在調(diào)用 pam_start()之后,讓應(yīng)用程序修改狀態(tài)信息。
5. 讀寫模塊狀態(tài)信息的接口
接口 pam_get_data()和 pam_set_data()用以按照PAM句柄要求訪問和更新特定模塊的信息。此外,還可以在這些模塊后附加一個清除數(shù)據(jù)函數(shù),以便當(dāng)調(diào)用 pam_end()時清除現(xiàn)場。
由于 PAM 模塊隨需加載,所以各模塊始化任務(wù)在第一次調(diào)用時完成。如果某些模塊的清除任務(wù)必須在鑒別會話結(jié)束時完成,則它們應(yīng)該使用 pam_set_data()規(guī)定清除函數(shù),這些執(zhí)行清除任務(wù)的函數(shù)將在應(yīng)用程序調(diào)用 pam_end()接口時被調(diào)用。
五、配置文件
我們注意到,配置文件也放在了在應(yīng)用接口層中,它與 PAM API 配合使用,從而達(dá)到了在應(yīng)用中靈活插入所需鑒別模塊的目的。它的作用主要是為應(yīng)用選定具體的鑒別模塊,模塊間的組合以及規(guī)定模塊的行為。下面是一個示例配置文件:
圖2.示例配置文件
我們可以看到,配置文件有許多登記項(每行對應(yīng)一個登記項)組成,每一行又分為五列(每列對應(yīng)一欄),詳細(xì)解釋如下:
第一欄,service表示使用PAM的應(yīng)用程序,比如login、passwd、rlogin等。這一欄中的OTHER表示所有沒在該文件中顯式列出的應(yīng)用。也就是說,如果所有程序具有相同的需求,整個配置文件只需要一行即可,并且該行的第一欄為OTHER。本例中,因為所有應(yīng)用程序使用相同的會話模塊,所以實際上可以用單行,即
" OTHER auth required pam_unix_auth.so"
來代替文件中的這些行:
"login session required pam_unix_session.so
ftp session required pam_unix_session.so
telnet session required pam_unix_session.so"。
第二欄,module_type指明程序所用PAM底層模塊的類型:auth表示鑒別類模塊;account表示帳戶類模塊;session表示會話類模塊;password表示口令類模塊。注意,每行只能指定一種類型模塊,如果程序需要多種模塊的話,可在多行中分別規(guī)定。
第三欄,control_flag規(guī)定如何處理模塊的成功和失敗情況。單個應(yīng)用程序可以調(diào)用多種底層模塊,這通常稱為"堆疊",對應(yīng)于某程序的按照配置文件中出現(xiàn)順序執(zhí)行的所有模塊成為"堆",堆中的各模塊的地位與出錯時的處理由control_flag欄的取值決定,它的五種可能的取值分別為 required、Requisite、sufficient或_optional,現(xiàn)介紹如下:
required--它表示該模塊的成功是用戶通過鑒別的必要條件,換句話說,只有當(dāng)對應(yīng)于應(yīng)用程序的所有帶required標(biāo)記的模塊全部成功后,該程序才能通過鑒別。同時,如果任何帶required標(biāo)記的模塊出現(xiàn)了錯誤,PAM并不立刻將錯誤消息返回給應(yīng)用程序,而是在所有模塊都調(diào)用完畢后才將錯誤消息返回調(diào)用它的程序。
Requisite--它與required相仿,只有帶此標(biāo)記的模塊返回成功后,用戶才能通過鑒別,不同之處在于其一旦失敗就不再執(zhí)行堆中后面的其它模塊,并且鑒別過程到此結(jié)束。
optional--它表示即便該模塊失敗,用戶仍能通過鑒別。在PAM體系中,帶有該標(biāo)記的模塊失敗后將繼續(xù)處理下一模塊。
sufficient--它表示該模塊取得成功是用戶通過鑒別的充分條件,也就是說只要標(biāo)記為sufficient的模塊一旦成功,那么PAM便立即向應(yīng)用程序返回成功而不必嘗試任何其他模塊。當(dāng)標(biāo)記為sufficient的模塊失敗時,sufficient模塊當(dāng)做optional對待。
第四欄,module_path指出PAM模塊的位置。
第五欄,options用于向特定模塊傳遞相關(guān)的選項,然后由模塊分析解釋這些任選項。比如使用此欄打開模塊調(diào)試,或向某模塊傳遞諸如超時值之類的參數(shù)等。另外,它還用于支持下文所述的口令映射技術(shù)。
如果任一欄出現(xiàn)錯誤,或某模塊沒有找到,那么所在行被忽略并將其作為嚴(yán)重錯誤進(jìn)行記錄。
本例中,login程序使用UNIX口令模塊進(jìn)行鑒別,而ftp程序卻使用S/Key模塊進(jìn)行鑒別。如我們想改變ftp程序的鑒別方法,比如也用UNIX口令模塊進(jìn)行鑒別,那么我們不必改動源程序,只需將配置文件中的
ftp auth required pam_skey_auth.so debug
改為
ftp auth required pam_unix_auth.so debug
這樣,當(dāng)用戶使用ftp時,將用傳統(tǒng)的UNIX口令鑒別方式來驗證其身份。由此可見,在PAM體制下為應(yīng)用程序改變鑒別機(jī)制是一件輕松的事情。另外,PAM體制的堆疊功能還使得應(yīng)用程序能夠支持多種鑒別機(jī)制,如下例中的login程序在配置文件中先后出現(xiàn)了三項與鑒別有關(guān)的登記項:
圖3.示例配置文件
當(dāng)login程序執(zhí)行時先用pam_unix.so模塊即傳統(tǒng)的UNIX口令方式鑒別用戶,然后再調(diào)用pam_kerb.so模塊即 Kerberos對用戶進(jìn)行鑒別,最后用pam_rsa.so模塊即RSA方式鑒別用戶。在按上述順序鑒別用戶的過程中,如果pam_unix.so模塊鑒別失敗,它將繼續(xù)調(diào)用下面的模塊進(jìn)行鑒別而非立刻向login程序返回錯誤消息;pam_kerb.so模塊也按同樣方式處理,直到順序處理完最后一個 pam_rsa.so模塊后,PAM才將前面出現(xiàn)的錯誤信息返回給login程序。對于該配置,即使pam_rsa.so模塊順利通過,只要 pam_unix.so模塊和pam_kerb.so模塊中有一個出現(xiàn)錯誤,用戶就不能通過鑒別;相反,即使pam_rsa.so模塊失敗,只要 pam_unix.so模塊和pam_kerb.so模塊都通過了,用戶也能通過鑒別。
六、口令映射
在同一個機(jī)器上使用多個鑒別機(jī)制,尤其是一個應(yīng)用程序集成多種鑒別機(jī)制可能導(dǎo)致用戶需要記憶多個口令,這會讓用戶覺得很不舒服。雖然可以讓所有機(jī)制使用相同的口令來獲取易用性,但是這將削弱系統(tǒng)的安全性--如果其中任何一個機(jī)制的口令泄露了,則所有機(jī)制都會受到牽累。此外,不同的鑒別機(jī)制在口令長度、容許的字符、更新間隔、有效期等方面可能具有他們特有的要求,這些要求也是為多鑒別機(jī)制使用同一個口令必須考慮的一個問題。
PAM為我們提供了這樣一種解決方案,它不排除為所有鑒別機(jī)制共用一個口令,同時允許通過口令映射技術(shù)讓每個機(jī)制使用不同的口令。該方案用用戶的" 主口令"加密其他的"副口令",并且將這些經(jīng)過加密的副口令存放在一個用戶能訪問的地方。主口令一旦經(jīng)過驗證,鑒別模塊就能用它解密那些加密的副口令從而獲得相應(yīng)口令,然后將所需口令傳遞給鑒別模塊。這稱為"口令映射"。如果口令映射出現(xiàn)錯誤,或如果映射不存在,那么各鑒別模塊應(yīng)該提示用戶輸入口令。為支持口令映射,主口令應(yīng)保存在PAM第二層并且在需要時由其提供給堆疊的各個鑒別模塊。同時,口令要在pam_authenticate函數(shù)返回之前清除。為了保障口令映射的安全,主口令必須足夠強(qiáng)壯,可以考慮使其的長度更長、組成口令字符的類型多樣化并使用混合類型的字符組成口令等有效措施。
口令如何加密及其存儲完全取決于具體的實現(xiàn):它能夠?qū)⒓用艿母笨诹睿ㄒ卜Q作"映射口令")存儲在可靠或不可靠的地方,諸如智能卡、本地文件或目錄服務(wù)。當(dāng)然,如果加密的口令保存在一個不可靠的允許公共訪問的地方,會留下受到字典攻擊的隱患。
為實現(xiàn)口令映射,所有鑒別模塊應(yīng)支持以下四個映射選項∶
1. use_first_pass∶它表示當(dāng)該模塊執(zhí)行時不提示用戶輸入口令,而將該模塊之前的提示用戶輸入的主口令作為它們的公共口令進(jìn)行驗證。如果用戶沒能通過主口令的鑒別,則該模塊不提示用戶輸入口令。此選項一般說來在系統(tǒng)管理員想強(qiáng)制用同一個口令通過多模塊時使用。
2. try_first_pass∶除了如果主口令不正確,將提示用戶輸入口令之外,它的用法與use_first_pass相同。
3. use_mapped_pass∶它表示使用口令映射技術(shù)得到此模塊的有效口令。也就是說,該模塊執(zhí)行時不提示用戶輸入口令,而是用映射口令即用主口令解密得到的該模塊的副口令作為本模塊的口令輸入進(jìn)行驗證。如果在此之前用戶沒能通過主口令的鑒別,則該模塊也不會提示輸入口令。
4. try_mapped_pass∶除了如果主口令不正確,它將提示用戶輸入口令之外,該項與use_mapped_pass用法相同。
當(dāng)口令更換后,PAM會保存所有新舊口令,并且使有關(guān)模塊能夠訪問到它們。其他模塊能夠使用此信息更新加密的口令而不必強(qiáng)制用戶再次輸入口令。
現(xiàn)以下面的配置文件為例講解口令映射:
圖4. 示例配置文件
在這里login程序集成了三種鑒別方式:傳統(tǒng)UNIX口令鑒別、Kerberos和RSA鑒別,但通常情況下用戶僅輸入一次口令便能通過鑒別了。當(dāng)程序調(diào)用pam_unix.so模塊時,PAM提示用戶輸入他們的UNIX口令,然后由pam_kerb.so模塊對用戶輸入的UNIX口令進(jìn)行鑒別。繼而調(diào)用pam_kerb.so模塊,由于該模塊的選項為use_mapped_pass,它將利用口令映射機(jī)制進(jìn)行認(rèn)證,也就是說,如果UNIX口令鑒別通過的話,就將其作為pam_kerb.so模塊的主口令來解密其對應(yīng)的映射口令從而進(jìn)行Kerberos鑒別。如果pam_unix.so模塊所需口令沒能通過驗證,則無法進(jìn)行口令映射,那么PAM將直接調(diào)用下一鑒別模塊而不提示用戶輸入其Kerberos口令。最后一個模塊的選項為 use_first_pass,所以pam_rsa.so模塊將使用前邊輸入的主口令來鑒別用戶,如果口令錯誤也不提示用戶輸入RSA口令。所以,只要第一次輸入的口令是正確的,并且映射口令存在,則一個口令便足以通過鑒別。
七、結(jié)束語
Linux-PAM是一種使用靈活功能強(qiáng)大的用戶鑒別機(jī)制,本文對它的組成結(jié)構(gòu)以及各部分之間的關(guān)系進(jìn)行了相應(yīng)的分析,希望對讀者理解PAM的機(jī)制有所幫助。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。