Linux身份鑒別機(jī)制概述
PAM: 你是誰???
你的金光驚醒了石頭的酣夢(mèng)!
2
總體描述
Linux身份鑒別機(jī)制是保護(hù)操作系統(tǒng)安全的重要機(jī)制之一,是防止惡意用戶進(jìn)入系統(tǒng)的一個(gè)重要環(huán)節(jié)。早期的身份鑒別機(jī)制就是傳統(tǒng)的UNIX身份鑒別機(jī)制,它采用口令加密并與原密碼進(jìn)行對(duì)比的方式來對(duì)用戶身份進(jìn)行鑒別。但是這種加密方式過于單一,在一個(gè)服務(wù)中用戶的帳號(hào)密碼泄露會(huì)涉及到多個(gè)服務(wù)的安全性,所以為了增強(qiáng)系統(tǒng)的安全性,出現(xiàn)了許多其他的身份鑒別機(jī)制,如指紋認(rèn)證、USB認(rèn)證等。但是這樣導(dǎo)致了一個(gè)問題,為了應(yīng)用這些認(rèn)證機(jī)制,就需要重新編寫并編譯應(yīng)用程序(如系統(tǒng)登陸服務(wù)login)。為了解決這個(gè)問題,1995年Sun公司的Vipin Samar和 Charlie Lai提出了PAM(Pluggable Authentication Modules)身份鑒別機(jī)制,它采用模塊化設(shè)計(jì)和插件功能,使得系統(tǒng)在更改認(rèn)證機(jī)制時(shí)不再需要修改應(yīng)用程序,極大的提高了認(rèn)證機(jī)制的靈活性。本報(bào)告對(duì)Linux各用戶帳號(hào)的權(quán)限區(qū)別進(jìn)行了分析,對(duì)傳統(tǒng)UNIX身份鑒別機(jī)制的實(shí)現(xiàn)過程進(jìn)行了研究,重點(diǎn)對(duì)PAM身份鑒別機(jī)制的實(shí)現(xiàn)過程進(jìn)行了研究與分析,最后通過一個(gè)具體的PAM策略演示場(chǎng)景實(shí)現(xiàn)了身份鑒別機(jī)制的執(zhí)行過程,研究結(jié)果也發(fā)現(xiàn)Linux身份鑒別機(jī)制是在Linux用戶態(tài)下實(shí)現(xiàn)的,并不涉及內(nèi)核的具體實(shí)現(xiàn)。
由于Linux身份鑒別機(jī)制是在用戶態(tài)下實(shí)現(xiàn),本報(bào)告涉及的源碼包括Linux-PAM-1.1.6,openpam和Linux su命令的實(shí)現(xiàn)。具體范圍說明如下:
Linux-PAM-1.1.6/moudles/pam_access.c:登錄認(rèn)證模塊的實(shí)現(xiàn)源碼。
Linux-PAM-1.1.6/libpam:PAM所用的頭文件。
openpam/lib/pam_acct_mgmt.c:賬號(hào)管理接口函數(shù)實(shí)現(xiàn)。
Linux su命令:Linux系統(tǒng)命令源碼包。
Linux身份鑒別機(jī)制就是對(duì)請(qǐng)求服務(wù)的用戶身份進(jìn)行鑒別,并且賦予相應(yīng)的權(quán)限的過程。本文通過查閱資料,分析Linux系統(tǒng)中對(duì)各用戶帳號(hào)的管理及其權(quán)限分配,分析傳統(tǒng)的UNIX身份鑒別機(jī)制,以su命令的代碼實(shí)現(xiàn)來進(jìn)行說明,著重分析PAM身份鑒別機(jī)制,并對(duì)其代碼實(shí)現(xiàn)來進(jìn)行分析說明。
在Linux系統(tǒng)中,系統(tǒng)設(shè)置了多個(gè)帳號(hào)和組來進(jìn)行管理,每個(gè)帳號(hào)都具有不同的權(quán)限,例如超級(jí)用戶root就具有最大的權(quán)限,對(duì)所有的文件具有讀寫執(zhí)行的權(quán)限,但是普通用戶對(duì)某些文件只具有讀有時(shí)甚至連讀的權(quán)限都沒有。Linux操作系統(tǒng)并不是以帳號(hào)名稱來識(shí)別用戶的,而是以標(biāo)識(shí)符UID和GID來辨別用戶的,這些帳號(hào)的信息都存放在/etc/passwd文件當(dāng)中,該文件中記錄的每個(gè)帳號(hào)信息是以行來表現(xiàn)的,如下所示:
root:x:0:0:root:/root:/bin/bash
每行是以7個(gè)字段來描述的,每個(gè)字段以冒號(hào)來進(jìn)行分隔,其中對(duì)應(yīng)字段的依次解釋如下:
1. 帳號(hào)名稱:用來對(duì)應(yīng)UID。
2. 密碼:所有的用戶都有對(duì)該文件的訪問權(quán)限,為了防止密碼竊取,就將這個(gè)字段的密碼數(shù)據(jù)改放到/etc/shadow中了,所以這里顯示的是X。
3. UID:用戶標(biāo)識(shí)符,表1-1列出了redhat系統(tǒng)中UID號(hào)的限制。
表1-1 UID限制
Id范圍 |
該用戶ID特性 |
0(系統(tǒng)管理員) |
當(dāng)UID為0時(shí),代表這個(gè)帳號(hào)是“系統(tǒng)管理員”!所以當(dāng)你要讓其他的帳號(hào)名稱也具有root權(quán)限時(shí),將該帳號(hào)的UID改為0即可。一個(gè)系統(tǒng)上面的系統(tǒng)管理員不見得只有root.不過不建議有多個(gè)。 |
1~499(系統(tǒng)帳號(hào)) |
保留給系統(tǒng)使用的ID,其實(shí)除了0之外,其他的UID權(quán)限與特性并沒有不一樣。默認(rèn)500以下的數(shù)字讓給系統(tǒng)作為保留帳號(hào)只是一個(gè)習(xí)慣。1~99:由distributions自行創(chuàng)建的系統(tǒng)帳號(hào);100~499:若用戶有系統(tǒng)帳號(hào)需求時(shí),可以使用的帳號(hào)UID。 |
500~65535 |
給一般用戶使用的 |
4. GID:用戶組標(biāo)識(shí)符,具體信息存放在/etc/group中。
5. 用戶信息說明列:解釋這個(gè)帳號(hào)的意義。
6. 主文件夾:即用戶的主文件夾。
7. Shell:當(dāng)用戶登錄系統(tǒng)后就會(huì)取得一個(gè)shell來與系統(tǒng)的內(nèi)核通信以進(jìn)行用戶的操作任務(wù)(一個(gè)shell可以用來替代成讓帳號(hào)無法取得shell環(huán)境的登錄操作/sbin/nologin)。
/etc/shadow中也是這樣的字段,具體字段的意義這里不再做詳細(xì)解釋,這個(gè)文件主要是為了增加系統(tǒng)安全性而另外設(shè)置用來存放用戶的密碼,只有root用戶才有權(quán)限訪問,但是為了安全性顯示的仍然是加密后的密碼。
系統(tǒng)是通過UID、GID來對(duì)不同的帳號(hào)進(jìn)行區(qū)分的,但是系統(tǒng)中是如何對(duì)應(yīng)實(shí)現(xiàn)具體的權(quán)限設(shè)置的呢?這里就從文件的權(quán)限來進(jìn)行說明。執(zhí)行ls -al命令后,結(jié)果如圖1-1所示。
圖1-1 文件屬性
每行顯示內(nèi)容分為七列:第一列代表這個(gè)文件的類型與權(quán)限,第二列表示有多少文件名鏈接到這個(gè)節(jié)點(diǎn),第三列表示這個(gè)文件的所有者的帳號(hào),第四列表示這個(gè)文件的所屬用戶組,第五列表示這個(gè)文件的容量大小,默認(rèn)單位為B,第六列為該文件的創(chuàng)建文件日期或者是最近的修改日期,第七列為該文件名。
第一列中總共有10個(gè)字符,這10個(gè)字符解釋如下:
1. 第一個(gè)字符為[d],表示為目錄,為[-]則是文件,為[l]則是鏈接文件,為[b]則表示設(shè)備文件里面的可供存儲(chǔ)的接口設(shè)備,為[c]則表示設(shè)備文件里面的串行端口設(shè)備,比如鍵盤、鼠標(biāo)等。
2. 接下來都是以三個(gè)字符為一組,一共有三組,且每組都是以“rwx”這樣的形式組合,其中[r]代表刻度,[w]代表可寫,[x]代表可執(zhí)行,如果沒有該權(quán)限則會(huì)用[-]來表示。第一組是文件所有者的權(quán)限,第二組為同組的權(quán)限,第三組為其他非本用戶組的權(quán)限。這樣就把文件的可讀屬性與不同用戶帳號(hào)的權(quán)限對(duì)應(yīng)起來了。
傳統(tǒng)的UNIX身份鑒別即口令認(rèn)證方式,它主要通過識(shí)別用戶的用戶名或者UID號(hào)獲取在/etc/shadow中存放的對(duì)應(yīng)用戶密碼密文等信息,然后獲取用戶輸入密碼并采用crypt()函數(shù)對(duì)獲得的輸入密碼進(jìn)行加密,當(dāng)然加密方式是與原用戶密碼的加密方式是一致的,然后將這兩個(gè)密文進(jìn)行比較,如果一致則通過驗(yàn)證,如果不一致則拒絕賦予權(quán)限。接下來以登錄Linux系統(tǒng)為例,說明登錄過程中傳統(tǒng)UNIX認(rèn)證方式對(duì)用戶帳號(hào)的鑒別過程。Linux用戶在登錄主機(jī)時(shí)會(huì)出現(xiàn)一個(gè)輸入賬號(hào)及密碼的界面,Linux會(huì)先找尋 /etc/passwd 里面是否有這個(gè)賬號(hào),如果拒絕用戶登錄請(qǐng)求,如果有的話則將該賬號(hào)對(duì)應(yīng)的 UID 、GID、該賬號(hào)的主目錄與shell設(shè)定 一并讀出,接著就是將用戶輸入密碼進(jìn)行加密,然后讀取/etc/shadow 中存放的密碼,將這個(gè)密碼與用戶輸入并加密的密碼進(jìn)行核對(duì),如果核對(duì)成功,則進(jìn)入系統(tǒng)。
Linux 提供getpwnam()來獲取用戶登錄的相關(guān)信息,返回的是一個(gè)passwd型的結(jié)構(gòu)體,該結(jié)構(gòu)體就包含了用戶帳號(hào)的各種信息,該結(jié)構(gòu)體如下所示。
PAM(Pluggable Authentication Modules)即可插拔驗(yàn)證模塊,它是一個(gè)非常完善的身份驗(yàn)證機(jī)制,它采用模塊化設(shè)計(jì)和插件功能,從而可以輕易的在應(yīng)用程序中插入新的鑒別模塊或者替換原來的組件,而不必對(duì)應(yīng)用程序做任何修改,從而使軟件的定制、維持和升級(jí)更加輕松。PAM 的易用性較強(qiáng),它對(duì)上層屏蔽了鑒別的具體細(xì)節(jié),用戶不必詳細(xì)知道各種鑒別機(jī)制是如何實(shí)現(xiàn)的,它還實(shí)現(xiàn)了多鑒別機(jī)制的集成問題。
PAM 為了實(shí)現(xiàn)其插件功能和易用性,采取了分層設(shè)計(jì)思想。就是讓各鑒別模塊從應(yīng)用程序中獨(dú)立出來,然后通過 PAM的API、 SPI作為兩者聯(lián)系的紐帶,這樣應(yīng)用程序就可以根據(jù)需要靈活地在其中“插入”所需要的鑒別功能模塊,從而真正實(shí)現(xiàn)了在認(rèn)證和鑒別基礎(chǔ)上的隨需應(yīng)變。PAM框架如下圖所示:
其中的配置文件(etc/pam.d)是由系統(tǒng)管理員來設(shè)置的,用以制定認(rèn)證策略。當(dāng)應(yīng)用程序調(diào)用 PAM 的API 時(shí),應(yīng)用接口層按照 PAM 配置文件的定義來加載相應(yīng)的認(rèn)證鑒別模塊,然后把請(qǐng)求(即從應(yīng)用程序那里得到的參數(shù))傳遞給底層的認(rèn)證鑒別模塊,這時(shí)認(rèn)證鑒別模塊就可以根據(jù)要求執(zhí)行具體的認(rèn)證鑒別操作了。當(dāng)認(rèn)證鑒別模塊執(zhí)行完相應(yīng)的操作后,再將結(jié)果返回給應(yīng)用接口層,然后由接口層根據(jù)配置的具體情況將來自認(rèn)證鑒別模塊的應(yīng)答返回給應(yīng)用程序。
上面簡(jiǎn)單描述了PAM的運(yùn)作方式,下面對(duì)它的三個(gè)層次加以介紹:
1.最上層為應(yīng)用程序?qū)樱菏褂肞AM 機(jī)制的應(yīng)用程序(如login、su等),調(diào)用PAM接口庫(kù)的上層接口API來實(shí)現(xiàn)認(rèn)證功能;
2.中間為應(yīng)用接口層:連接應(yīng)用程序和服務(wù)模塊的中間層,它根據(jù)配置文件中的設(shè)置加載相應(yīng)的服務(wù)模塊,將請(qǐng)求傳遞到具體的服務(wù)模塊,向應(yīng)用程序的開發(fā)者提供API使用各種鑒別模塊,向鑒別模塊的開發(fā)者提供SPI來掛載新的鑒別模塊;
3.最下層為服務(wù)模塊:服務(wù)模塊中都為動(dòng)態(tài)鏈接庫(kù),它給應(yīng)用程序提供具體的認(rèn)證用戶服務(wù),應(yīng)用程序可以使用幾個(gè)服務(wù)模塊。PAM所支持的四種任務(wù)管理:account 類型表示賬戶管理,它執(zhí)行賬戶管理,它主要用來限制/允許用戶對(duì)某個(gè)服務(wù)的訪問時(shí)間,當(dāng)前有效的系統(tǒng)資源(最多可以有多少個(gè)用戶),限制用戶的位置(例如:root用戶只能從控制臺(tái)登錄);auth類型表示認(rèn)證管理,對(duì)用戶進(jìn)行認(rèn)證。讓應(yīng)用程序提示用戶輸入密碼或者其它的標(biāo)記,確認(rèn)用戶的合法性;通過它的憑證許可權(quán)限,設(shè)定組成員關(guān)系或者其它優(yōu)先權(quán);password類型表示口令管理,用于更新與用戶相關(guān)的認(rèn)證特性,如更改用戶密碼;session類型表示會(huì)話管理,用于進(jìn)入給定的服務(wù)之前,或者離開給定的服務(wù)之后,需要進(jìn)行的會(huì)話操作,如:存儲(chǔ)關(guān)于與用戶交換數(shù)據(jù)的log信息、掛接目錄等。【3】
應(yīng)用PAM的服務(wù)例程是通過讀取PAM的配置文件初始化pam_handle這個(gè)句柄,用來記錄整個(gè)PAM的過程信息例如服務(wù)名、接口傳遞參數(shù)等,定義服務(wù)的配置文件存放在/etc/pam.d中,/etc/pam.conf也是pam的配置文件,該配置文件是老版本的配置文件,目前所安裝的版本當(dāng)中,如果有pam.d這個(gè)文件就首要讀取這個(gè)文件,若沒有再讀取pam.conf這個(gè)文件,另外若所讀服務(wù)不存在相應(yīng)配置文件,此時(shí)系統(tǒng)會(huì)讀取other這個(gè)配置文件的信息,other這個(gè)配置文件是所有服務(wù)的缺省選項(xiàng)。pam.d中的配置文件的語法形式如下:
module-type control-flag mudle-path arguments【3】
1.module-type:linux PAM 所提供的四種服務(wù)模塊,包括auth、account、session、password;
2.control-flag:控制標(biāo)志用來設(shè)置驗(yàn)證成功或者失敗后PAM需要做出的反應(yīng),有四個(gè)關(guān)鍵詞如下所示:
required:表示即使某個(gè)模塊對(duì)用戶的驗(yàn)證失敗,也要等所有的模塊執(zhí)行完成,PAM才可以返回錯(cuò)誤信息,如此用戶就不知道被哪個(gè)模塊拒絕了。
requisite:一旦模塊對(duì)用戶的驗(yàn)證失敗,PAM立馬返回出錯(cuò)信息。
sufficient:一旦模塊對(duì)用戶的驗(yàn)證成功,PAM立馬返回成功信息,并把控制權(quán)交給用戶。
optional:PAM會(huì)忽略這個(gè)模塊所產(chǎn)生的驗(yàn)證錯(cuò)誤,繼續(xù)執(zhí)行下一個(gè)模塊。
3.module-path:PAM驗(yàn)證模塊的路徑;
4.arguments:傳遞給模塊的參數(shù)。參數(shù)是可選擇的,可以是讀取另外配置文件的路徑信息,也可以是各種模塊所需的傳遞參數(shù)。以下列出pam_unix模塊的參數(shù)信息:
表1-2 pam_unix模塊參數(shù)【3】
參數(shù) |
說明 |
debug |
打開調(diào)試信息,通過syslog寫入日志系統(tǒng) |
audit |
比debug記錄更為詳細(xì)的調(diào)試信息 |
nullok |
默認(rèn)值下,如果用戶輸入的口令為空,則不允許用戶訪問服務(wù),該參數(shù)覆蓋率這個(gè)默認(rèn)值,即使不輸入口令就可以獲得服務(wù) |
nodelay |
取消延遲,默認(rèn)是2秒為延遲時(shí)間 |
try_first_pass |
提示用戶使用前面模塊認(rèn)證通過的口令,只適用于auth 類型 |
use_first_pass |
強(qiáng)制使用前面模塊認(rèn)證通過的口令,只適用于auth password類型 |
not_authok |
當(dāng)口令改變時(shí),強(qiáng)制模塊設(shè)置新口令到以前模塊提供的口令 |
md5 |
當(dāng)用戶下次改變他們的口令時(shí),使用md5算法加密口令 |
shadow |
維護(hù)shadow口令,即使用/etc/shadow存儲(chǔ)口令 |
unix |
當(dāng)用戶更改密碼時(shí),密碼被放置在/etc/passwd中 |
bigcrype |
當(dāng)用戶下次改變口令時(shí),使用DEC C2算法加密口令 |
nis |
使用NISRPC(遠(yuǎn)程過程調(diào)用)設(shè)置新口令 |
Remember=x |
將每個(gè)用戶最后x個(gè)口令存儲(chǔ)在/etc/security/opasswd文件中,用于強(qiáng)制口令更改歷史,以免用戶頻繁使用同一個(gè)口令 |
broken_shadow |
在account管理模塊中讀取shadow口令時(shí)忽略錯(cuò)誤 |
pam_conf配置文件的寫法與pam.d中的配置文件沒有太大的出入,只是在最前面多了一行具體的服務(wù)名稱,例如login,而pam.d中是將各種模塊分開來寫,這樣更便于控制。
PAM提供了多種接口函數(shù)以供用戶使用,其中包括框架API【4】、服務(wù)類型的API和服務(wù)模塊SPI。
框架API:
每個(gè)支持PAM機(jī)制的應(yīng)用程序在使用PAM機(jī)制之前必須調(diào)用函數(shù)pam_start()初始化PAM上下文和PAM事務(wù),使用完后調(diào)用pam_end()來結(jié)束PAM機(jī)制,通過pam_get_item、pam_set_item()來讀寫PAM事物的狀態(tài)信息,通過pam_get_data()、pam_set_data()來取得和設(shè)置PAM模塊及會(huì)話的相關(guān)信息,通過pam_putenv()、pam_getenv()、pam_getenvlist()來讀寫環(huán)境變量,通過pam_strerror()返回相關(guān)的錯(cuò)誤信息;
服務(wù)類型的API:
1.認(rèn)證管理模塊通過pam_authenticate()對(duì)用戶名和密碼進(jìn)行認(rèn)證,通過pam_setcred()用來修改用戶的信任參數(shù),建立數(shù)字認(rèn)證;
2.賬戶管理模塊通過pam_acct_mgmt()來檢查用戶本身是否具有權(quán)限登錄系統(tǒng)、賬戶是否過期、賬戶是否有登錄時(shí)間限制等;
3.密碼管理模塊通過pam_chauthtok()來修改用戶的密碼;
4.會(huì)話管理模塊通過pam_open_session()來開始會(huì)話,以pam_close_session()來結(jié)束會(huì)話;
PAM中的API與SPI詳細(xì)解釋如表1-3所示。
表1-3 PAM中API以及SPI【3】
服務(wù)管理類型 |
PAM API |
PAM SPI |
說明 |
account |
pam_acct_mgmt() |
pam_sm_acct_mgmt() |
檢查認(rèn)證特性、賬戶有效期和驗(yàn)證訪問控制 |
authentication |
pam_authenticate() |
pam_sm_authenticate() |
根據(jù)認(rèn)證特征認(rèn)證用戶 |
pam_setcred() |
pam_sm_setcred() |
在認(rèn)證后會(huì)話前調(diào)用,用來修改用戶的信任參數(shù),如:uid gid |
|
passwd |
pam_chauthtok() |
pam_sm_chauthtok() |
用于改變給定用戶的認(rèn)證特征 |
session |
pam_open_session() |
pam_sm_open_session() |
為認(rèn)證成功的用戶建立會(huì)話 |
pam_close_session() |
pam_sm_open_session() |
結(jié)束會(huì)話 |
【1】鳥哥的私房菜.人民郵電出版社.2010.
【2】Linux安全策略與實(shí)例.李洋等.機(jī)械工業(yè)出版社.2009.
【3】Linux安全體系分析與編程.倪繼利.電子工業(yè)出版社.2007.11
【4】The Linux-PAM Application Developers' Guide
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!