2012年7月10日 星期二

使用PAM模組管理使者帳戶安全性 (Managing the account security with PAM)

使用者帳戶的安全性管理工作通常是系統安全性的基礎,如果無法確保帳戶與密碼的安全性,一旦存在並曝露帳戶與密碼使用上的任何弱點,恐將為有心人利用此帳戶管理不當的漏洞進行攻擊入侵而導致資安意外,所以帳戶與密碼的安全性管理實為系統管理員確保系統安全性的首要工作

Linux 系統上的PAM模組提供了豐富的驗證和檢查機制,為管理人員維護帳戶安全性提供了最佳選擇,本文將說明如何透過PAM模組來管理帳戶與密碼的各項安全性問題。

制定帳戶與密碼原則 (Define Account and Password Policy)

一般的Linux系統均採用傳統的型一驗證因子(Type 1 Factor)--密碼驗證方法,因此為了確保帳戶安全性,管理員必需先擬定系統的帳戶使用原則,尤其是強制密碼原則應列為最主要的工作,因為強制密碼原則可避免員工使用容易猜測或容易破解的密碼,而依據經驗,完整的密碼原則需要包含下列密碼使用或變更上的限制條件:

  1. 限制密碼最短使用期限和最長使用期限
  2. 限制密碼使用的最短長度
  3. 不能使用先前用過的數次密碼 (記憶密碼歷程)
  4. 密碼複雜度(強度)檢查

另一方面,基於某些場合或環境上特定的安全性考量,其它可能需要實施的帳戶安全性管理項目包括了:

  1. 限制使用者登入機器
  2. 限制使用者登入時段
  3. 限制使用者登入次數

Linux帳戶原則實做基本指引

至於如何達成上述所制定的帳戶安全性目標,底下列出了實做Linux帳戶原則的指引:

  1. 編輯shadow組態檔-/etc/login.defs,定義密碼使用期限。
  2. 編輯/etc/pam.d/system-auth檔,定義密碼強度檢查機制。
  3. 如有更嚴謹的需要,編輯/etc/pam.d/system-auth檔案,並以密碼品質控制模組pam_passwdqc取代pam_cracklib。
  4. 編輯/etc/security/limits.conf、/etc/security/access.conf、/etc/security/time.conf以限制登入次數、登入位置和登入時段並在適當的PAM服務組態檔(如/etc/pam.d/login)引入pam模組。

底下詳細說明每一個步驟。

壹. shadow 密碼設定檔—/etc/login.defs

原來Linux 的shadow-utils套件內附 /etc/login.defs檔案可用來控制帳戶建立時的密碼限制,login.defs檔案內的四個密碼相關欄位如下:

PASS_MAX_DAYS 99999   # 設定shadow檔案內的第5欄位,密碼最長的使用的天數
PASS_MIN_DAYS 0   # 設定shadow檔案內的第4欄位,密碼最短的使用的天數
PASS_MIN_LEN 5   # 設定密碼最短的字元長度
PASS_WARN_AGE 7   # 設定shadow檔案內的第6欄位,密碼到期前的警告天數

不過利用/etc/login.defs這個檔案來設定密碼原則有幾個值得留意的問題:

  • PASS_MAX_DAYS, PASS_MIN_DAYS 和PASS_WARN_AGE只會應用在帳戶被建立時,修改這些值,對於那些已經存在的帳戶並不會有所影響(需使用chage指令), 所以最好在機器尚未建立任何帳戶前就已經設定。
  • PASS_MIN_LEN 在主流的RedHAT、Debain Linux,預設上均已被PAM模組取代。
  • login.defs無法檢查密碼複雜度

由於以上的限制,所以login.defs並無法實現一個完整的密碼原則,倘若要完整的實做Linux系統的密碼原則,仍需利用並設定適當的PAM模組組態才行。

貳. 利用PAM模組設定密碼原則

若要利用PAM來定義系統的密碼原則,您需要編輯 /etc/pam.d/system-auth檔案,底下為CentOS 6的system-auth內容:

#%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 sufficient pam_fprintd.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_localuser.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 type=
password sufficient pam_unix.so sha512 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_cracklib.so 模組
  • pam_unix.so 模組

不過值得留意的一點為 system-auth這個檔案是由authconfig工具自動產生,每執行一次就會自動產生此檔,所以一旦您手動更動過此檔案之後,切勿再執行authconfig命令,否則所做的變動將會被重新覆蓋而失效。

