Linux可插拔認證模塊(PAM)的配置文件、工作原理與流程

 

在上一篇文章《Linux可插拔認證模塊的基本概念與架構》中,我們講到了PAM的一些基本概念和相關架構,接下來我們看看PAM的配置文件如何使用。

PAM的配置文件:

我們注意到,配置文件也放在了在應用接口層中,他與PAM API配合使用,從而達到了在應用中靈活插入所需鑑別模塊的目的。他的作用主要是爲應用選定具體的鑑別模塊,模塊間的組合以及規定模塊的行爲。下面是一個示例配置文件:

# cat /etc/pam.d/system-auth:
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      /lib/security/$ISA/pam_env.so
auth        sufficient    /lib/security/$ISA/pam_unix.so likeauth nullok
auth        required      /lib/security/$ISA/pam_deny.so

account     required      /lib/security/$ISA/pam_unix.so
account     sufficient    /lib/security/$ISA/pam_succeed_if.so uid < 100 quiet
account     required      /lib/security/$ISA/pam_permit.so

password    requisite     /lib/security/$ISA/pam_cracklib.so retry=3
password    sufficient    /lib/security/$ISA/pam_unix.so nullok use_authtok md5 shadow nis
password    required      /lib/security/$ISA/pam_deny.so

session     required      /lib/security/$ISA/pam_limits.so
session     required      /lib/security/$ISA/pam_unix.so

我們可以看到,配置文件有許多配置項(每行對應一個配置項)組成,每一行又分爲四列(每列對應一欄):

第一欄,認證鑑別接口類型:

auth:表示鑑別類接口模塊類型用於檢查用戶和密碼,並分配權限;

這種類型的模塊爲用戶驗證提供兩方面服務。讓應用程序提示用戶輸入密碼或者其他標記,確認用戶合法性;通過他的憑證許可權限,設定組成員關係或者其他優先權。

account:表示賬戶類接口,主要負責賬戶合法性檢查,確認帳號是否過期,是否有權限登錄系統等;

這種模塊執行的是基於非驗證的帳號管理。他主要用於限制/允許用戶對某個服務的訪問時間,當前有效的系統資源(最多可以多少用戶),限制用戶位置(例如:root只能通過控制檯登錄)。

多數情況下auth和account會一起用來對用戶登錄和使用服務的情況進行限制。這樣的限制會更加完整。比如下面是一個具體的例子:login是一個應用程序。Login要完成兩件工作——首先查詢用戶,然後爲用戶提供所需的服務,例如提供一個shell程序。通常Login要求用戶輸入名稱和密碼進行驗證。當用戶名輸入的時候,系統自然會去比對該用戶是否是一個合法用戶,是否在存在於本地或者遠程的用戶數據庫中。如果該賬號確實存在,那麼是否過期。這些個工作是由account接口來負責。

如果用戶滿足上述登錄的前提條件,那麼他是否具有可登錄系統的口令,口令是否過期等。這個工作就要由auth接口來負責了,他通常會將用戶口令信息加密並提供給本地(/etc/shadow)或者遠程的(ldap,kerberos等)口令驗證方式進行驗證。

如果用戶能夠登錄成功,證明auth和account的工作已經完成。但整個驗證過程並沒有完全結束。因爲還有一些其他的問題沒有得到確認。例如,用戶能夠在服務器上同時開啓多少個窗口登錄,用戶可以在登錄之後使用多少終端多長時間,用戶能夠訪問哪些資源和不能訪問哪些資源等等。也就是說登錄之後的後續驗證和環境定義等還需要其他的接口。這就是我們下面要提到的兩組接口:

session:會話類接口。實現從用戶登錄成功到退出的會話控制;

處理爲用戶提供服務之前/後需要做的些事情。包括:開啓/關閉交換數據的信息,監視目錄等,設置用戶會話環境等。也就是說這是在系統正式進行服務提供之前的最後一道關口。

password:口令類接口。控制用戶更改密碼的全過程。也就是有些資料所說的升級用戶驗證標記。

注意,上述接口在使用的時候,每行只能指定一種接口類型,如果程序需要多種接口的話,可在多行中分別予以規定。

第二欄,control_flag控制位:

