­

linux用戶用戶組與ACL

使用者ID:UID與GID

在使用Linux的過程中,經常會遇到各種用戶ID(user identifier, UID)和組ID(group identifier, GID),Linux也是通過對這些ID的管理實現的自主訪問控制(discretionary access control, DAC)。

用戶ID(英語:user identifier,一般縮寫為User ID或UID),全稱用戶標識符,在類UNIX系統中是內核用來辨識用戶的一個無符號整型數值,亦是UNIX文件系統與進程的必要組成部分之一。[1]

雖然我們登錄Linux主機時使用的是賬戶,但是對於Linux系統而言,它只認識ID。而ID與賬戶的對應就記錄在/etc/passwd文件中。可以通過命令id查看各個id與賬戶名的對應關係:
image_192

從上圖中我們可以看到,我的用戶名是wang,它的UID是1000,GID也是1000

UID範圍

在不同系統中,UID值範圍也有所不同,但一般來說UID是由一個16bit的無符號整數表示的,其範圍在0-65535之間。

UID 賬戶
0 root,超級用戶的UID總為0
65535 nobody,總是UID的最大值
1~999 一般約定是系統保留範圍,由系統使用
1000~65534 一般用戶UID

UID與GID分類

值得注意的是,以下的分類都是針對進程而言的,只有進程才會有下述幾種ID。

中文 英文 解釋
有效用戶ID與有效組ID Effective UID, EUID, Effective GID, GID 在創建和訪問文件時發揮作用。具體來說,創建文件時,系統內核將根據創建文件的進程的EUID與EGID設定文件的所有者/組屬性,而在訪問文件時,內核亦根據訪問進程的EUID與EGID決定其能否訪問文件。
真實用戶ID與真實用戶組 Real UID, RUID, Real GID, RGID 用於辨識進程的真正所有者,且會影響到進程發送訊號的許可權。
暫存用戶ID Saved UID, SUID 特權許可權運行的進程暫時需要做一些不需特權的操作時使用,這種情況下進程會暫時將自己的有效用戶ID從特權用戶(常為root)對應的UID變為某個非特權用戶對應的UID,而後將原有的特權用戶UID複製為SUID暫存;之後當進程完成不需特權的操作後,進程使用SUID的值重置EUID以重新獲得特權。
文件系統用戶ID File System UID, FSUID 在Linux中使用,且只用於對文件系統的訪問許可權控制,在沒有明確設定的情況下與EUID相同(若FSUID為root的UID,則SUID、RUID與EUID必至少有一亦為root的UID),且EUID改變也會影響到FSUID。設立FSUID是為了允許程式(如NFS伺服器)在不需獲取向給定UID賬戶發送訊號的情況下以給定UID的許可權來限定自己的文件系統許可權。

訪問文件

舉例而言,假設我要執行以下命令,sudo vim /etc/apt/sources.list,我當前的用戶是wang,那麼這個這個進程的RUID就是1000(對應wang這個賬戶),而sudo指使使用root許可權,因此該進程的EUID就是0root賬戶)。我們查看/etc/apt/sources.list文件的所有者和所有組,它的所有者是root,組是root。因此我們必須使用sudo進行提權,也即是修改進程的EUID0,這樣才能夠訪問/etc/apt/sources.list文件,但是RUID依然是1000

創建文件

再舉例創建文件。如下圖所示:
image_193
文件的所有組和所有者依然與進程的EUID和EGID指定,而非RUID和RGID。

父子進程

子進程繼承了父進程所有的各種UID和GID。

許可權控制

這裡描述的許可權控制是指Linux中基於用戶和用戶組以及r\w\x許可權的控制,其中r表示可讀,w表示可寫,x表示可執行。

Linux一般把文件存取的身份分為三個類別:owner/group/others,且三種身份都各有read/write/execute許可權。

查看/etc/shadow的詳細資訊如下圖所示:
image_194
分析如下:

許可權 鏈接數 所有者 所有組 文件大小 文件最後被修改的時間 文件名
-rw-r—– 1 root shadow 1.6K May 9 2021 /etc/shadow

對許可權進行詳細分析如下,每個文件的許可權都有10個字元表示,其中-表示無對應許可權,這十個字元可分為四組,第一組就是第一個字元;表示文件類型,第二組就是第2、3、4個字元,是所有者擁有的許可權,依次是r/w/x;第5、6、7個字元表示組許可權,依次是r/w/x;第8、9、10個字元表示其他人的許可權,依次是r/w/x。如果所在位置為-,則表示無對應許可權。

對應上述/etc/shadow文件的許可權為,所有者即root擁有讀寫許可權,組shadow只有讀許可權,其他人沒有任何許可權。

rwx與421

在Linux系統中,可以使用chmod命令來改變文件的許可權,例如:sudo chmod 640 /etc/shadow。這個含義就是將文件/etc/shadow的所有者許可權改為6即rw;組許可權改為4即r;其他人許可權改為0即無任何許可權。之所以6表示rw,4表示r,這是因為Linux是通過位來表示許可權的。