使用 pam_cracklib.so 模組

有些Linux版本,並不見的會預先安裝了 spam_cracklib.so 模組的套件(libpam-cracklib),而且其設定檔載入的位置也可能隨著Linux版本的不同而有所不同,例如 Debian, Ubuntu, OpenSUSE 的位置在於 /etc/pam.d/common-password檔案. 而RedHat, CentOS, Fedora, Mandriva 的檔案位置為 /etc/pam.d/system-auth。

pam_cracklib.so模組可做為PAM模組的密碼檢查器,用以避免駭客的字典查詢攻擊法(dictionary attack)和暴力破解法(brute force attack),其主要功能乃在於用來強制密碼的複雜度,包括密碼是否在易猜測的字典檔內,密碼輸入允許失敗次數,密碼長度與字元類型的組合,不過pam_cracklib的用法有些複雜且不少不易了解之處,底下一一說明。

預設的pam-cracklib模組本身就提供了密碼的強度檢查,它會拒絕下列情況的密碼:

  1. 回文(palindrome):密碼正寫和倒寫均相同
  2. 僅是變更舊密碼的大小寫 (Case change Only)
  3. 相似密碼(similar):舊密碼和新密碼太過相近
  4. 密碼輪流(rotate):將舊密碼字元輸替使用(如 password" 變為"asswordp)
  5. 已用過(Already used ):採用先前已用過的密碼

pam_cracklib整個密碼檢查流程順序為:

字典查詢==>是否回文(palindrome)==>是否只是變更舊密碼換大小寫==>檢查是否與舊密碼太過相近(difork)==>是否符合長度與字元要求(是否過於簡單)==>先前輸替字元的密碼==>選擇性的檢查是否使用連續相同的字元==>選擇性的檢查是否包括使用者名稱

pam_cracklib.so 模組重要選項及說明為:

maxrepeat=N 超過N個相同連續的字元將被拒絕
minlen
  • 此選項用以限制最短密碼長度,但它的用法並不像字面上一般簡單,因為它需要搭配length credit的使用 (請看下一個選項)
  • Linux的密碼可由大寫字母、小寫字母、數字與其它四類字元形成,預設上只要使用到任何一種類型的字元就可以得到1個 length credit
  • 假若您的minlen=12,但設定密碼為 a1z9PA/\卻可以通過檢查,因為密碼中包含了四種類型的字元,每一種可得一個length credit,共可獲得四個Length credit,而密碼本身有8個字元,所以8+4=12可以符合minlen=12的要求
  • 不論您的minlen或credit如何設定,Cracklib 並不允許使用人輸入6個字元以下
  • 記住,不論您的minlen或credit如何設定,Cracklib 並不允許使用人輸入6個字元以下 ,如果您要允許五個字元長度的密碼請勿使用此模組。
lcreditucreditdcreditocredit (預設值均為 1 )
  • 設定小寫、大寫、數字和其它字元的 credit
  • 此值設定成正數和負數有不同的涵意:
    (1) 設定為正數(N)代表當新密碼出現這種類型的字元時,其Length credit為當此種字元出現小於或等於N時,每出一次 Length credit 加 +1 ,例 dcreat=3時,如果新密碼只出現一個數字則length credit =1,若出現二個數字則credit=2,若出現三個數字則credit=3,若出現四個數字以上則credit=3
    (2)  設定為零時,則表示沒有 length credit
    (3) 設定為負數(-N)時,代表新的密碼必需至少出現N個這種類型的字元