規定如何處理PAM模塊鑑別認證的結果,簡而言之就是鑑別認證成功或者失敗之後會發生什麼事,如何進行控制。單個應用程序可以調用多種底層模塊,通常稱爲“堆疊”。對應於某程序按照配置文件中出現順序執行的所有模塊成爲“堆”,堆中的各模塊的地位與出錯時的處理方式由control_flag欄的取值決定,他的四種可能的取值分別爲required、Requisite、sufficient或_optional:

required:表示該行以及所涉及模塊的成功是用戶通過鑑別的必要條件。換句話說,只有當對應於應用程序的所有帶 required標記的模塊全部成功後,該程序才能通過鑑別。同時,如果任何帶required標記的模塊出現了錯誤,PAM並不立刻將錯誤消息返回給應用程序,而是在所有模塊都調用完畢後纔將錯誤消息返回調用他的程序。 反正說白了,就是必須將所有的模塊都執行一次,其中任何一個模塊驗證出錯,驗證都會繼續進行,並在執行完成之後才返回錯誤信息。這樣做的目的就是不讓用戶知道自己被哪個模塊拒絕,通過一種隱蔽的方式來保護系統服務。就像設置防火牆規則的時候將拒絕類的規則都設置爲drop一樣,以致於用戶在訪問網絡不成功的時候無法準確判斷到底是被拒絕還是目標網絡不可達。

requisite:與required相仿,只有帶此標記的模塊返回成功後,用戶才能通過鑑別。不同之處在於其一旦失敗就不再執行堆中後面的其他模塊,並且鑑別過程到此結束,同時也會立即返回錯誤信息。與上面的required相比,似乎要顯得更光明正大一些。

sufficient:表示該行以及所涉及模塊驗證成功是用戶通過鑑別的充分條件。也就是說只要標記爲sufficient的模塊一旦驗證成功,那麼PAM便立即嚮應用程序返回成功結果而不必嘗試任何其他模塊。即便後面的層疊模塊使用了requisite或者required控制標誌也是一樣。當標記爲sufficient的模塊失敗時,sufficient模塊會當做 optional對待。因此擁有sufficient 標誌位的配置項在執行驗證出錯的時候並不會導致整個驗證失敗,但執行驗證成功之時則大門敞開。所以該控制位的使用務必慎重。

optional:他表示即便該行所涉及的模塊驗證失敗用戶仍能通過認證。在PAM體系中,帶有該標記的模塊失敗後將繼續處理下一模塊。也就是說即使本行指定的模塊驗證失敗,也允許用戶享受應用程序提供的服務。使用該標誌,PAM框架會忽略這個模塊產生的驗證錯誤,繼續順序執行下一個層疊模塊。

include:表示在驗證過程中調用其他的PAM配置文件。在RHEL系統中有相當多的應用通過完整調用/etc/pam.d/system-auth來實現認證而不需要重新逐一去寫配置項。這也就意味着在很多時候只要用戶能夠登錄系統,針對絕大多數的應用程序也能同時通過認證。

另外還有一種比較複雜的格式爲value = action的語法來設置控制標誌,標誌之間會以空格分開。格式如下:

value1 = action1    value2 = action2    ……

其中value可以是下列Linux PAM庫的返回值:

success、open_err、symbol_err、service_err、 system_err、buf_err、perm_denied、auth_err、cred_insufficient、authinfo_unavail、user_unknown、maxtries、new_authtok_reqd、acct_expired、 session_err、cred_unavail、cred_expired、cred_err、no_module_data、conv_err、 authtok_err、authtok_recover_err、authtok_lock_busy、authtok_disable_aging、 try_again、ignore、abort、authtok_expired、module_unknown、bad_item和default。

最後一個(default)能夠用來設置上面的返回值無法表達的行爲。

actionN可以是一個非負整數或者是下面的記號之一:ignore、ok、done、bad、die和reset。如果是非負整數J,就表示需要忽略後面J個同樣類型的模塊。通過這種方式,系統管理者可以更加靈活地設置層疊模塊,模塊的層疊路徑由單個模塊的反應決定。

關於這幾個記號的詳細解釋:

ignore:如果使用層疊模塊,那麼這個模塊的返回值將被忽略,不會被應用程序知道。

