PAM詳解

PAM詳解

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)函數打開)的形式保存在 /lib/security/lib64/security

2 關於本文的一些說明

  在開始閱讀本文時,你應該清楚本文假定特定的文件是在特定的目錄中。我們遵照RFC-86的約定。如果你使用的linux發行版或其他支持PAM的系統以不同的方式發佈這些文件的話,那麼你應該謹慎使用本文提供的例子。

  例如,本文假設PAM可加載目標文件(模塊)是在/lib/security//lib64/security/目錄下,這是符合 HFSFilesystem Hierarchy Standard)標準的。在 Solaris中,他們有屬於 Solaris自己的PAM版本,在其他的UNX中,你可能會在/usr/lib/security中看到這些文件。因此,使用本文的例子時應該注意進行必要的轉換。

3 綜述

   我們從一個例子開始討論。首先找一個能夠爲用戶提供服務的應用程序,login就是一個這樣的程序。login要做兩件事,首先確認發出請求的這個用戶是不是該用戶本身,然後爲用戶提供所需服務:在這裏提供的是以一個以用戶身份的運行的shellbash, tcsh, zsh, etc.

   通常,login所做的前面的步驟只是提示用戶輸入密碼並與驗證是否與系統本地中存儲的密碼一致,然後對用戶身份的驗證,就是Linux-PAM的工作了。

   從一個程序開發人員的角度看(在這個例子中,就是login程序的開發人員),LinuxPAM的工作就是校驗--驗證用戶的身份。

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

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

  Linux-PAM處理四種類型的任務:驗證管理(auth)、帳戶管理(account)、會話管理(session)和口令管理 (password)。應用程序使用的管理方式通過相關的Linux-PAM配置文件設置。管理功能是有配置文件指定的模塊完成的。配置文件的語法將會在下面討論。

  下圖描述了Linux-PAM組織架構:
