認識身份驗證與權限管理:UNIX UID、使用者驗證與 PAM | PAM 設定

認識身份驗證與權限管理:UNIX UID、使用者驗證與 PAM | PAM 設定

Overview of Content

探索Linux系統中身份驗證與權限管理的核心概念,從UID切換到使用者驗證和PAM框架的全面解析。

  • 認識UID & UID切換:稍微深入了解 UID 的概念,探討 setuid 函數以及與安全問題相關的注意事項
  • 多使用者驗證:介紹使用者標示和認證的不同方法,包括傳統取得使用者名稱和使用函數庫取得使用者資訊
  • 認識PAM:認識高靈活性的 PAM 框架,包括 PAM 設定、堆疊規則、驗證設定選項以及其他相關知識點

無論您是Linux系統管理員還是開發人員,本文將為您提供深入的身份驗證和權限管理知識,幫助您更好地理解和應用於實際工作中。

個人程式分享時比較注重「縮排」,所以可能不適合手機的排版閱讀,建議切換至「電腦版」、「平板版」視窗看 😀

寫文章分享不易,如有引用參考請詳註出處,如有指導、意見歡迎留言(如果覺得寫得好也請給我一些支持),感謝 😀


認識 UNIX UID & UID 切換

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

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

A. 檔案為 setuid 權限

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

像是 passwd 命令就有 setuid 權限

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

● 任何程序只有要足夠的檔案存取權限都可以執行 setuid 檔案

B. 呼叫系統設定 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)相同
graph UID --> euid UID --> ruid UID --> suid

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

這麽多 UID 要幹麻

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

詳細可看 man 2 setuid 手冊

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

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

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

graph TB r(root 用戶, 1000) --> |1. 執行 |應用 subgraph 應用 setuid end r(root 用戶, 1000) --> |2. 暫時改變 euid, ruid, suid 為 1000 | 應用

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

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

graph TB r(一般用戶, 6666) --> |1. 執行 |應用 subgraph 應用 setuid end r(一般用戶, 6666) --> |2. 暫時改變 euid 為 6666 | 應用

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

ps -eo pid,euid,ruid,comm

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

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

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

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

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

傳統取得使用者名稱

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

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

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

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

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

graph LR 驗證應用程序 --> |1. System Call, geteuid| 核心 -.-> |euid| 驗證應用程序 pw(/etc/passwd 檔案) 驗證應用程序 --> |2 開啟, 讀取| pw -.-> |第三欄位, uid| 驗證應用程序 pw -.-> |第一欄位, user name| 驗證應用程序

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

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

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

B. 程序可以使用函數庫的 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 繼續執行其他規則
requisitePAM 會繼續執行其他規則驗證失敗,忽略其他 PAM 規則
requiredPAM 繼續執行其他規則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/*

解釋如下

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

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

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

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

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

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

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

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


更多 Linux Shell 知識

探索 Debian 系統上的套件管理系統(PKMS 概念)| 套件倉庫

Linux 環境、服務:用戶、權限管理

Linux 環境、服務、管理

在這個主題中,你可以探索各種 Linux 環境、服務和管理相關的重要概念…

了解 Linux 組成:內核責任、GNU 工具、桌面環境 | 基礎版到發行版

在這裡,你將了解 Linux 系統的基本組成部分,包括內核、GNU 工具和桌面環境,並了解不同 Linux 發行版之間的差異

探索 X Window 服務與桌面環境:Linux 視窗 XWindow 服務、D-Bus 機制

這裡探討了 Linux 系統中 X Window 服務和 D-Bus 機制的工作原理,讓你深入了解桌面環境的背後運作方式

Linux 系統管理入門:安全性、用戶管理與權限設定指南

在這個指南中,你將學習如何管理 Linux 系統,包括安全性、用戶管理和權限設定,以確保系統的安全和有效運作

認識身份驗證與權限管理:UNIX UID、使用者驗證與 PAM | PAM 設定

這裡介紹了 UNIX 系統中的身份驗證機制和權限管理方式,包括 UNIX UID、使用者驗證和 PAM(Pluggable Authentication Modules)設定

Linux Shell 相關知識

Linux Shell 相關知識

這個主題涵蓋了各種與 Linux Shell 相關的知識,從基礎到進階都有…

Shell 基礎知識:包括 Shell 的基礎使用以及差異,還有變數以及計算

認識命令行:Shell 類型、命令差異 | Sub Shell 關係 | Builtin 命令

這裡介紹了命令行中不同類型的 Shell,以及各種 Shell 命令之間的區別和內建命令的用法

Shell 全局及區域變數、特殊變數及環境變數 | Shell 啟動順序 | Array 變數

學習如何在 Shell 中使用全局變數、特殊變數和環境變數,以及如何設置和管理這些變數

探索腳本與命令:Shell 腳本的必備相關知識 | 腳本的數學運算

這裡介紹了 Shell 腳本的基本知識和常用技巧,包括如何執行腳本和進行數學運算

Shell 結構化

Shell 腳本程式中的條件語句和高級特性 | Shell 結構化 & 判斷

該篇文章是介紹結構化腳本的基礎以及特殊的高級技巧,轉著於腳本中的邏輯判斷

掌握 Bash 腳本中的迴圈與循環控制技巧 | Shell 結構化 & 循環

接著是腳本中的循環與控制的技巧,它可以讓我們在 Shell 腳本中有更多的判斷與技巧

探索 Shell 函數與腳本庫 | Shell 結構化 & 函數

這裡你將會學在到結構化腳本的重要技巧「函數」,它可以讓你建立可重複利用的腳本,以節省我們之後開發的時間

Shell 掌握參數處理與用戶輸入技巧 | Shell 結構化 &輸入互動

不可互動的腳本有時候相對無趣,這篇文章有分享如何讓腳本與使用者產生交互互動,並依照使用者輸入的參數做讀取

Shell script 進階

Shell 命令輸入與輸出指南:掌握標準文件描述符與重定向 | 臨時文件

掌控 Shell、指令的輸出輸入是成為進階使用 CLI 之人必經的一課,透過這篇文章可以了解到輸出輸入、臨時文件等等資訊

探索 Linux 訊號與後台進程管理:安排定期啟動腳本 | 運行時啟動腳本

信號可以算是 Shell 腳本與 Linux 系統之間的通訊方式,透過這個文章,我們可以了解到信號與 Shell 腳本的安排時間

Linux 硬體規劃:檔案系統、分區

Linux 硬體規劃:檔案系統、分區

最後,這個主題涵蓋了 Linux 系統中硬體結構相關的重要概念…

Shell 文件和目錄操作的常用命令和技巧 | 尋找檔案

這裡介紹了 Shell 中常用的文件和目錄操作命令,包括如何尋找文件和管理文件系統

深入探索 Linux 文件系統與硬體管理 | 分區、檔案系統、邏輯卷 | inode

學習如何管理 Linux 文件系統,包括分區、文件系統和邏輯卷等相關概念,以及文件系統中的 inode 機制

理解 Unix/Linux 設備偵測、建立 | 認識與使用 udevd | SCSI 與 Linux 核心

這裡介紹了 Unix/Linux 系統中的設備偵測和管理,包括如何使用 udevd 和 SCSI 相關的 Linux 核心知識


Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

發表迴響