Linux-PAM系統管理指南

lawzjf發表於2007-09-23

對應的英文文件:

另外一篇:http://www.enterprisenetworkingplanet.com/netsecur/article.php/10952_3514511_1

1.簡介

  Linux-PAM(Pluggable Authentication Modules for Linux.基於Linux的插入式驗證模組)是一組共享庫,使用這些模組,系統管理者可以自由選擇應用程式使用的驗證機制。也就是說,勿需重新編譯應用程式就可以切換應用程式使用的驗證機制。甚至,不必觸動應用程式就可以完全升級系統使用的驗證機制。



  在歷史上,需要對使用者進行驗證的應用程式,必須同某種驗證機制編譯到一起。例如,傳統的UN*X系統是使用密碼對使用者進行校驗的。使用者輸入的密碼經過crypt加密後,然後和/etc/passwd檔案中的密文進行比較。在這種系統中,如果優先權的識別不是基於這種方式,就需要透過使用者識別符和使用者組識別符對優先權進行驗證。服務和應用程式可以使用基於使用者和使用者組識別的驗證方式。通常,使用者組的分配是透過/etc/group檔案。

  不幸的是,隨著計算機速度的加快和網路的大範圍普及,使用這種驗證方式越來越不安全了。因此,人們開發了許多新的驗證方法。

  Linux-PAM工程的目的就是分離應用軟體和驗證機制的開發。透過驗證函式庫可以實現上述目的。PAM庫由本地的系統配置檔案 /etc/pam.conf或者/etc/pam.d/目錄下的一些配置檔案來設定。而模組以動態可載入目標檔案(使用dloptn(3)函式開啟)的形式儲存在/usr/lib/security目錄中。

2.關於本文的一些說明

  在開始閱讀本文時,你應該清楚本文假定特定的檔案是在特定的目錄中。我們遵照RFC-86的約定。有些Linux釋出把這些檔案放在不同的位置,因此如果你的系統是象RedHat之類的釋出,那麼你應該謹慎使用本文提供的例子。

  例如,本文假設PAM可載入目標檔案(模組)是在/usr/lib/security/目錄下,而在RedHat Linux系統中它們被放在了/lib/security目錄下。因此,使用本文的例子時應該注意進行必要的轉換。

3.綜述

  我們從一個例子開始討論。首先找一個能夠為使用者提供服務的應用程式,login就是一個這樣的程式。login要做兩件事,首先查詢使用者,然後為使用者提供所需服務,例如提供一個shell程式。

  通常,login會提示使用者輸入密碼。然後對密碼進行校驗,這項任務就是Linux-PAM完成的。

  從程式設計師的角度看,Linux-PAM的任務就是校驗使用者的合法性。

  Linux-PAM具有很大的靈活性,系統管理者可以透過它自由選擇使用的驗證方式。你也可以自由選擇應用程式使用的驗證方式。Linux-PAM能夠提供的驗證方式多種多樣,從絕對信任(pam_permit)到視網膜掃描、音訊分析以及一次性口令,不一而足。

  為了描述Linux-PAM的靈活性,我們可以假想一種情況:一個系統管理者(父母)希望提高使用者(他們的子女)的數學能力。他/她就可以透過一個孩子們非常喜歡的遊戲“Shoot 'em up game”達成上述目的,當然前提是這個遊戲能夠使用PAM提供的驗證機制。驗證可以設定:每次孩子們要玩遊戲時,都需要回答出一組小於12的隨機數的乘積。這樣孩子們每次玩遊戲之前都可以練習乘法運算。隨著他們的成長,可以增加數字的大小。

  Linux-PAM處理四種型別的任務:驗證管理(auth)、帳戶管理(account)、會話管理(session)和口令管理(password)。應用程式使用的管理方式透過相關的Linux-PAM配置檔案設定。管理功能是有配置檔案指定的模組完成的。

  應用程式X,它透過一些介面呼叫Linux-PAM庫,而自己並不知道使用的驗證方法。Linux-PAM庫讀出PAM配置檔案的內容,根據配置檔案載入程式X需要的模組。這些模組進入某個管理組並且按照配置檔案設定的順序層疊在一起。它們為應用程式執行各種驗證任務。應用程式和使用者之間透過 conversation函式實現資訊交換。

3.1 入門

  下面是Seth Chaiklin說的一段話:

