Linux 中的 Sticky Bit、SUID 和 SGID 示例

在本文中,我們解釋了對名為 Sticky bit、SUID 和 SGID 的文件和目錄起作用的特殊權限。

粘滯位僅適用於目錄。 如果用戶想在某個目錄中創建或刪除文件/目錄,他需要對該目錄的寫權限。 對目錄的寫權限賦予用戶創建文件的權限以及刪除文件的權限。

/tmp 目錄是臨時文件/目錄的目錄。 該目錄擁有所有三個級別的所有權限,因為所有用戶都需要創建/刪除他們的臨時文件。 但是由於用戶對該目錄有寫權限,他們可以刪除該目錄中的任何文件。 該文件的權限對刪除沒有任何影響。

但是在目錄上設置粘滯位後,任何人都可以在其中創建文件/目錄,但只能刪除自己的文件。 不能刪除其他用戶擁有的文件。

粘滯位 – 如何查看和設置

你會注意到 t 標記添加到 /tmp 目錄,這意味著為此目錄設置了位。

$ ls -ld /tmp/
drwxrwxrwt 4 root root 4096 Aug 19 02:29 /tmp/

在 Linux 中,可以使用 chmod 命令設置粘滯位。 您可以使用 +t 標籤添加和 -t 標記以刪除粘滯位。

$ chmod o-t dir1
$ ls -l
total 8
drwxr-xr-x 2 root root 4096 Aug 19 03:08 dir1
$ chmod o+t dir1
$ ls -l
total 8
drwxr-xr-t 2 root root 4096 Aug 19 03:08 dir1

或者,

$ chmod 1777 dir1/
$ ls -l
total 8
drwxrwxrwt 2 root root 4096 Aug 19 03:08 dir1

注意:在 Unix 風格的操作系統中,sticky bit 有不同的用途,但我們不在這裡討論它。

什麼是 SUID 位以及如何設置它

當一個可執行文件運行時,它在執行它的用戶的所有權下運行。 這意味著當學生用戶運行 ls 命令時,相應的進程將在學生的所有權下運行。 SUID 位,也稱為設置用戶 ID 位,會覆蓋此行為。 如果在程序上設置了 SUID 位,則該程序將作為該文件的所有者運行,而不管是誰在執行它。

Linux 中的 passwd 命令設置了 SUID 位。

$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 23420 Aug 3 2010 /usr/bin/passwd

這可以在第三個權限字段中看到。 ‘s’ 代替 ‘x’ 表示設置了 SUID 位。 設置 SUID 位後,當普通用戶(比如學生)運行 passwd 命令時,該命令以“root”的所有權運行,而不是作為學生運行,因為 root 是該文件的所有者。 此行為是必需的,因為密碼存儲在 /etc/shadow 文件中,該文件沒有組或其他級別的權限。

$ ls -l /etc/shadow
-r-------- 1 root root 1027 Jul 13 21:56 /etc/shadow

您需要了解出於安全原因,不能授予所有用戶對該文件的讀或寫權限; 否則,他們將讀取/更改其他用戶的密碼。 所以這就導致了一個問題,如果用戶沒有這個文件的權限,那麼他們將如何更改自己的密碼? 所以SUID位解決了這個問題。 passwd 命令設置了SUID 位,所以當普通用戶執行這個命令時,他們以root 的所有權運行它,即passwd 命令的所有者。

如何設置和取消設置 SUID 位

需要注意的是,SUID 位僅適用於文件。 要在文件上設置 SUID 位,請使用 chmod 命令,如下所示

$ ls -l
total 8
-rwxr--r-- 1 root root 104 Aug 19 01:26 hello.sh
$ chmod u+s hello.sh
$ ls -l
total 8
-rwsr--r-- 1 root root 104 Aug 19 01:26 hello.sh

也可以使用更改權限的數字方法。 假設如果文件的正常權限是 744,那麼在設置 SUID 位後,這些將變為 4744。 SUID 位的值為 4。

$ ls -l
total 8
-rwxr--r-- 1 root root 104 Aug 19 01:26 hello.sh
$ chmod 4744 hello.sh
$ ls -l
total 8
-rwsr--r-- 1 root root 104 Aug 19 01:26 hello.sh

SGID Bit 如何處理文件和目錄

與 SUID 位不同,SGID 位對文件和目錄都起作用,但在這兩種情況下都有不同的含義。

關於文件:

對於文件,它與 SUID 位具有相似的含義,即當任何用戶執行設置了 SGID 位的文件時,它將始終以該文件的組所有權執行,而不管是誰在運行它。 為了 example, 文件 /sbin/netreport 設置了 SGID 位,這可以在組權限中的“s”而不是“x”中看到。

$ ls -l /sbin/netreport
-rwxr-sr-x 1 root root 6020 Oct 13 2010 /sbin/netreport

該文件具有根組的組所有權。 所以當一個用戶(比如學生)執行它時,相應的進程將沒有學生的組所有權,而是根組的所有權。

在目錄上:

現在讓我們談談目錄上的 SGID。 目錄上的 SGID 用於創建協作目錄。 要了解目錄上的 SGID 位,請考慮以下場景:

假設三個用戶 jack、jones 和 jenny 在某個項目上一起工作。 它們都屬於一個名為 javaproject 的組。 在項目過程中,他們需要共享與項目相關的所有文件。 他們都必須能夠看到彼此的文件。 這可以通過在組級別提供讀取權限來完成。 此外,假設用於項目的目錄是“/javaproject”。

這裡出現了一個問題,當一個文件被創建時,它屬於創建該文件的用戶的主要組。 因此,當不同的用戶在這個目錄中創建他們的文件時,這些文件將不具有 javaproject 組的組所有權。

我們針對我們的問題所做的是將/javaproject 目錄的組設置為javaproject 組,並在其上設置SGID 位。 當在目錄上設置 SGID 位時,在其中創建的所有文件和目錄都具有與該目錄關聯的組的組所有權。 這意味著在/javaproject 目錄上設置SGID 位後,在該目錄中創建的所有文件和目錄都將擁有“javaproject”組的組所有權。 此外,此行為是遞歸的,即在此目錄中創建的目錄也將設置 SGID 位。 新目錄的權限也將與 /javaproject 目錄的權限相同。

可以使用 chmod 命令設置 SGID 位,如下所示:

$ ls -ld /javaproject
drwxrwxr-x 2 root javaproject 4096 Aug 19 02:33 /javaproject
$ chmod g+s /javaproject
$ ls -ld /javaproject
drwxrwsr-x 2 root javaproject 4096 Aug 19 02:33 /javaproject

現在當 jones 用戶在這個目錄中創建一個文件時,它是在 javaproject 組的組所有權下創建的。

$ touch /javaproject/jones1.txt
$ mkdir /javaproject/jones1dir
$ ls -l /javaproject/
total 12
drwxrwsr-x 2 jones javaproject 4096 Aug 19 02:38 jones1dir
-rw-rw-r-- 1 jones javaproject 0 Aug 19 02:37 jones1.txt

SGID 位對應的數值為 2,因此要以數字方式添加 SGID 位,請使用以下命令:

$ ls -ld /shared/
drwxrwxr-x 2 root adm 4096 Aug 19 02:47 /shared/
$ chmod 2775 /shared/
$ ls -ld /shared/
drwxrwsr-x 2 root adm 4096 Aug 19 02:47 /shared/

感謝您閱讀本文並參考 粘滯位維基頁面 以及。

另請閱讀:

  • 了解初學者的 Linux 文件權限