difork 用以控制新的密碼內必需要有多久個字元與舊的密碼不同,此外,只要有一半的字元與舊密碼不同,則就會接受此新的密碼
reject_username 禁止使用者名稱直接或以反逆的方式出現在新密碼中
retry 允許使用者變更密碼嘗試的次數,例如retry=3表示使用者有三次的機會來設定符合規定的密碼,超過三次無法變更成功,就會回應錯誤
範例與說明
pam_cracklib最讓人混淆而不易搞清楚的地方在於length credit的使用,底下以三個例子來說明其用法。
  • 範例一:
    password required pam_cracklib.so dcredit=-1 ucredit=-1 ocredit=-1 lcredit=0 minlen=8
    要求新密碼中,至少要有1個數字,一個小寫,一個其它字元,長度至少為8
  • 範例二:
    password required pam_cracklib.so ocredit=-3 minlen=9
    密碼若為 /\!aA1 即可通過 (因使用大寫、小寫和數字皆可獲得一個length credit,所以雖然只輸入六個字元,但因有包含所需的三個特殊字元加上三個credit所以為合格密碼)
  • 範例三:
    password required pam_cracklib.so ocredit=3 ucredit=-1 minlen=11
    要求新密碼中,長度為11,特殊字元在三個以下,每個credit加1,大寫至少要出現一個,小寫和數字只要出現credit就加1 (預設)
    新密碼 /\!Aa1 可通過檢查,因為特殊字元三個導致credit +3, 小寫和數字又都有出現,credit又加了2,所以此密碼credit共加了5 ,大寫也符合規定的出現一個,輸入6個字元,符合最小長度6+5=12的要求
    若密碼為 /\Aa12 則不會通過檢查,/\Aa123 就可通過檢查

使用 pam_unix.so 模組

pam_unix為傳統的密碼驗證模組,透過呼叫標準的系統程式庫來取得或設定帳戶密碼相關資訊,通常是由/etc/passwd和/etc/shadow檔案取得驗證及密碼相關資訊,但也可以藉由設定/etc/nsswitch.conf檔案來使用其它的帳戶資料庫。

pam_unix的使用簡單,通常也和上述的pam_cracklib搭配使用,常用的參數如下表:

nullok 預設上並不允許使用者利用空白密碼存取與驗證,但使用nullok則可覆蓋過此預設,而可以使用空白密碼。
try_first_pass 當有必要提示使用者輸入密碼進行驗證前,先使用先前PAM堆疊通過的密碼
use_first_pass 強迫使用先前PAM堆疊通過檢查的密碼來進行驗證,而絶不會提示使用者需要輸入密碼,如果沒有PAM堆疊先前使用的密碼或密碼不適合,則會拒絕存取。
use_authtok 當密碼變更,將強制模組設定此新密碼給先前PAM堆疊所使用的密碼模組
remember=n 將使用者最近幾次使用的密碼儲存記錄在/etc/security/opasswd檔案中,以避免使用者重複使用先前用過的舊密碼
shadow 維護shadow密碼系統
md5、bigcrypt、sha256、sha512、blowfish 當使用者下回變更密碼時,所使用的加密演算法 。
  • 基於安全性考量,md5雜湊和 bigcrypt (DES對稱加密)不建議使用
  • blowfish對稱加密演算法較容易有相容性問題,亦不建議使用
  • 建議使用 sha256 或 sha512。

PAM模組密碼強度檢查範例

根據上面說明,透過PAM模組實現所制定的密碼強度檢查,您需要編輯 /etc/pam.d/system-auth檔案並且修改pam_cracklib和pam_unix那二行的參數,底下列出數個範例以資參考:

範例一:
password requisite pam_cracklib.so try_first_pass retry=3 dcredit=-1 lcredit=-1 ocredit=-1 ucredit=0 minlen=7 reject_username
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5

使用者的密碼需要至少七個字元以上, 密碼內至少要出現數字、小寫字母和其它字元三種字元,且不能包含使用者名稱,不能使用先前用過的五次密碼
範例二:
password requisite pam_cracklib.so try_first_pass retry=3 lcredit=-1 ucredit=-1 ocredit=-2 dcredit=-1 minlen=8 reject_username
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=8

使用者的密碼需要至少八個字元以上, 密碼內數字、小寫字母和大寫字元三種字元至少要出現一次,而其它字元至少要出現二次,密碼不能包含使用者名稱,不能使用先前用過的八次舊密碼

參. 使用pam_passwdqc取代pam_cracklib (如有必要)

Linux PAM程式庫中大多使用pam_cracklib來執行密碼複雜度檢查機制,但它並非唯一可檢查密碼強度的模組,還有一個密碼品質控制PAM模組-pam_passwdqc (password quality-control )也可以用來執行類似的工作,所以除了大部份版本的Linux所用的pam_cracklib,您也可以改採用pam_passwdqc模組來執行密碼複雜度檢查工作。