從這一點來看,PAM應該工作在理想世界中,在這裡所有的應用程式都沒有錯誤。然而,事實遠非如此。因此,如果你要使用PAM,需要考慮一些實際的問題。
如果你把Linux用作一個單使用者系統,或者系統中的使用者是相互信任的,那使用PAM沒有多大意思。
  你可以在沒有重要東西的系統上取消PAM,這實際上可以帶來一些方便。使系統象Win95。

  在網路環境下,就需要考慮使用者驗證的問題了。

  如果你使用Linux作為一個伺服器,用它來提供一些不同的服務,這時PAM就體現了它的價值。一般情況下,透過使用不同的模組,程式可以搜尋各種密碼資料庫,而程式本身勿需改寫。下面是一些例子:

apache有一個模組能夠提供PAM服務。因此,對於特定目錄的驗證可以透過PAM完成,這意味著大量現有的PAM模組可以用來進行驗證工作,包括RADIUS、NIS、NCP。
pppd有一個使用PAM驗證的版本(來自RedHat)。
  我可以把PAM由於任何需要驗證的程式嗎?

  可以說能也可以說不能。能,是指如果你能夠修改原始碼,就可以加入PAM驗證功能;不能是指如果你無法修改原始碼,那麼在二進位制可執行檔案匯中是無法加入PAM驗證功能的。

  我怎樣才能區分程式是否使用了PAM驗證?

使用ldd命令,如果這個程式的使用的動態連線庫沒有libpam和libpam_misc,那它肯定不使用PAM驗證。然而,還有可能已經包含這兩個庫了,但是因為某些問題,程式無法正常工作。因此需要更好的方法來測試。
對於需要使用PAM的程式,需要在/etc/pam.d目錄中為其設定配置檔案。配置檔案的名字被編寫程式序原始碼中,通常和程式的名字是一樣的,但不總是這樣。例如:有個程式叫作pamprog,它的PAM配置檔案是/etc/pam.d/pamprog。在配置檔案中,只有下面兩行: auth required pam_permit.so
auth required pam_warn.so

  現在對其進行測試。第一行,表示所有的使用者都允許透過;第二行表示想syslog中寫入一條警告資訊。如果測試成功,就表示程式能夠使用PAM進行驗證。然後你可以在配置檔案中加入更為複雜的驗證功能。

4.Linux-PAM配置檔案

  Linux-PAM的目標就是為系統管理者提供最大限度的靈活性。系統管理者可以透過兩種形式對Linux-PAM進行配置:單一配置檔案/etc/pam.conf;或者是/etc/pam.d/目錄。這一節我們將討論其配置檔案的語法。

4.1 配置檔案的語法

  讀者首先應該明白Linux-PAM的記號是大小寫敏感的。有兩個特殊的符號:#和。配置檔案中的註釋以#開頭,一般配置檔案中每行是一個入口(除了註釋),但是如果某個入口的定義很長,可以透過使用轉義符回行,而下一行也被看作是這個入口的一部分。

  一般/etc/pam.conf檔案每行都是這種格式:

  service-name module-type control-flag module-path arguments

  下面我們將對每個記號進行解釋。除了這種方式之外,還可以使用/etc/pam.d/目錄對Linux-PAM進行配置,稍後我們將對這種方式進行講述。

service-name
為這個入口分配的服務名。通常這是給定應用程式的會話名。例如:ftpd、rlogind、su等等。

Linux-PAM還為預設的驗證機制保留一個特殊的服務名,就是OTHER,大小寫均可。注意,如果某個模組指定了以命名的服務,那OTHER就被忽略。

modle-type
Linux-PAM當前有四種型別的模組:

auth
這種型別的模組為使用者驗證提供兩方面的服務。

讓應用程式提示使用者輸入密碼或者其它的標記,確認使用者的合法性;
透過它的憑證許可許可權,設定組成員關係(不同於上面討論的/etc/groups檔案)或者其它優先權。
account
這類模組執行基於非驗證的帳戶管理。它主要用來限制/允許使用者對某個服務的訪問時間,當前有效的系統資源(最多可以有多少個使用者),限制使用者的位置(例如:root使用者只能從控制檯登入)。

session
這類模組的主要用途是處理為使用者提供服務之前/後需要做的一些事情,包括:記錄開啟/關閉交換資料的資訊,監視目錄等。

password
用來升級使用者驗證標記。

control-flag
控制標誌用來設定驗證成功或者失敗後PAM需要作出的反應。因為模組可以層疊(stacked,同樣型別的模組依次執行),控制標誌可以決定每個模組的重要性。應用程式不會意識到單個模組成功或者失敗,它只會收到Linux-PAM庫成功或者失敗的綜合反應資訊。層疊模組的執行順序取決於/etc/pam.conf檔案的入口順序,入口列前的模組先執行。從Linux-PAM 6.0開始可以使用兩種語法定義控制標誌。

