本文主要介紹 Linux 系統中,權限控制的基本原理。
安全模型在 Linux 系統中,我們所有的操作實質都是在進行進程存取檔案的操作。我們存取檔案需要先取得對應的存取權限,而存取權限是透過 Linux 系統中的安全模型取得的。
對於 Linux 系統中的安全模型,我們需要知道下面兩點:
注意, 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 中的檔案有以下類型:
存取權限控制群組
#分為三組進行控制:
可設定的權限
#下面給出常見(但非全部)的權限值, 包括:
範例
透過 ls -l 可以查看到其檔案類型及權限,透過 chmod 修改權限。
舉例來說,
#輸出中, 第1 個字元表示檔案類型,其中,普通檔案(-)、目錄檔案(d)、套接字檔案(s),管道檔案(p),字元檔案(c),區塊檔案(b),連結檔案(l);第2 個字元開始的-rwxr-xr-x 部分錶示檔案的權限位,共有9 位。
對於檔案 /usr/bin/qemu-i386 , 這個權限控制的意思是:
對於 test/, test2/, test3/ 設定的權限:
#進程權限
對於進程,有下列屬性與檔案存取權限相關:
範例
我們可以使用 ps 和 top 選擇查看具有 euid 和 ruid 的進程。或透過 top 來查看進程的 euid 和 ruid
透過 top 來查看的範例:
先輸入 top 得到類似如下
#這裡透過 -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 為 「中心」。
透過 exec 執行檔修改權限屬性
透過 exec 呼叫可執行檔之時:
如下:
透過 setuid(uid) 系統呼叫修改權限屬性
透過 setuid(uid) 修改權限屬性之時:
範例
再舉幾個比較特別的例子:
設定了 set-user-id
#如前所述,這個輸出的意思是,對於 /usr/bin/sudo 文件,
這樣設定之後,對於 owner,具有讀取、寫入、執行權限,這一點沒有什麼不同。但對於不屬於 root 群組的普通使用者進程來說,卻大不相同。
普通使用者程序執行 sudo 指令時透過其 others 中的 x 取得執行權限,再透過 user 中的 s 使得一般使用者行程暫時具有了 sudo 可執行檔屬主 ( root ) 的權限,即超級權限。
這也是為什麼透過 sudo 指令就可以讓一般使用者執行許多管理員權限的指令的原因。
設定了 stick-bit
#這樣設定之後,對於 /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 指令)時,用戶切換為當前用戶,執行完又切換回去。
過程如下:
下面我們來看看如果 man 啟動一個 shell 的時候會發生什麼事:
實際上,我們描述man 使用setuid 函數的方法不是特別正確,因為程式可能會set-user-ID 為root . 這時候, setuid 會把所有三種uid 都變成你設定的id,但是我們只需要設定effective user ID。
以上是Linux權限控制的基本原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!