首頁 >系統教程 >Linux >Linux權限控制的基本原理

Linux權限控制的基本原理

王林
王林轉載
2023-12-31 15:59:501286瀏覽

本文主要介紹 Linux 系統中,權限控制的基本原理。 Linux權限控制的基本原理

安全模型

在 Linux 系統中,我們所有的操作實質都是在進行進程存取檔案的操作。我們存取檔案需要先取得對應的存取權限,而存取權限是透過 Linux 系統中的安全模型取得的。

對於 Linux 系統中的安全模型,我們需要知道下面兩點:

  1. Linux 系統上最初的安全模型叫 DAC, 全名為 Discretionary Access Control ,翻譯為自主存取控制。
  2. 後來又增加設計了一個新的安全模型叫 MAC, 全名為 Mandatory Access Control, 翻譯為強制存取控制。

注意, MAC 和DAC 不是互斥的, DAC 是最基本的安全模型,也是通常我們最常使用到的存取控制機制是Linux 必須具有的功能, 而MAC 是建構在DAC 之上的加強安全機制,屬於可選模組。存取前, Linux 系統通常都是先做 DAC 檢查, 如果沒有通過則操作直接失敗 ; 如果透過 DAC 檢查並且系統支援 MAC 模組,再做 MAC 權限檢查。

為區分兩者,我們將支援 MAC 的 Linux 系統稱為 SELinux, 表示它是針對 Linux 的安全加強系統。

這裡,我們將講述 Linux 系統中的 DAC 安全模型。

DAC 安全性模型

DAC 的核心內容是:在 Linux 中,進程理論上所擁有的權限與執行它的使用者的權限相同。其中涉及的一切內容,都是圍繞著這個核心進行的。

使用者和群組 ID 資訊控制

使用者、群組、口令資訊

透過 /etc/passwd 和 /etc/group 保存使用者和群組訊息,透過 /etc/shadow 保存密碼口令及其變動訊息, 每行一筆記錄。

使用者和群組分別以 UID 和 GID 表示,一個使用者可以同時屬於多個群組,預設每個使用者必屬於一個與之 UID 同值同名的 GID 。

對於/etc/passwd , 每筆記錄欄位分別為使用者名稱: 口令(在/etc/shadow 加密儲存):UID:GID(預設UID): 描述註解: 主目錄: 登入shell(第一個執行的程序)

對於 /etc/group , 每筆記錄欄位分別為 群組名稱:口令(一般不存在群組口令):GID:群組成員使用者清單(逗號分割的使用者 UID 清單)

對於 /etc/shadow ,每筆記錄欄位分別為: 登入名稱: 加密口令: 最後一次修改時間: 最小時間間隔: 最大時間間隔: 警告時間: 不活動時間:

範例

以下是使用者和群組資訊的舉例。 /etc/shadow 中的口令資訊為加密存儲,不舉例。

Linux權限控制的基本原理

#檔案權限控制資訊

#檔案類型

Linux 中的檔案有以下類型:

  • 普通文件, 又包括文字檔案和二進位文件,可用 touch 建立;
  • 套接字文件, 用於網路通訊,一般由應用程式在執行中間接創建;
  • 管道檔案是有名管道,而非無名管道,可用 mkfifo 建立;
  • 字元檔案和區塊檔案皆為裝置文件,可用 mknod 建立;
  • 連結檔案是軟連結文件,而非硬連結檔案, 可用 ln 建立。

存取權限控制群組

#分為三組進行控制:

  • user 包含對檔案屬主設定的權限
  • group 包含對檔案屬群組設定的權限
  • others 包含對其他者設定的權限

可設定的權限

#下面給出常見(但非全部)的權限值, 包括:

  • r 表示具有讀取權限。
  • w 表示具有寫入權限。
  • x 一般針對可執行檔 / 目錄,表示具有執行 / 搜尋權限。
  • s 一般針對可執行檔 / 目錄,表示具有賦予檔案屬主權限的權限,只有 user 和 group 群組可以設定該權限。
  • t 一般針對目錄,設定黏滯位後,有權限的使用者只能寫、刪除自己的檔案, 否則可寫、刪除目錄所有檔案。舊系統也表示可執行檔案運作後將 text 拷貝到交換區提升速度。

範例

透過 ls -l 可以查看到其檔案類型及權限,透過 chmod 修改權限。

舉例來說,

Linux權限控制的基本原理

#

輸出中, 第1 個字元表示檔案類型,其中,普通檔案(-)、目錄檔案(d)、套接字檔案(s),管道檔案(p),字元檔案(c),區塊檔案(b),連結檔案(l);第2 個字元開始的-rwxr-xr-x 部分錶示檔案的權限位,共有9 位。