簡單的一種是使用單一關鍵詞定義控制標誌。有四個這樣的關鍵詞:required、requisite、sufficient和optional。

Linux-PAM透過如下方式解釋這些關鍵詞:

required
表示即使某個模組對使用者的驗證失敗,也要等所有的模組都執行完畢之後,PAM才返回錯誤資訊。這樣做是為了不讓使用者知道被哪個模組拒絕。如果對使用者驗證成功,所有的模組都會返回成功資訊。

requisite
如果特定的模組對使用者的驗證失敗,PAM馬上返回一個錯誤資訊,把控制權交回應用程式,不再執行其它模組進行驗證。

sufficient
表示如果一個使用者透過這個模組的驗證,PAM結構就立刻返回驗證成功資訊,把控制權交會應用程式。後面的層疊模組即使使用requisite或者required控制標誌,也不再執行。如果驗證失敗sufficient的作用和optional相同。

optional
表示即使本行指定的模組驗證失敗,也允許使用者享受應用程式提供的服務。使用這個標誌,PAM框架會忽略這這個模組產生的驗證錯誤,繼續順序執行下一個層疊模組。

還有一種比較複雜的語法來設定控制標誌,它由一組value=action形式的標記組成,標記之間以空格分開:

[value1=action1 value2=action2 ...]

valueN可以是下列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
PAM驗證模組的路徑。如果以/開頭,就表示是完整的路徑;如果不是以/打頭,就表示是相對於/usr/lib/security的相對路徑。

args
傳遞給模組的引數。類似於通常的Linux Shell命令列引數。有效的引數包括一些通用引數和特定於給定模組的引數。無效的引數將被忽略,並會把錯誤資訊記錄到syslog。

  注意:配置檔案中的任何一行錯誤都會導致驗證失敗,同時相關錯誤資訊被記錄到syslog。

4.2 基於目錄的配置形式

  從Linux-PAM 5.6版開始引入了一種基於目錄的配置方式,透過/etc/pam.d/目錄下的檔案對PAM進行配置。這種方式比單一的配置檔案具有更大的靈活性。這個目錄下的所有配置檔案都以某個服務名命名(小寫)。

  不過,這兩種配置方式不能同時起作用,也就是說,你只能使用其中一種對Linux-PAM進行配置。一般/etc/pam.d/優先。

  /etc/pam.d/目錄下的配置檔案的語法和/etc/pam.conf檔案的語法相似,形式如下:

  module-type control-flag module-path arguments

  和/etc/pam.conf檔案語法的唯一不同就是沒有服務名(service-name),服務名由檔名設定。例如:/etc/pam.d/login檔案儲存對login服務的設定。

  這種配置方式與單一配置檔案相比,具有很大的優越性:

減少了配置錯誤的機率。
更易於維護。
可以透過使用不同配置檔案的符號連線決定系統的驗證策略。
可以加快對於配置檔案的解析。
可以對單個的Linux-PAM配置檔案設定不同的存取許可權。
更易於軟體包的管理。
4.3 通用引數

  下面是一些通用引數,可以被所有的模組解析:

debug
透過syslog系統呼叫記錄除錯資訊。

nowarn
使模組不要嚮應用程式輸出警告資訊。

use_first_pass
使模組不提示使用者輸入密碼,而是使用為前一個驗證模組輸入的密碼。如果無效,則驗證失敗。這個引數只能用於auth和password型別模組。

try_first_pass
首先使用使用者為上一個模組輸入的密碼進行驗證,如果不行,就提示使用者輸入密碼,這個引數只能用於auth型別的模組。

use_mapped_pass
這個引數目前還不能被任何Linux-PAM模組支援,主要因為美國加密演算法的出口限制。

expost_account
通常,對於模組來說洩露使用者的某些資訊並非一個安全的策略。有時候使用者名稱、起始目錄或者使用者使用的shell等資訊都可以被攻擊者用來攻擊一個使用者帳戶。這個引數是一個適用於每個模組的標準引數,它可以使模組儘量少地洩露使用者資訊。

4.4 配置檔案入口示例

  在這一節,我們將給出一些例子,以便於理解。

4.4.1 預設策略

  一個合理的OTHER入口對於加強系統安全非常重要。下面是一個非常偏執的例子。

  # 預設; 拒絕訪問
  #
  OTHER auth required /usr/lib/security/pam_deny.so
  OTHER account required /usr/lib/security/pam_deny.so
  OTHER password required /usr/lib/security/pam_deny.so
  OTHER session required /usr/lib/security/pam_deny.so

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/37724/viewspace-152634/,如需轉載,請註明出處,否則將追究法律責任。

相關文章