Overview of Content
探索Linux系統中身份驗證與權限管理的核心概念,從UID切換到使用者驗證和PAM框架的全面解析。
- 認識UID & UID切換:稍微深入了解 UID 的概念,探討 setuid 函數以及與安全問題相關的注意事項
- 多使用者驗證:介紹使用者標示和認證的不同方法,包括傳統取得使用者名稱和使用函數庫取得使用者資訊
- 認識PAM:認識高靈活性的 PAM 框架,包括 PAM 設定、堆疊規則、驗證設定選項以及其他相關知識點
無論您是Linux系統管理員還是開發人員,本文將為您提供深入的身份驗證和權限管理知識,幫助您更好地理解和應用於實際工作中。
個人程式分享時比較注重「縮排」,所以可能不適合手機的排版閱讀,建議切換至「電腦版」、「平板版」視窗看 😀
寫文章分享不易,如有引用參考請詳註出處,如有指導、意見歡迎留言(如果覺得寫得好也請給我一些支持),感謝 😀
認識 UNIX UID & UID 切換
像是 su、sudo 這種個指令允許我們切換使用者,而 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,那普通使用者執行時就可以執行它來獲得整個系統的控制權
● 程式功能面問題
如果你的程式需要 setuid 為 root 才可以啟動(使用 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 要幹麻?
簡單來說為了 方邊控制,想想如果沒有 UID 的改變,那我們在啟動程式後需要中止(或是資源修改),就會需要不斷的使用
sudo切換詳細可看
man 2 setuid手冊
● 如果我們是切換使用者執行程式(使用到 setuid)時,Linux 會將當前用戶的 Effective UID 設定為檔案的 Effective UID(ruid 不會改變)
A. root 用戶使用執行應用,而應用中使用到
setuid 函數會將實際用戶 ID(ruid)、有效用戶 ID(euid)、保存用戶 ID(suid)設定為 root 用戶 ID
B. 一般用戶使用執行應用,而應用中使用到 setuid
一般用戶執行 setuid 只會將有效用戶 ID(euid)設定為當前用戶 ID
● 一般情況下
euid,ruid會被設定為相同,可用以下命令查看ps -eo pid,euid,ruid,comm
多使用者驗證:使用者標示、認證
「使用者標示、認證」通常是指在使用者空間中的應用程序或程式庫使用的功能,用於識別和驗證使用者的身份
多使用者系統必須支援 使用者標識、使用者認證,像 Ubuntu 就是可以擁有多個使用者一起使用的系統,所以需要 驗證不同的使用者
| 支援功能 | 說明 |
|---|---|
使用者「標識」(identification) | 判斷是哪位使用者(Linux 核心透過使用者 EUID 來管理程序、檔案權限),並可透過 setuid 來切換 |
使用者「認證」(authentication) | 驗證是否是宣稱的使用者 |
核心並不關心使用者空間有關認證的事項(eg. 使用者名稱、密碼);核心只保存資料,而驗證是應用端的規範、應用
傳統取得使用者名稱
● 傳統的 Unix 會經過以下步驟(概略)來獲取使用者名稱(不包括密碼比對)
A. 程序透過 系統呼叫 geteuid(),取得核心返回的 euid
B. 開啟、讀取 /etc/passwd 檔案
● 解析欄位,並使用切割的第三個項目來作為使用者 ID(EUID)
● 匹配成功後獲取第一個項目作為使用者名稱
使用函數庫:取得使用者資訊
● 由於使用者名稱的獲取是有固定步驟,所以 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 繼續執行其他規則 |
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/*
解釋如下
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 知識
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 核心知識