作者較偏好使用pam_passwdqc來執行密碼檢查,因為它沒有麻煩的length credit問題,而且pam_passwdqc模組不僅將密碼(password)和通行口令(passphrase)的檢查條件分開,還對不同字元類型組成的密碼允許分開限制長度,這較為合理,此外它可以只警告而不強制,把root排除在外,所以較具彈性,pam_passwdqc模組的要參如下表:

min=N0,N1,N2,N3,N4
(例: min=disabled,disabled,15,8,7)
這是pam_passwdqc最重要選項,對針五種不同類型的密碼(password)或通行口令(Passphrase)所要求的最短長度,若使用disabled則代表禁止使用這種類型的密碼,min選項後面有5個數字N0,N1,N2,N3,N4,其涵義如下:
  • N0 只包含一種字元類別的密碼至少要多少長度,右邊的例子 disabled代表不允許使用此種密碼
  • N1 包含二種字元類別的密碼至少需要多少長度,右邊的例子 disabled代表不允許使用此種密碼,所以
    綜合 N0, N1後,在本系統中合格的密碼至少需包含三種或四種字元類別才行
  • N2 代表如果使用通行口令除了passphrase選項所訂的字數要求外)還需要符此長度,本例代表使用通行
    口令至少要15個字元
  • N3 包含三種字元類別的密碼至少需要多少長度,右邊的例子,若密碼內使用三種不同的字元類型時要
    求至少要有8個字元
  • N4 包含四種字元類別的密碼至少需要多少長度,右邊的例子,若密碼內使用四種不同的字元類型時要
    求至少要有7個字元
max 最大允許的密碼長度,避免使用者使用太長的密碼,因為某些服務可能無法支援太長的密碼。
enforce=none | users | everyone 本模組密碼檢查結果設定為警告用途(none),只強制套用在非root的使用者(users)、或強制套用到包含root的所有使用者。
passphrase 使用通行口令時至少需要包含幾個字(word),若設為0則代表不支援使用者自行選取的通行口令。
retry=3 模組提示詢問新密碼的次數
similar={permit | deny} 是否允許新密碼和舊的密碼相近

使用pam_passwdqc取代pam_cracklib,您需要編輯 /etc/pam.d/system-auth檔案,然後將pam_cracklib一行換成pam_passwdqc及其參數,如下面所示

password requisite pam_cracklib.so try_first_pass retry=3 type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok

改為:

password  requisite   pam_passwdqc.so min=disabled,disabled,12,8,7 max=40 passphrase=3  similar=deny enforce=everyone retry=4
password  sufficient  pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=8

Linux 嚴格密碼原則實施結語

綜合而論,在linux上要制定嚴謹的密碼原則其實很簡單:

  1. 設定密碼最長最短使用期限
    編輯/etc/login.defs檔案,若帳戶已存在請使用chage –m –M 指令變更shadow檔第四與第五欄位
  2. 設定密碼複雜度檢查機制
    編輯/etc/pam.d/system-auth檔案,修改pam_cracklib和pam_unix二行參數,加上長度、字元限制與記錄密碼歷程
  3. 若您需要更嚴謹的密碼原則,請使用pam_passwdqc取代pam_cracklib

肆. PAM模組的其它帳戶安全性管理設定

除了密碼原則之外,某些環境下可能還需要搭配一些PAM模組的限制以確保安全,常見限制包括了限制使用者同時登入次數,登入的位置和登入的時段等,分別詳述如下。

利用pam_limits限制使用者登入次數

pam_limits模組可用來限制使用者工作階段取得的系統資源,如限制最大CPU時間,最大記憶體空間、處理程序數...等,在此將利用來限制使用者登入的次數,即使是 root也會受到限制,使用時pam_limits模組會參考 /etc/security/limits.conf 檔案內的設定,來限制使用者或群組所使用資源,步驟如下:

  1. 引入PAM限制模組

    請修改 /etc/pam.d/login檔案,並加入一行:

    session required pam_limits.so

  2. 修改 /etc/security/limits.conf 檔案
    limits.conf 的設定格式有四個欄位,分別是 domain、type、item、value。
    • domain 可以是使用者或群組名稱,使用群組時時,需要在前面加上個 "@" 符號。
    • type 有 soft 及 hard 這兩個選項可以設定,分別代表的是警告用途的 soft limit 以及具強制性的 hard limit,而 "-" 則 代表二者)。
    • item 為限制存取資源的項目,有core 、data、fsize、memlock、nofile、rss、stack、cpu、nprooc、maxlogins、… 等,請參考說明手冊,在此使用maxlogins以控制登入數。
    • value 自然是該 item 的設定值。

    下面的範例限制 admins群組的成員,最多只能同時登入兩次 (包含遠端登入),而其它使用者只能登入一次。

    @admins -  maxlogins 2
    *  hard maxlogins 1

