Try   HackMD

使用者切換、認識 PAM

Overview of Content

認識 UID & UID 切換

像是 susudo 這種個指令允許我們切換使用者,而 login 這個系統元件負責控制使用者存取 這些會涉及核心如何切換使用者

  • 更改使用者 ID 一般可以透過以下兩種方式(setuid 的行為由核心負責完成切換

    1. 檔案為 setuid 權限

      有些可執行檔的執行位元是 s(一般為 x),表示在執行時會以 檔案擁有者的身份去執行,而非當前的用戶去執行

      像是 passwd 命令就有 setuid 權限

      請看下圖左邊 -rwsr-xr-x 中的 s,這表示了 passwd 命令有 setuid 權限

      Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →

      • 任何程序只有要足夠的檔案存取權限都可以執行 setuid 檔案
    2. 呼叫系統設定 setuid() 函數

      可用 setuid() 函數來處理與程序相關連的所有使用者 ID(之後在詳細介紹)

      • setuid() 規範

        setuid() 規範由核心定義,大多以 root 使用者身份才能呼叫 setuid();如果不已 root 身份呼叫 setuid(),那會有部份限制

        大多數情況下都只接受 root 使用者呼叫

切換 UID:setuid 函數、安全問題

  • setuid 這個系統呼叫(System call)調整的是 euid (所有者)

  • Linux 核心透過 setuid 程序核相關系統呼叫來處理使用者切換(還有相關檔案的存取權限),如果沒有注意,可能會導致安全性問題,常出現的問題如下

    • 檔案如果有 s 顯示,那該檔案將會有 setuid 的權限,會幫普通使用者提權

      如果你建立了一個 shell 並且 setuid 權限為 root,那普通使用者執行時就可以執行它來獲得整個系統的控制權

    • 程式功能面問題

      如果你的程式需要 setuidroot 才可以啟動(使用 sudo),如果程式出現 Bug 那很可能會導致系統損壞

各種 UID:執行時 UID 切換

  • 大多數時候提及的使用者 ID 都是「簡化過」的,實際上每個程序都有 超過一個 UID(或是應該說,UID 其實是有多種不同含義的) UID 有分為以下幾種,如下表…

    UID 種類 說明 補充
    Effective UID (euid) Effective UID 是用於權限檢查的用戶身份。當程序執行時,Effective UID 獲得了 Real UID 的權限,並可能根據需要被臨時修改(例如使用 setuid) 執行者,也就是一般情況下我們所說的 UID
    Real UID (ruid) Real UID 是程序「執行」的實際用戶身份 所有者,可以用來對程序發送訊號(像是中止)
    Saved UID(suid) 已保存 UID -
    File system UID(fsuid) fsuid 是Linux特有的使用者ID,用於檔案系統權限檢查 通常情況下,進程的檔案系統使用者ID(fsuid)與其有效使用者ID(euid)相同

    從這裡我們可以看到 Unix 將應用的各個不同功能做了權限的區分,像是「設定」、「執行」 等等權限分離

    UID

    euid

    ruid

    suid

    • 這麽多 UID 要幹麻

      簡單來說為了 方邊控制,想想如果沒有 UID 的改變,那我們在啟動程式後需要中止(或是資源修改),就會需要不斷的使用 sudo 切換

      詳細可看 man 2 setuid 手冊

  • 如果我們是切換使用者執行程式(使用到 setuid)時,Linux 會將當前用戶的 Effective UID 設定為檔案的 Effective UID(ruid 不會改變)

    1. root 用戶使用執行應用,而應用中使用到

      setuid 函數會將實際用戶 ID(ruid)、有效用戶 ID(euid)、保存用戶 ID(suid)設定為 root 用戶 ID

      Unsupported markdown: list
      Unsupported markdown: list

      應用

      setuid

      root 用戶, 1000

    2. 一般用戶使用執行應用,而應用中使用到 setuid

      一般用戶執行 setuid 只會將有效用戶 ID(euid)設定為當前用戶 ID

      Unsupported markdown: list
      Unsupported markdown: list

      應用

      setuid

      一般用戶, 6666

      • 一般情況下 euid, ruid 會被設定為相同,可用以下命令查看

        ​​​​​​​​​​​​ps -eo pid,euid,ruid,comm

        Image Not Showing Possible Reasons
        • The image was uploaded to a note which you don't have access to
        • The note which the image was originally uploaded to has been deleted
        Learn More →

多使用者驗證:使用者標示、認證

「使用者標示、認證」通常是指在使用者空間中的應用程序或程式庫使用的功能,用於識別和驗證使用者的身份

多使用者系統必須支援 使用者標識使用者認證,像 Ubuntu 就是可以擁有多個使用者一起使用的系統,所以需要 驗證不同的使用者

支援功能 說明
使用者「標識」identification 判斷是哪位使用者(Linux 核心透過使用者 EUID 來管理程序、檔案權限),並可透過 setuid 來切換
使用者「認證」authentication 驗證是否是宣稱的使用者

核心並不關心使用者空間有關認證的事項(eg. 使用者名稱、密碼);核心只保存資料,而驗證是應用端的規範、應用

傳統取得使用者名稱

  • 傳統的 Unix 會經過以下步驟(概略)來獲取使用者名稱(不包括密碼比對)

    1. 程序透過 系統呼叫 geteuid(),取得核心返回的 euid

    2. 開啟、讀取 /etc/passwd 檔案

      • 解析欄位,並使用切割的第三個項目來作為使用者 ID(EUID)

      • 匹配成功後獲取第一個項目作為使用者名稱

Unsupported markdown: list

euid

Unsupported markdown: list

第三欄位, uid

第一欄位, user name

驗證應用程序

核心

/etc/passwd 檔案

使用函數庫:取得使用者資訊

  • 由於使用者名稱的獲取是有固定步驟,所以 Unix 有提供一個標準函數庫供我們使用,簡化步驟如下

    1. 程序透過 系統呼叫 geteuid(),取得核心返回的 euid

    2. 程序可以使用函數庫的 getpwuid 函數來獲取與該使用者 ID 相關聯的使用者記錄,其中包括使用者名稱

      • 這裡說明的函數並「不包括密碼」的驗證 (/etc/passwd);傳統的密碼驗證有以下 侷限

        • 密碼協定、權限

          • 加密協定並 沒有系統等級的標準

          • 比對密碼的前提是 你需要對加密密碼有存取權限

        • 傳統驗證會假定

          • 假定每當使用者需要存取資源時都需輸入使用者名稱、密碼驗證

          • 假定是使用輸入密碼,無法接受指紋識別、人臉驗證(也就是生物識別技術),如果需要則須自己使用插件做功能支援

認識 PAM:高靈活性框架

為了提高使用者驗證的靈活性,Sun 公司在 1995 年提出了一個 新標準 PAM (Pluggable Authentiation Module)

PAM可以被視為「使用者標示、認證」方面的一個應用… PAM 是一個用於管理系統身份驗證「框架」,在許多 Unix-like 系統中被廣泛使用

PAM 是共享的驗證函式庫,使用者被移交給 PAM 來決定使用者的驗證方式,這 方便於插入新的驗證方式(其靈活性很高),並且也提供一些驗證控制服務

驗證函式庫由 Open source software foundation 提出

PAM 設定:堆疊規則、驗證設定選項

  • PAM 的設定檔通常存放在 /etc/pam.d 目錄下(也可能在 /etc/pam.conf 檔案中)

    ​​​​ls -laF /etc/pam.d

  • 我們來看 /etc/pam.d/chsh 的內容;在註解中我們可以看到:它只允許使用者使用 /etc/shells 中的 Shell

    ​​​​# This will not allow a user to change their shell unless ​​​​# their current one is listed in /etc/shells. This keeps ​​​​# accounts with special shells from changing them. ​​​​ ​​​​auth required pam_shells.so
    設置欄位(左到右) chsh 設置 說明
    功能類型 auth 某個使用者應用程式請求 PAM 執行的「驗證」任務;以當前來說是 auth 驗證任務
    控制參數 required 任務失敗時的操作;required 表示如果這個模組的執行失敗,則整個認證過程將被視為失敗(也就是 驗證是必須的操作
    模組 pam_shells.so 可插拔的驗證模組;以當前來說 pam_shells.so 模組檢查使用者 Shell 是否在 /etc/shells
    • 詳細設置可以透過 man 5 pam.conf 手冊查看

    我們在更近一步認識每一個欄位可以設定的數值

    • 功能類型:主要有以下幾類

      通常我們會結合 功能類型、模組 來確定該行的功能

      功能類型 說明 補充
      auth 驗證使用者身份 -
      account 檢查使用者帳號狀態 eg. 使用者是否有操作的權限
      session 僅在使用者目前程序內執行 eg. 顯示當日訊息
      password 用來更改使用者密碼、其他驗證資訊 -
    • 控制參數者:有分為 簡單語法高級語法,簡單語法有如下幾種

      控制參數 成功後操作 失敗後操作
      sufficient 驗證就成功,PAM 會忽略其他規則 PAM 繼續執行其他規則
      requisite PAM 會繼續執行其他規則 驗證失敗,忽略其他 PAM 規則
      required PAM 繼續執行其他規則 PAM 繼續執行其他規則,但最終仍會驗證失敗!
      • 高級語法是使用方括號 [] 表示,它可以根據模組的回傳值手動定義相應的操作

        可查看 man -5 pam.conf 手冊

      PAM 的驗證說可堆疊的規則,範例如下

      ​​​​​​​​auth sufficient pam_rootok.so ​​​​​​​​auth requisite pam_shells.so ​​​​​​​​auth sufficient pam_unix.so ​​​​​​​​auth required pam_deny.so

      堆疊規則後的驗證順序如下圖所示

    • 模組參數:PAM 模組就是運行的函數,使用時也可以帶入參數

      ​​​​​​​​# 參數 nullok ​​​​​​​​# 表示使用者可不用密碼 ​​​​​​​​auth sufficient pan_unix.so nullok

PAM 其他知識點:模組查詢

  • 模組查詢:可使用以下指令查看 PAM 相關使用模組的文檔

    ​​​​man -k pam_

  • /etc/pam.d/other 檔案:沒有設定檔的程式會套用 other 的規則

    • 其中 @include 語法用來載入整個設定檔(以可以使用控制參數來載入某個特定功能的設定檔)

預設會取密碼的方式、PAM 獲得密碼

  • 首先提及 /etc/shadow 檔案

    檔案 /etc/login.defs 它是 /etc/shadow 檔的設定值,其中包含了用於 shadow 密碼檔案加密算法的資訊

    • login.defs 的功能

      login.defs 的功能 已經漸漸被 PAM 取代,不過仍有作用,如果在系統不支援 PAM 時,就會去使用 login.defs 的功能

  • PAM 如何獲得密碼加密資訊

    PAM 處理密碼是透過,功能類型的 auth & password 兩個功能去驗證;如果要查看密碼設定可以使用以下命令

    ​​​​grep -r password.*unix /etc/pam.d/*

    解釋如下

    1. 功能參數password 這表示這個設定行用於密碼驗證步驟

    2. 控制參數[success=1 default=ignore] 這是一個控制指令,用於指定驗證模組的執行流程

      • success=1:表示如果這個模組成功驗證了密碼,則跳過下一個成功的模組

      • default=ignore:表示如果這個模組不符合執行條件,則忽略它,並繼續執行下一個模組

    3. 模組pam_unix.so 這是實際執行密碼驗證的 PAM 模組的名稱,並帶入以下參數

      • obscure:這是 pam_unix.so 模組的一個參數,用於指定密碼的複雜性要求

      • yescrypt:這是 pam_unix.so 模組的另一個參數,用於指定密碼的加密方法

        目前看起來,PAM 並不知道要使用哪個算法驗證,猜測是按照一訂的規則去一次嘗試解開,這也是它「框架」給予的部分自由度

Appendix & FAQ

tags: linux