對於檔案 /usr/bin/qemu-i386 , 這個權限控制的意思是:

  1. 第 2~4 位元的 rwx 表示該檔案可被它的 owner (屬主)以 r 或 w 或 x 的權限存取。
  2. 第 5~7 位元的 r-x 表示該檔案可被與該檔案相同屬群組的使用者以 r 或 x 的權限存取
  3. 第 8~10 位元的 r-x 表示該檔案可被其它未知使用者以 r 或 x 的權限存取。

對於 test/, test2/, test3/ 設定的權限:

  1. r,w,x 權限對每一個權限控制群組的權限以一位 8 進位來表示; 例如: 755 表示 rwxr-xr-x 。
  2. s,t 權限會取代x 位置顯示;設定s,t 權限則需在對應的、用於控制r,w,x 的8 進位權限控制組前追加數字; s 權限用於屬主屬組控制, t 用於其它控制。
  3. 設定屬主 s 需追加 4, 設定屬組 s 追加 2, 設定其它者 t 權限追加 1 ; 例如前面對 test/ 設定 t, 則用 1775, 表示 rwxrwxr-t 。
進程權限控制資訊

#進程權限

對於進程,有下列屬性與檔案存取權限相關:

  • effective user id : 與進程存取檔案權限相關的 UID (簡寫為 euid )。
  • effective group id : 進程存取檔案權限相關的 GID (簡寫為 egid )。
  • real user id : 建立該行程的使用者登入系統時的 UID (簡寫為 ruid )。
  • real group id : 建立該進程的使用者登入系統時的 GID (簡寫為 rgid )。
  • saved set user id : 拷貝自 euid 。
  • saved set group id : 拷貝自 egid 。

範例

我們可以使用 ps 和 top 選擇查看具有 euid 和 ruid 的進程。或透過 top 來查看進程的 euid 和 ruid

透過 top 來查看的範例:

先輸入 top 得到類似如下

Linux權限控制的基本原理

#這裡透過 -d 選項延長 top 的刷新頻率便於操作。此處可見,只有 USER 字段,表示對應進程的 effective user id.

開啟 read user id 的顯示選項:

a. 在 top 指令運行期間,輸入 f, 可以看見類似如下行:

b. 輸入 c 即可開啟 Real user name 的顯示開關。

c. 最後 Return 回車回到 top 中,即可看到 real user id 的選項。此時輸入`o`,可調整列次序。最後我們看到包含`effective user id`和`real user id`的輸出如下:

進程存取檔案的權限控制策略

規則

進程存取檔案大致權限控制策略

對於進程存取檔案而言,最重要的是 euid, 所以其權限屬性皆以 euid 為 「中心」。

  • 流程的 euid 一般預設為 其 ruid 值
  • 若可執行檔的可執行權限位元為 s ,程序對其呼叫 exec 後,其 euid 被設定為該執行檔的 user id
  • 進程的 saved set user id 拷貝自 euid.
  • 當進程的 euid 與檔案的 user id 相符時,流程才具有檔案 user 權限位元所設定的權限
  • 群組權限 egid 的控制規則類似。

透過 exec 執行檔修改權限屬性

透過 exec 呼叫可執行檔之時:

  • 進程 ruid 值始終不變;
  • saved set-user ID 總是來自 euid ;
  • euid 值取決於檔案的 set-user-ID 位元是否已設定。

如下:

透過 setuid(uid) 系統呼叫修改權限屬性

透過 setuid(uid) 修改權限屬性之時:

  • superuser 可順利修改 ruid, euid, saved set-user ID ;
  • unprivileged user 只能在 uid 與 ruid 相等時修改 euid, 其它無法修改。

範例

再舉幾個比較特別的例子:

設定了 set-user-id

Linux權限控制的基本原理

#如前所述,這個輸出的意思是,對於 /usr/bin/sudo 文件,

  • 第 1~3 位元的 rws 表示該檔案可被它的 owner(屬主)以 r 或 w 或 s 的權限存取
  • 第 4~6 位元的 r-x 表示該檔案可被與該檔案相同屬群組的使用者以 r 或 x 的權限存取。
  • 第 7~9 位的 r-x 表示該檔案可被其它未知使用者以 r 或 x 的權限存取。

這樣設定之後,對於 owner,具有讀取、寫入、執行權限,這一點沒有什麼不同。但對於不屬於 root 群組的普通使用者進程來說,卻大不相同。

普通使用者程序執行 sudo 指令時透過其 others 中的 x 取得執行權限,再透過 user 中的 s 使得一般使用者行程暫時具有了 sudo 可執行檔屬主 ( root ) 的權限,即超級權限。

這也是為什麼透過 sudo 指令就可以讓一般使用者執行許多管理員權限的指令的原因。