bad:他表示這個返回碼應該被看作是模塊驗證失敗的標誌。如果這個模塊是層疊模塊的第一個驗證失敗的模塊,那麼他的狀態值就是整個層疊模塊驗證的狀態值和結果。

die:終止層疊模塊驗證過程,立刻返回到應用程序。

ok:告訴PAM這個模塊的返回值將直接作爲所有層疊模塊的返回值。也就是說,如果這個模塊前面的模塊返回狀態是PAM_SUCCESS,那這個返回值就會覆蓋前面的返回狀態。注意:如果前面的模塊的返回狀態表示模塊驗證失敗,那麼不能使用這個返回值再加以覆蓋。

done:終止後續層疊模塊的驗證,把控制權立刻交回應用程序。

reset:清除所有層疊模塊的返回狀態,從下一個層疊模塊重新開始驗證。

第三欄,module_path即所使用模塊的全路徑名稱。

以Red Hat Enterprise Linux(RHEL)爲例,值得注意的是在i368/i686和x86_64系統中模塊的全路徑名稱是不一樣的。所以當有的時候用戶將一些PAM的配置文件從原來系統複製到新的系統時,如果兩種系統架構不同,那麼不修改模塊路徑名稱則可能導致PAM報錯。

第四欄,options用於向特定模塊傳遞相關的選項,然後由模塊分析解釋這些選項。

比如使用此欄打開模塊調試模式,或向某模塊傳遞諸如超時值之類的參數等。另外他還用於支持下文所述的口令映射技術。

如果任一欄出現錯誤或某模塊沒有找到,那麼所在行被忽略並將其作爲嚴重錯誤進行記錄。

到此爲止,PAM的基本架構和PAM配置文件的基本格式已經做了比較詳細的介紹。下一篇文章我們將介紹PAM是如何工作的。

到此爲止,PAM的基本架構和PAM配置文件的基本格式已經做了比較詳細的介紹。下面我們需要看看PAM是如何工作的。

PAM的工作原理與流程:

以RHEL系統爲例,當pam安裝之後有兩大部分:在/lib/security目錄下的各種pam模塊以及/etc/pam.d和/etc/pam.d目錄下的針對各種服務和應用已經定義好的pam配置文件。當某一個有認證需求的應用程序需要驗證的時候,一般在應用程序中就會定義負責對其認證的PAM配置文件。以vsftpd爲例,在它的配置文件/etc/vsftpd/vsftpd.conf中就有這樣一行定義:

pam_service_name=vsftpd 

表示登錄FTP服務器的時候進行認證是根據/etc/pam.d/vsftpd文件定義的內容進行。

那麼,當程序需要認證的時候已經找到相關的pam配置文件,認證過程是如何進行的?下面我們將通過解讀/etc/pam.d/system-auth文件予以說明。

首先要聲明一點的是:system-auth是一個非常重要的pam配置文件,主要負責用戶登錄系統的認證工作。而且該文件不僅僅只是負責用戶登錄系統認證,其它的程序和服務通過include接口也可以調用到它,從而節省了很多重新自定義配置的工作。所以應該說該文件是系統安全的總開關和核心的pam配置文件。

下面是/etc/pam.d/system-auth文件的全部內容:

# grep -v ^# /etc/pam.d/system-auth
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so
 
account     required      pam_unix.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so
 
password    requisite     pam_cracklib.so try_first_pass retry=3
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so
 
session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

第一部分表示,當用戶登錄的時候,首先會通過auth類接口對用戶身份進行識別和密碼認證。所以在該過程中驗證會經過幾個帶auth的配置項。

其中的第一步是通過pam_env.so模塊來定義用戶登錄之後的環境變量, pam_env.so允許設置和更改用戶登錄時候的環境變量,默認情況下,若沒有特別指定配置文件,將依據/etc/security/pam_env.conf進行用戶登錄之後環境變量的設置。

然後通過pam_unix.so模塊來提示用戶輸入密碼,並將用戶密碼與/etc/shadow中記錄的密碼信息進行對比,如果密碼比對結果正確則允許用戶登錄,而且該配置項的使用的是“sufficient”控制位,即表示只要該配置項的驗證通過,用戶即可完全通過認證而不用再去走下面的認證項。不過在特殊情況下,用戶允許使用空密碼登錄系統,例如當將某個用戶在/etc/shadow中的密碼字段刪除之後,該用戶可以只輸入用戶名直接登錄系統。

