在之前的文章《理解基本的Unix文件權限》中,我們討論了為什麼基本的Unix權限系統對於安全性來說那麼重要,同時希望幫助讀者學會如何設置一般的Unix特權分離模式。之後,我們又講到了《通過adduser和umask 管理默認的Unix文件權限》。 當然,為了確保Unix系統安全,我們還要學習更多有關Unix文件權限系統的知識。
在提到高級Unix文件權限管理時,有兩個權限不得不提,那就是setuid以及setgid權限。之所以如此重要,是因為用好了這兩個權限,可以有效的提高系統安全性,但是對於初級管理員來說,能夠用好這兩個權限確實不容易。如果不夠細心,或者錯誤的使用了這兩種權限,將會給Unix系統帶來嚴重的安全風險。
每個進程都有兩種不同方法分類的UID。一種是“真實”UID,另一種是“有效” UID。 真實 UID是開啟進程的用戶賬戶的UID,有效UID是用戶特權附加到進程後的用戶UID。一般情況下,真實UID和有效UID是相同的,而setuid 和 setgid 權限允許你修改這個行為。
當用戶運行一個程序,實際上就是開啟了一個新的進程,用戶擁有這個進程,同時用戶的UID就是這個進程的真實UID。但同時這個程序也可以被其他用戶運行。比如root用戶可以通過命令行形式運行ls,其他用戶也可以運行這個程序。下面是root運行 ls -l 命令:
> ls -l /bin/ls
-r-xr-xr-x 1 root wheel 25312 May 1 2009 /bin/ls
正如我們在前一篇文章《理解基本的Unix文件權限》中說明的,這個輸出結果表示root用戶擁有ls,wheel是ls的組擁有者。同時該結果還顯示r-x 是root帳戶擁有者,組帳戶擁有者,以及所有其他用戶的權限。這意味著用戶 foo也可以讀取和執行ls命令。當用戶loo執行ls命令時,ls進程的擁有者就是foo,盡管之前root已經運行過ls。.
設置以上權限可以通過 chmod命令,如下:
> chmod 555 /bin/ls
(注:最好不要隨便修改你自己系統上的ls權限。任何一項修改都是在必要的情況下進行的。)
這是設置文件權限的最常見方法。另外,在555前面增加數字可以設置該文件的其它權限。添加數字4可以設置setuid權限。當然,盡管ls是root下危險性最低的程序,但是設置這個權限仍然是不明智的。本文中的修改只是為了做演示,大家不要效仿:
> chmod 4555 /bin/ls
修改後使用 ls -l 查看權限,將變成:
> ls -l /bin/ls
-r-sr-xr-x 1 root wheel 25312 May 1 2009 /bin/ls
setgid權限的設置方法相同,只是把數字4改成了數字2:
> chmod 2555 /bin/ls
這個修改和之前的setuid修改一樣,不同之處在於這裡修改的是組擁有者,而不是用戶賬戶擁有者的權限:
> ls -l /bin/ls
-r-xr-sr-x 1 root wheel 25312 May 1 2009 /bin/ls
如果想解除 setuid 或 setgid權限設定,可以使用數字0:
> chmod 0555 /bin/ls
不過使用這個0時一定要小心,如果要修改權限的文件或文件夾有“sticky bit”設置,就不能用0來去除setuid 和setgid權限。如果用ls –l命令查看文件,看到權限後面跟了一個“t”,就意味著該文件有“sticky bit”設置:
> ls -l / | grep tmp
drwxrwxrwt 18 root wheel 4096 Dec 16 00:00 tmp
sticky bit 不在本文討論的范圍,因此我們只需要記住,如果遇到了這種情況,就是用數字1來代替數字0,消除setuid 或setgid權限。在本例中,我們可以使用以下命令來改變ls-l權限:
> chmod 1777 /tmp
良好的安全性
在之前的文章《不安全的內存FAQ》中,setuid權限可以被用來提高特定環境的安全性。在GnuPG 環境,它可以用來確保程序可以使用安全內存,因為非特權UID無法訪問安全內存。使用安全內存可以讓攻擊者更難以從RAM中獲取你的GnuPG密碼。
在其他情況下,那些需要root級特權的服務器程序為了避免使用root級別的特權,也可以將其設置為setuid 權限,這樣它們以root特權啟動後會降低特權等級,以更低級的UID運行。這樣做可以確保服務器進程能夠按照原先所需的設定正常啟動,接下來放棄root特權的UID又能保證在接下來的運行過程中不會因為被攻擊而讓黑客獲取root權限。
不過在大多數情況下,你都不必手動設置文件的setuid或setgid權限。少數的幾個常用又需要設置setuid權限的程序實際上在它們安裝時就進行了自動設置。因此只有極少數的情況下需要我們設置setuid 或 setgid權限,但是要極為小心。
不佳的安全性
對於幾乎全部程序來說,設置setuid 位都會帶來少許安全風險。比如為ls設置setuid,將使得用戶可以訪問那些他原本沒有權利訪問的文件夾中的內容。
這就已經足夠引發更嚴重的結果了。比如,能修改文件系統的應用程序如果擁有了root權限,就可以修改任意文件系統了。如果某個程序被設置了setuid root權限,一旦這個程序被黑客掌握,系統中的重要文件就有可能被刪除,移動或者拷貝。
同樣糟糕的情況是為那些可以執行命令的程序設置權限。比如, Vim文本編輯器可以運行shell命令。如果Vim設置了setuid root權限,那麼就算是特權等級最低的普通用戶也可以用Vim通過shell方式以root用戶身份登錄。
正是出於以上有利或不利的原因,有些人覺得使用setuid 和 setgid權限有好處,而更多的人則選擇不同的方法達到同樣的效果。
首選方案
使用setuid 和 setgid的首選方案就是“不要使用它”。僅在極少的情況下,正確的使用這個權限,能起到提高系統安全性的作用,而更多情況下,使用setuid 或 setgid權限都將導致嚴重的安全問題。