因為文件擁有三種不同的許可權r/w/x,Linux就使用3bit作為許可權記錄,如果是只讀的那麼就是100,如果是只寫的就是010,如果是只可執行的就是001,可讀可寫的呢就是110啦。讀者自行將二進位轉換為十進位,就會發現6就表示110,也就是可讀可寫不可執行的意思啦。

當然,這裡描述的3bit許可權位並不是實際上Linux的許可權實現機制,而是為了讀者方便理解記憶,數字與許可權的對應關係。實際的許可權記錄比較複雜。

關於許可權的一些問題

  1. 一個文件可有隻寫許可權但是不可讀嗎?
    答案是可以的,如下圖所示。
    image_195

  2. 一個文件不具有可執行許可權就一定不可執行嗎?有了可執行許可權就一定可以執行嗎?
    答案是不一定。
    image_196
    image_197

  3. 目錄的rwx

  • 目錄的只讀訪問不允許使用cd進入目錄,必須要有執行的許可權才能進入。
  • 只有執行許可權只能進入目錄,不能看到目錄下的內容,要想看到目錄下的文件名和目錄名,需要可讀許可權。
  • 一個文件能不能被刪除,主要看該文件所在的目錄對用戶是否具有寫許可權,如果目錄對用戶沒有寫許可權,則該目錄下的所有文件都不能被刪除,文件所有者除外
  • 目錄的w位不設置,即使你擁有目錄中某文件的w許可權也不能寫該文件

進程UID與文件許可權類型的匹配

根據前文我們已經知道,對文件的訪問和創建等操作需要檢查的都是EUID,而不是RUID。即使RUID是普通用戶,而EUIDroot則就擁有了對root所能訪問的所有文件的許可權。對應/etc/shadow我們就檢查對應的root許可權是讀寫,因此該進程就可以對/etc/shadow進行讀寫操作。如果,該進程的EUID不是root,但是是屬於shadow組的,那麼就只有讀許可權,否則沒有任何許可權。

Set-UID提權[2]

在一個典型的電腦系統中,用戶需要使用超級用戶的許可權來完成諸如修改密碼的操作。一種方式是通過守護進程(Windows下成為服務)方式來實現,另一種方式是通過設置Set-UID許可權的方式來實現。

Set-UID程式和其他unix程式唯一的區別就在於他有一個特殊的標誌位:Set-UID比特位。使用這個比特位的目的是告訴作業系統,當運行這個程式時應當與未設置該位的程式相區分。

我們在前文中提過,許可權匹配是通過EUID來實現的。對於非Set-UID程式而言,進程的EUID是和RUID一致的,當它被一個用戶ID為5000的用戶運行時,RUIDEUID都是5000。而當執行一個Set-UID程式時,RUIDEUID的值是不一樣的,RUID的值取決於執行該程式的用戶ID,而EUID則取決於Set-UID程式文件的所有者。

設置Set-UID

image_198

提權測試

image_199

ACL(Access Control List)規則

前文所述的規則又稱為UGO(user,group,others)規則,這套機制比較簡單。在自主訪問控制中,還有ACL規則,作為補充。在Linux系統中,ACL用於設定用戶針對文件的許可權。

ACL主要有兩種命令進行控制,getfaclsetfacl

# 例子源於//blog.csdn.net/pwl999/article/details/110878563
[root@localhost ~]# useradd zhangsan
[root@localhost ~]# useradd lisi
[root@localhost ~]# useradd st
[root@localhost ~]# groupadd tgroup
// 添加需要試驗的用戶和用戶組,省略設定密碼的過程
[root@localhost ~]# mkdir /project #建立需要分配許可權的目錄
[root@localhost ~]# chown root:tgroup /project/
// 改變/project目錄的屬主和屬組
[root@localhost ~]# chmod 770 /project/
// 指定/project目錄的許可權
[root@localhost ~]# ll -d /project/
drwxrwx--- 2 root tgroup 4096 1月19 04:21 /project/
// 查看一下許可權,已經符合要求了
// 這時st學員來試聽了,如何給她分配許可權
[root@localhost ~]# setfacl -m u:st:rx /project/
// 給用戶st賦予r-x許可權,使用"u:用戶名:許可權" 格式
[root@localhost /]# cd /
[root@localhost /]# ll -d project/
drwxrwx---+ 3 root tgroup 4096 1月19 05:20 project/
// 使用ls-l査詢時會發現,在許可權位後面多了一個"+",表示此目錄擁有ACL許可權
[root@localhost /]# getfacl project
// 查看/prpject目錄的ACL許可權
#file: project <-文件名
#owner: root <-文件的屬主
#group: tgroup <-文件的屬組
user::rwx <-用戶名欄是空的,說明是屬主的許可權
user:st:r-x <-用戶st的許可權
group::rwx <-組名欄是空的,說明是屬組的許可權
mask::rwx <-mask許可權
other::--- <-其他人的許可權

// 大家可以看到,st 用戶既不是 /prpject 目錄的屬主、屬組,也不是其他人,我們單獨給 st 用戶分配了 r-x 許可權。這樣分配許可權太方便了,完全不用先辛苦地規劃用戶身份了。

推薦閱讀

參考文獻


  1. 用戶ID–維基百科 ↩︎

  2. 杜文亮. 電腦安全導論:深度實踐[M]. 高等教育出版社, 2020. ↩︎