+----------------+
| application: X |
+----------------+       / +----------+       +================+
| authentication-[---->--\--] Linux-    |--<--| PAM config file|
|       +        [----<--/--]    PAM    |     |================|
|[conversation()][--+    \ |            |     | X auth .. a.so |
+----------------+ |     / +-n--n-----+       | X auth .. b.so |
|                | |         __| |            |            _____/
| service user | A         |      |           |____,-----'
|                | |       V      A
+----------------+ +------|-----|---------+ -----+------+
                      +---u-----u----+     |      |       |
                      |   auth....   |--[ a ]--[ b ]--[ c ]
                      +--------------+
                      |   acct....   |--[ b ]--[ d ]
                      +--------------+
                      |   password   |--[ b ]--[ c ]
                      +--------------+
                      |   session    |--[ e ]--[ c ]
                      +--------------+


  上圖中,左邊的應用程序X,它通過一些接口調用Linux-PAM庫,而自己並不知道使用的驗證方法。中間的Linux-PAM庫參照圖右邊配置文件中的內容,加載應用程序X所適用的模塊。這些模塊進入某個管理組,並按照配置文件裏的配置層疊在一起。在這些模塊被Linux-PAM調用時,會對應用程序執行不同的驗證工作。應用程序和用戶之間的信息交換可以通過 conversation函數實現。

    如果一個程序想使用PAM,在程序中必須有支持PAM功能的代碼。如果你有程序的源代碼,你可以將合適的PAM功能代碼添加進去,如果只有二進制文件,而二進制文件又不支持PAM,那就無能爲力了。

4 Linux-PAM配置文件

   當一個使用了PAM的應用程序啓動時,它會啓動於PAMAPI的連接,然後去讀取配置文件/etc/pam.conf,另外,配置文件也可能存在於/etc/pam.d中。如果存在/etc/pam.d,那麼/etc/pam.conf將會被忽略。

   這些配置文件列出了某個或某些系統服務所要求PAM驗證規則,以及PAM規則失敗事件發生時PAM-API的行爲。

4.1 配置文件語法

    下面將介紹配置文件的語法。配置文件是一個規則列表,每條規則都獨佔一行,但也可能由於某個規則長度過長導致溢出,可以使用使用轉意服符 `\<LF>'轉寫到下一行。 在同一行中,寫在“#”後面的都是註釋。

    每一條規則的內容都是用空格分開的,前三個參數不區分大小寫,如下:
   service type control module-path module-arguments
   (服務)  (類型)(控制)  (模塊路徑)      (模塊參數)

    在/etc/pam.d目錄下的配置文件,其規則內容都是不包含service部分的,即不包含服務名稱,而/etc/pam.d目錄下文件的名字就是服務名稱。文件名必須是小寫的。

   PAM的一個重要特點是,許多個PAM規則疊加在一塊共同起作用的來完成一個指定的驗證工作。

   service(服務) 通常都是類似於loginsu這樣的常見應用程序。爲定義默認的規則,預留了service-name
   The service is typically the familiar name of the corresponding application: login and su are good examples.
   The service-name, other, is reserved for giving default rules. On

ly lines that mention the current service
   (or in the absence of such, the other entries) will be associated with the given service-application.

   type(類型)是一個管理相近規則的管理組,他的作用就是指定後面的模塊與哪一個管理組相關聯。包括下面四總類型:

       acount   用於非驗證的帳戶管理,它主要用來限制/允許用戶對某個服務的訪問時間,當前可用的系統資源(用戶的最大數量),或者限制用戶的位置(例如:root用戶只能從控制檯登錄)

       auth     爲用戶提供了兩個方面的驗證,第一, 讓應用程序提示用戶輸入密碼或者其它的標記,確認用戶的合法性;第二,通過它的憑證許可權限,設定組成員關係(不同於上面討論的/etc/groups文件)或者其它優先權。

       passwd   用來升級用戶驗證標記

       session  這類模塊的主要用途是處理爲用戶提供服務之前/後需要做的一些事情,包括:記錄打開/關閉交換數據的信息,掛載目錄等。

    如果在類型之前加了"-",則當模塊丟失導致不能正常加載時,相關的日誌將不會記錄到系統日誌中,對於那些不一定每次都需要安裝的模塊來說,這一特性是有用的。

   control(控制標誌) 控制標誌用來設置驗證成功或者失敗後PAM-API需要作出的反應,控制標誌有兩種語法,一種是簡單的,只需要一個單獨的關鍵字即可,另一種複雜的方式是在方括號裏面寫“value=action

    簡單語法如下:

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

       requisite  如果特定的模塊對用戶的驗證失敗,PAM馬上返回一個錯誤信息,把控制權交回應用程序,不再執行其它模塊進行驗證。返回值與第一個fail的模塊有關。

       sufficient 表示如果一個用戶通過這個模塊的驗證,PAM結構就立刻返回驗證成功信息(即使前面有模塊fail了,也會把fail結果忽略掉),把控制權交回應用程序。後面的層疊模塊即使使用requisite或者required控制標誌,也不再執行。如果驗證失敗,sufficient的作用和optional 相同。

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

       include    include all lines of given type from the configuration file specified as an argument to
                      this control.

       substack   include all lines of given type from the configuration file specified as an argument to
                  this control. This differs from include in that evaluation of the done and die actions in
                  a substack does not cause skipping the rest of the complete module stack, but only of
                  the substack. Jumps in a substack also can not make evaluation jump out of it, and the
                  whole substack is counted as one module when the jump is done in a parent stack. The
                  reset action will reset the state of a module stack to the state it was in as of beginning
                  of the substack evaluation.

   還有一種比較複雜的語法來設置控制標誌,它由一組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, conv_again, incomplete, and default.最後一個(default)能夠用來設置上面的返回值無法表達的行爲。

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

      ignore  如果使用層疊模塊,這個模塊的返回狀態將不會對應用程序獲取的返回值產生影響。

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

       die     對層疊模塊最終結果的影響相當於bad,並且立刻反回到應用程序。

       ok      告訴PAM這個模塊的返回值直接作爲整個層疊模塊的返回值。也就是說,如果這個模塊前面的模塊返回狀態是PAM_SUCCESS,那這個返回值就會覆蓋前面的返回狀態。注意:如果前面的模塊的返回狀態表示模塊驗證失敗,那麼這個“ok”標記的返回值將不會覆蓋前面的返回值。

       done    對層疊模塊最終結果的影響相當於ok,並且立刻反回到應用程序。

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

   對於簡單語法的四種控制標誌: required; requisite; sufficient; and optional,都有相同效果的複雜語法與其對應。

  required   [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
  requisite  [success=ok new_authtok_reqd=ok ignore=ignore default=die]
  sufficient [success=done new_authtok_reqd=done default=ignore]
  optional   [success=ok new_authtok_reqd=ok default=ignore]

  module-path(模塊路徑) 如果以"/"開頭,則表示模塊的全路徑,否則就表示相對於 /lib/security//lib64/security/的相對路徑。

  module-arguments(模塊參數) 一組用空格分開的變量,用來改變當前PAM模塊的行爲。對於當前模塊無效的參數將會被忽略,並把錯誤信息記錄到syslog中。注意,如果想在一個參數中使用空格,就要在其外面加上中括號,例子如下:

  squid auth required pam_mysql.so user=passwd_query passwd=mada \
  db=eminence [query=select user_name from internet_service \
  where user_name='%u' and password=PASSWORD('%p') and \
  service='web_proxy']

   按照規則,你可以在字符串中使用字符“[”,但是如果要使用字符"]",就必須加上轉移字符"\]"

   配置文件中,任何一行的語法錯誤都會引發認證過程失敗,失敗信息會記錄到syslog中。

4.2 基於目錄的配置

   比單一配置文件更靈活的配置方法是使用/etc/pam.d目錄。這個目錄中存放的都是以service-name(服務名稱)命名的文件:每個服務都有私有配置文件。

  /etc/pam.d目錄下的配置文件語法與/etc/pam.conf基本相同,由一下幾部分組成:

  type control module-path module-arguments

   唯一不同的是沒有了service-nameservice-name直接作爲了文件的名字。例如 /etc/pam.d/login就是login服務的配置文件。

4.3 配置文件內容舉例

   本節我們將會舉一些Linux-PAM配置文件的例子。作爲第一次配置你的系統,你可以按照下面的例子來配置。

   一個合理的OTHER入口對於加強系統安全非常重要。下面是一個非常偏執的例子(但是以它作爲開始並不壞)

  #
  # default; deny access
  #
  other   auth     required  pam_deny.so
  other   account  required  pam_deny.so
  other   password required  pam_deny.so
  other   session  required  pam_deny.so

   雖然這是一個最安全的策略(默認拒絕訪問),但是對於一個PAM沒有配置好的系統來說,這中配置並不合理。例如:如果這個文件的其它部分編寫不好,那麼很容易把所有的用戶擋在門外。

  pam_deny.so模塊並不是非常完善,pam_deny模塊在運行時不記錄任何信息,除非用戶在無法執行某個服務程序時能夠與系統管理人員聯繫,否則系統管理者很長時間不會知道系統配置錯誤。

   在上面例子中,以模塊層疊的方式加入以下幾行,系統管理者就可以獲得有關的警告信息了:

  #
  # default; wake up! This application is not configured
  #
  other auth     required pam_warn.so
  other password required pam_warn.so

   在使用/etc/pam.d目錄的系統中,以other命名的配置文件內容應該是這樣的:

  #
  # default configuration: /etc/pam.d/other
  #
  auth     required       pam_warn.so
  auth     required       pam_deny.so
  account  required       pam_deny.so
  password required       pam_warn.so
  password required       pam_deny.so
  session  required       pam_deny.so

   對於不熟悉Linux-PAM的系統管理者,下列幾行可以作爲最基本的系統配置:

  #
  # default; standard UN*X access
  #
  auth     required       pam_unix.so
  account required        pam_unix.so
  password required       pam_unix.so
  session required        pam_unix.so

5 安全問題

5.1 如果出現錯誤

   如果發生錯誤,Linux-PAM可能會改變系統的安全性。這取決於你自己的選擇,你可以選擇不安全(開放系統)和絕對安全(拒絕任何訪問)。通常,Linux-PAM在發生錯誤時,傾向於後者。任何的配置錯誤都可能導致系統整個或者部分無法訪問。

   配置Linux-PAM時,可能遇到最大的問題可能就是Linux-PAM的配置文件(/etc/pam.d/*或者/etc/pam.conf)被刪除了。如果發生這種事情,你的系統就會被鎖住。

   有辦法可以進行恢復,最好的方法就是用一個備份的鏡像來恢復系統,或者登錄進單用戶模式然後進行正確的配置。

5.2 不要使用脆弱的other文件  

  other文件的脆弱並不是一件好事,因爲支持PAM的應用程序如果沒有特定的配置文件在/etc/pam.d下的話,則將會用other的配置,這樣的話系統很可能受到***的威脅。

   這是一個示例配置,pam_deny模塊將拒絕所有的訪問,而pam_warn模塊將向auth.notice日誌設備發送一條警告信息:
  #
  # The PAM configuration file for the `other' service
  #
  auth      required   pam_deny.so
  auth      required   pam_warn.so
  account   required   pam_deny.so
  account   required   pam_warn.so
  password  required   pam_deny.so
  password  required   pam_warn.so
  session   required   pam_deny.so
  session   required   pam_warn.so

參考:
The Linux-PAM System Administrators' Guide1.1.0
Linux-PAM系統管理指南 http://doc.linuxpk.com/5214.html


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