
我正在努力理解 SUID 位元的概念以及為何它們有用。
例如,假設我有一個程式:
-rwsr-xr-x 1 root root 12364 Jan 12 2013 /usr/bin/foo
我的理解是,s
使用者擁有者的in execute位元本質上意味著該檔案可以由具有檔案擁有者權限的其他使用者執行。
我為什麼想要這樣的東西?為什麼不直接更改文件的群組,以便它適用於所有使用者所屬的群組?
答案1
Setuid 和 setgid(以及 setcap(如果存在))是提升權限的唯一方法。除了透過這種機制之外,進程可以放棄特權,但永遠不會獲得它們。因此,您將無法執行任何需要額外權限的操作。
例如,程式su
需要sudo
能夠以任何使用者身分執行命令。因此,無論哪個使用者呼叫它們,它們都需要以 root 身分運行。
另一個例子是ping
。 TCP 和 UDP 套接字可供任何使用者訪問,因為這些協定有連接埠的概念,並且進程可以控制連接埠(這稱為綁定連接埠),因此核心知道將封包傳送到哪裡。 ICMP 沒有這樣的概念,因此只有以 root 身分執行(或具有適當功能)的程式才允許請求將 ICMP 封包分派給它們。為了讓任何使用者都能夠運行ping
,該ping
程式需要具有額外的權限,因此它是 setuid root(或 setcap)。
作為群組權限的範例,請考慮將本地高分儲存在檔案中的遊戲。由於只有使用者獲得的實際高分才應該儲存在分數檔案中,因此分數檔案必須是玩家不可寫入的。僅允許遊戲程式寫入分數檔。所以遊戲程式設為 setgid games
,且分數檔是組可寫的games
,但玩家不可寫。
還有一種提升權限的替代方法,就是從特權啟動程序啟動需要額外權限的程式。當使用者想要執行需要額外權限的任務時,他會執行一個前端程序,該程序使用某種形式的進程間通訊來執行特權操作。這對於某些用例來說效果很好,例如ping
(一個ping
解析選項和報告進度的程序,以及ping-backend
發送和接收資料包的服務),但不適用於其他用例,例如遊戲高分檔。
答案2
最常見的原因是可執行檔可以以 root 身分執行。例如:
find /bin/ -type f \( -perm -4000 -o -perm -2000 \) -ls | awk '{print $3,$NF}'
-rwsr-xr-x /bin/su
-rwsr-xr-x /bin/mount
-rwsr-xr-- /bin/fusermount
-rwsr-xr-x /bin/ping6
-rwsr-xr-x /bin/ping
-rwsr-xr-x /bin/umount
這些都是普通用戶可以運行但需要提升權限的命令。mount
是一個完美的例子,您可以安裝任何user
設定了類似選項的磁碟,/etc/fstab
但安裝需要root
特權,因此設定了 SUID 位元。
答案3
suid(或 sgid)位元使可執行檔以與呼叫它的使用者不同的使用者/群組運行。
如果這樣做的唯一原因是存取特定文件,是的,您可以使用其他機制使該文件可寫入。但是,用戶可以這樣做任何事物到文件 - 而不是僅您的程式允許的事情。
例如,您可以讓您的程式僅允許以某種格式向檔案追加一行。但如果您只使用檔案系統權限,使用者也可以從檔案中刪除行。或放入格式錯誤的行。
基本上,suid 程式可以強制執行任意策略。檔案系統權限不能。例如,您的系統有一個 suid 程式/bin/su
。它為您提供 root shell(例如),但前提是您首先滿足策略 — 通常需要輸入 root 密碼。僅憑權限是無法做到這一點的。