使用者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與賬戶名的對應關係:
從上圖中我們可以看到,我的使用者名稱是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
就是0
(root
賬戶)。我們檢視/etc/apt/sources.list
檔案的所有者和所有組,它的所有者是root
,組是root
。因此我們必須使用sudo
進行提權,也即是修改程式的EUID
為0
,這樣才能夠訪問/etc/apt/sources.list
檔案,但是RUID
依然是1000
。
建立檔案
再舉例建立檔案。如下圖所示:
檔案的所有組和所有者依然與程式的EUID和EGID指定,而非RUID和RGID。
父子程式
子程式繼承了父程式所有的各種UID和GID。
許可權控制
這裡描述的許可權控制是指Linux中基於使用者和使用者組以及r\w\x
許可權的控制,其中r
表示可讀,w
表示可寫,x
表示可執行。
Linux一般把檔案存取的身份分為三個類別:owner/group/others
,且三種身份都各有read/write/execute
許可權。
檢視/etc/shadow
的詳細資訊如下圖所示:
分析如下:
許可權 | 連結數 | 所有者 | 所有組 | 檔案大小 | 檔案最後被修改的時間 | 檔名 |
---|---|---|---|---|---|---|
-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的許可權實現機制,而是為了讀者方便理解記憶,數字與許可權的對應關係。實際的許可權記錄比較複雜。
關於許可權的一些問題
-
一個檔案可有隻寫許可權但是不可讀嗎?
答案是可以的,如下圖所示。
-
一個檔案不具有可執行許可權就一定不可執行嗎?有了可執行許可權就一定可以執行嗎?
答案是不一定。
-
目錄的rwx
- 目錄的只讀訪問不允許使用cd進入目錄,必須要有執行的許可權才能進入。
- 只有執行許可權只能進入目錄,不能看到目錄下的內容,要想看到目錄下的檔名和目錄名,需要可讀許可權。
- 一個檔案能不能被刪除,主要看該檔案所在的目錄對使用者是否具有寫許可權,如果目錄對使用者沒有寫許可權,則該目錄下的所有檔案都不能被刪除,檔案所有者除外
- 目錄的w位不設定,即使你擁有目錄中某檔案的w許可權也不能寫該檔案
程式UID與檔案許可權型別的匹配
根據前文我們已經知道,對檔案的訪問和建立等操作需要檢查的都是EUID
,而不是RUID
。即使RUID
是普通使用者,而EUID
是root
則就擁有了對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的使用者執行時,RUID
和EUID
都是5000。而當執行一個Set-UID程式時,RUID
和EUID
的值是不一樣的,RUID
的值取決於執行該程式的使用者ID,而EUID
則取決於Set-UID
程式檔案的所有者。
設定Set-UID
提權測試
ACL(Access Control List)規則
前文所述的規則又稱為UGO(user,group,others)規則,這套機制比較簡單。在自主訪問控制中,還有ACL規則,作為補充。在Linux系統中,ACL用於設定使用者針對檔案的許可權。
ACL主要有兩種命令進行控制,getfacl
和setfacl
。
# 例子源於https://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 許可權。這樣分配許可權太方便了,完全不用先辛苦地規劃使用者身份了。
推薦閱讀
參考文獻
杜文亮. 電腦保安導論:深度實踐[M]. 高等教育出版社, 2020. ↩︎