設定了 stick-bit

Linux權限控制的基本原理

#這樣設定之後,對於 /tmp 目錄,任何人都有讀取、寫入、執行權限,這一點沒有什麼不同。但是對於 others 部分設定了黏滯位 t, 其功能卻大不相同。

若目錄沒有設定黏滯位,任何對目錄有寫入權限者都則可刪除其中任何檔案和子目錄,即使他不是對應檔案的擁有者,也沒有讀取或寫入授權; 設定黏滯位後,使用者就只能寫入或刪除屬於他的檔案和子目錄。

這也是為什麼任何人都能在 /tmp 目錄中寫檔案、目錄,卻只能寫和刪除自己擁有的檔案或目錄的原因。

舉一個 man 程式的應用程式片段,描述 set-user-id 和 saved set-user-id 的使用

man 程式可以用來顯示線上幫助手冊, man 程式可以被安裝指定 set-user-ID 或 set-group-ID 為一個指定的使用者或群組。

man 程式可以讀取或覆寫某些位置的文件,這一般由一個設定檔 (通常是 /etc/man.config 或 /etc/manpath.config ) 或命令列選項來進行設定。

man 程式可能會執行一些其它的命令來處理包含顯示的 man 手冊頁的檔案。

為防止處理出錯, man 會從兩個特權之間進行切換:執行 man 指令的使用者特權,以及 man 程式的擁有者的特權。

需要抓住的主線:當只執行man 之時,進程特權就是man 用戶的特權, 當透過man 執行子進程(如透過!bash 引出shell 指令)時,用戶切換為當前用戶,執行完又切換回去。

過程如下:

  1. 假設 man 程式檔案被使用者 man 所擁有,並且已經設定了它的 set-user-ID 位,當我們 exec 它的時候,我們有以下情況:
    – real user ID = 我們的使用者 UID
    – effective user ID = man 使用者 UID
    – saved set-user-ID = man 使用者 UID
  2. man 程式會存取所需的設定檔和 man 手冊頁。這些檔案由 man 使用者所擁有,但由於 effective user ID 是 man, 檔案的存取就被允許了。
  3. 在 man 為我們執行任何指令的時候,它會呼叫 setuid(getuid())) (getuid() 回傳的是 real user id).
    因為我們不是 superuser 進程,這個變化只能改變 effective user ID. 我們會有以下情況:
    現在 man 進程運行的時候把我們得 UID 作為它的 effective user ID. 這也就是說,我們只能存取我們擁有自己權限的檔案。也就是說,它能夠代表我們安全地執行任何 filter.
    – real user ID = 我們的使用者 UID(不會被改變)
    – effective user ID = 我們的使用者 UID
    – saved set-user-ID = man 的使用者 UID(不會被改變)
  4. 當 filter 做完了的時候, man 會呼叫 setuid(euid).
    這裡, euid 是 man 使用者的 UID.(這個 ID 是透過 man 呼叫 geteuid 來保存的) 這個呼叫是可以的,因為 setuid 的參數和 saved set-user-ID 是相等的。 (這也就是為什麼我們需要 saved set-user-ID). 這時候我們會有以下情況:
    – real user ID = 我們的使用者 UID(不會被改變)
    – effective user ID = man 的 UID
    – saved set-user-ID = man 的使用者 UID(不會被改變)
  5. 由於 effective user ID 是 man, 現在 man 程式可以操作它自己的檔案了。
    透過這樣使用 saved set-user-ID, 我們可以在流程開始和結束的時候透過程式檔案的 set-user-ID 來使用額外的權限。然而,期間我們卻是以自己的權限來運作的。如果我們無法在最後切換回 saved set-user-ID, 我們就可能會在我們運行的時候保留額外的權限。

下面我們來看看如果 man 啟動一個 shell 的時候會發生什麼事:

  • 這裡的 shell 是 man 使用 fork 和 exec 來啟動的。
  • 因為這時 real user ID 和 effective user ID 都是我們的普通用戶 UID(參見 step3), 所以 shell 沒有其它額外的權限.
  • 啟動的 shell 無法存取 man 的 saved set-user-ID(man) , 因為 shell 的 saved set-user-ID 是由 exec 從 effective user ID 拷貝過來的。
  • 在執行 exec 的子進程 ( shell ) 中,所有的 user ID 都是我們的普通使用者 ID.

實際上,我們描述man 使用setuid 函數的方法不是特別正確,因為程式可能會set-user-ID 為root . 這時候, setuid 會把所有三種uid 都變成你設定的id,但是我們只需要設定effective user ID。

以上是Linux權限控制的基本原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:linuxprobe.com。如有侵權,請聯絡admin@php.cn刪除