利用pam_access限制使用者登入的位置

pam_access 模組透過參照 /etc/security/access.conf 檔案內容,來允許或拒絕那些使用者帳號能從哪些特定的來源端登入,而access.conf檔案內容的格式如下:

 access.conf檔案格式:permission : users : origins
  • permission:可以設定成 " + " (允許存取) 或 " - " (拒絕存取)
  • users:可以是使用者名稱、群組名稱或所有人(ALL),為了區分使用者與群組,群組需要前面加上@ 符號。
  • origins:設定來源端,可以是終端機(tty)、主機名稱(hostname)、網域名稱 (.domain.com)、IP 位址 (192.168.1.1)、網段(192.168.1.0/24、192.168.1.0/255.255.255.0)、所有來源端 (ALL) 、本機(LOCAL)。
範例:
  1. -: ALL EXCEPT root mary:192.168.1.1
    root和mary二人只允許從192.168.1.1機器登入
  2. -:root:ALL EXCEPT LOCAL
    root只能由本機登入
  3. + : root : 192.168.1.0/24
    允許root由192.168.1網段內的機器登入

管理員若需要限制使用者登入位置,其實做步驟與範例如下:

  1. 引入PAM限制模組

    請修改 /etc/pam.d/login檔案,並加入一行:

    session required pam_access.so

  2. 修改 /etc/security/access.conf 檔案
    -:ALL .spam.net .badnet.com
    -:ALL EXCEPT root: tty1 tty2 tty3
    +:ALL EXCEPT root: 192.168.1.
    +:(wheel) may: ws1 ws2
    -:ALL:ALL

利用pam_time限制使用者登入時間

pam_time模組會參考 /etc/security/time.conf檔案的內容,來限定使用者登入的時間,而這個 time.conf 的設定格式如下表:

 time.conf檔案格式:services;ttys;users;times
  • services:規則應用的服務名稱
  • ttys:規則應用的終端機名稱。
  • users:使用者或群組名稱列。
  • times:限制存取的時間,時間格式的寫法:週一至週日分別以英文表示為 Mo、Tu、We、Th、Fr、Sa、Su,而 Wd(Weekdays)、Wk(Weekends)、Al (All) 分別表示上班天、週末(週六和週日)以及週一至週日的每一天,AlTh 則是除了星期四以外的每一天。另外若需要搭配確切的存取時間來使用,比如 " TuThSa0800-1700 " 是每週二、四、六的早上八點至下午五點," ! Mo0000-2400 " 則是表示週一時間都禁止的意思。

※ 您可以搭配萬用字元 " * " 以及各種邏輯運算式 ! (NOT)、| (OR)、& (AND) 來彈性使用

範例:
  1. login ; tty* ; !root ; !Al0000-2400
    除了 root以外的任何者均不得在任何時間利用本機終端機登入
  2. * ; * ; !root ; Wd0800-1800 
    除了 root以外的一般使用者只能在上班天的早上八點到下午六點間登入
  3. login ;*;joe|may|bill;A11200-2000
    允許joe, may, bill三個人在每天的中午十二點至下午八點登入

管理員若需要限制使用者登入的時段,其實做步驟和範例大抵如下:

  1. 引入PAM限制模組

    請修改 /etc/pam.d/login以及/etc/pam.d/gdm二個檔案,並各加入底下一行:

    account required pam_time.so

  2. 修改 /etc/security/time.conf 檔案
    login ; tty* ; !root ; !Al0000-2400

    login|gdm ;*;joe|may|bill;A11200-2000

結語

使用者帳戶的安全性管理為系統安全性的基礎,而利用PAM模組來提供Linux各種服務的驗證並進行帳戶管理工作可謂相當有彈性又功能強大,不過對一般系統管理員而言複雜度也不低,所以實做前請將重要組態檔備份一份,而對於root相關設定務必小心,以免設定不當反而造成root鎖定問題,再者,設定完成後一定得加以測試驗證,以避免實做上的錯誤與遺漏而造成另一層安全性問題。

相關文章