下面的配置項中,通過pam_succeed_if.so對用戶的登錄條件做一些限制,表示允許uid大於500的用戶在通過密碼驗證的情況下登錄,在Linux系統中,一般系統用戶的uid都在500之內,所以該項即表示允許使用useradd命令以及默認選項建立的普通用戶直接由本地控制檯登錄系統。

最後通過pam_deny.so模塊對所有不滿足上述任意條件的登錄請求直接拒絕,pam_deny.so是一個特殊的模塊,該模塊返回值永遠爲否,類似於大多數安全機制的配置準則,在所有認證規則走完之後,對不匹配任何規則的請求直接拒絕。

第二部分的三個配置項主要表示通過account賬戶類接口來識別賬戶的合法性以及登錄權限。

第一行仍然使用pam_unix.so模塊來聲明用戶需要通過密碼認證。第二行承認了系統中uid小於500的系統用戶的合法性。之後對所有類型的用戶登錄請求都開放控制檯。

第三部分會通過password口另類接口來確認用戶使用的密碼或者口令的合法性。第一行配置項表示需要的情況下將調用pam_cracklib來驗證用戶密碼複雜度。如果用戶輸入密碼不滿足複雜度要求或者密碼錯,最多將在三次這種錯誤之後直接返回密碼錯誤的提示,否則期間任何一次正確的密碼驗證都允許登錄。需要指出的是,pam_cracklib.so是一個常用的控制密碼複雜度的pam模塊,關於其用法舉例我們會在之後詳細介紹。之後帶pam_unix.so和pam_deny.so的兩行配置項的意思與之前類似。都表示需要通過密碼認證並對不符合上述任何配置項要求的登錄請求直接予以拒絕。不過用戶如果執行的操作是單純的登錄,則這部分配置是不起作用的。

第四部分主要將通過session會話類接口爲用戶初始化會話連接。其中幾個比較重要的地方包括,使用pam_keyinit.so表示當用戶登錄的時候爲其建立相應的密鑰環,並在用戶登出的時候予以撤銷。不過該行配置的控制位使用的是optional,表示這並非必要條件。之後通過pam_limits.so限制用戶登錄時的會話連接資源,相關pam_limit.so配置文件是/etc/security/limits.conf,默認情況下對每個登錄用戶都沒有限制。關於該模塊的配置方法在後面也會詳細介紹。

可見,不同應用程序通過配置文件在認證過程中調用不同的pam模塊來定製具體的認證流程。其中我們不難看出,其實可以根據實際的需要對pam的配置文件進行修改以滿足不同的認證需求,例如下面的例子:

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth    required    pam_env.so
auth    required    pam_tally.so onerr=fail deny=5
auth    sufficient  pam_unix.so nullok try_first_pass
auth    requisite   pam_succeed_if.so uid >= 500 quiet
auth    required    pam_deny.so

account required    pam_unix.so
account sufficient  pam_succeed_if.so uid < 500 quiet
account required    pam_permit.so

password    requisite pam_cracklib.so try_first_pass retry=3 minlen=10 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 difok=6
password    requisite pam_passwdqc.so use_first_pass enforce=everyone
password    sufficient pam_unix.so md5 remember=6 shadow nullok try_first_pass use_authtok
password    required pam_deny.so

session     optional pam_keyinit.so revoke
session     required pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required pam_unix.so

在其中就增加了對用戶密碼修改時複雜度的限制,用戶多次錯誤輸入密碼之後的鎖定限制以及用戶使用密碼歷史等限制選項。

所以我們通過對上述system-auth配置文件的修改,模塊的增加和選項的變化,從很大的程度上增加了用戶登錄驗證的安全性要求。我們會在之後的文章中對該配置進行詳細說明。

另外也一定需要注意,在整個的PAM配置文件當中,配置項以及模塊調用的邏輯順序非常關鍵。因爲PAM是按照配置項的先後順序來進行驗證。錯誤的模塊調用順序很可能導致嚴重的安全問題甚至系統錯誤。所以對PAM配置進行修改的時候務必要考慮這一點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章