Linux 权限

      对于linux权限在Linux学习中一直是一个繁琐的问题,经常会遇到访问拒绝之类的问题,以至于你的网站无法访问。在这里希望有心人仔细看下去......用 ls 命令之後﹐您會看到目錄內容會以行列的形式列出來﹐不過﹐除非您原先就知道它們是什麼﹐否則您也看不出究竟哪一個是目錄﹐哪一個是檔案(不過﹐現在的 Linux 會用不同的顏色來表示不同的檔案﹐這樣也直觀多了)。如果您需要更詳細的信息﹐可以加上 -l 的參數﹕

ls -l

(本文章部分来源于网上,感觉内容写的比较精炼,所以就挪用了一部分)

這時後﹐您會看到這樣的結果﹕

-rw-r--r--   1 root  root   103 Oct 27 22:09 test.ls
-rw-r--r--   1 root  root   103 Oct 27 22:37 test.ls.copy
lrwxrwxrwx   1 root  root     7 Oct 27 22:37 test.ls.ln -> test.ls
drwxr-xr-x   2 root  root   024 Oct 27 22:37 test1-1   

這裡﹐我們得到的信息明顯多了許多。首先讓我們看看第一列的意思﹕在句子開頭共有10 字母空位可提供檔案的一些屬性信息。第一個如果是‘-’的話﹐表示這是一個常規檔案﹐如果是‘d’的話表示這是一個目錄﹐如果是‘l’的話﹐表示這是一個 link﹔接著其後的 9 個字母﹐分為三組﹕分別是分配給‘user (擁有者)’﹑‘group (群組)’﹑和‘others (其他使用者)’這三個不同使用者群的權限﹔而其中每一組使用者可以擁有這些權限﹕‘r’表示 readable (可讀)﹑‘w’表示 writable (可寫)﹑和‘x’表示 executable (可執行)。

跟著是一個數字﹐是關於這個檔案的 hard link 數目。目前為 1 ﹐也就是說它只有一個 hard link 而已﹐也就是最後一個。如果這個檔案被刪除掉﹐那麼它所佔據的磁碟空間就會釋放出來。

接下來我們看到 root root 這兩列﹐分別表示‘user’和‘group’是誰。user 會是系統的其中一個使用者﹐通常是建立這個檔案的使用者﹐而 group 則是該 user 所屬的群組。通常﹐一個 group 可以包括好些 user 在內﹐同時﹐一個 user 也可以從屬於好幾個 group 之中。無論是 user 或 group﹐都必須由系統管理員來建立或刪除。

至於再後面數列﹐是檔案的一些資料﹕大小和修改日期﹐最後則是檔案名稱。

那麼﹐我們看看第一行﹕

我們可以獲得這樣的信息﹕首先﹐這是一個檔案﹐它的擁有者 root 對這個檔案具備‘讀(r)’和‘寫(w)’的權限﹐而屬於 root 這個群組的組員﹐都只具備‘讀(r)’的權限﹐其他的使用者也只具備‘讀(r)’的權限。

當您得到一個檔案的時候﹐會根據您目前的身份(可以用 id 命令查詢)來判定您對該檔案擁有的權限。如果您就是該檔案的擁有者﹐那您就獲得 user 相關的權限﹔如果您不是它的 user﹐那麼看您是否屬於這個 group 裡面﹐然則您就獲得 group 的權限﹔如果您既不是 user﹐也不在 group 裡面﹐那您就獲得 others 的權限了。

我們這裡看到的權限設定為內建值﹐也就是該檔案被建立起的時候就是這樣設定的了。不過﹐我們可以改變這些設定哦~~~﹐下面讓我們輸入這幾個命令﹕

chmod u+x test.ls
chmod g+wx test.ls
chmod o+x test.ls

或是合為一句﹕
chmod u+x,g+wx,o+x test.ls

這個 chmod 命令是 change mode 的意思﹐第一行是為 user 增加 x 權限﹐第二行是為 group 增加 w 和 x 權限﹐而第三行則是為 others 增加 x 權限﹐如果您這時候再使用 ls -l 的話﹐您會看到 test.ls 的權限會變成﹕rwxrwxr-x 這樣的權限值了。我們使用“+”來增加權限﹐如果使用“-”是刪除權限﹐如果使用“=”則是指定權限值。不過﹐您是否覺得這樣輸入命令很麻煩呢﹖有沒用更方便的辦法啊﹖答案是﹕有的﹗現在﹐請您輸入這樣的命令﹕

chmod 777 test.ls

您會看到test.ls的權限會變成﹕rwxrwxrwx﹐也就是所有使用者都具備所有權限了﹐因為我們給每一個使用者群都賦予‘7’這個數值﹐它分別是﹕1(x)+2(w)+4(r)的總和﹐如果是‘0’的話﹐就表示沒用任何權限。但事實上﹐權限值並的真正計算方法是以二進位進行的﹕

先讓我們看看 x,r,w 的 bit 位元表示方式﹕

x: 001
w: 010
r: 100

如果將全部位元做 OR 運算就是最終 permission﹕rwx 的位置都是 111 ﹐換成十進位就是 7 了。

 

下面您如果輸入﹕

chmod 750 test.ls

您會發現權限會變成﹕rwxr-x---﹐至於為什麼會如此﹐不妨算算看﹕

1) 將 750 換成二進位﹐就是﹕111,101,000
2) 分別將 rwx 的位置代入得﹕rwx,r-x,---
(方法﹕1 對應著的權限就打開﹐0 對應的就關閉)

就這麼簡單 ^_^

 

好了﹐我們剛纔已經會得計算自己對一個檔案擁有什麼樣的權限﹐也知道如何改變檔案的權限設定。但是﹐檔案被建立的時候﹐預設會獲得怎樣的權限呢﹖這個值就要靠 umask 來決定了。如果您現在輸入 umask﹐會得到 022 的值﹐這個值決定了檔案在建立的時候﹐要拿掉什麼樣的權限。在沒有使用 umask 的時候﹐所建立的檔案都是 777 這個值的﹐但當運用了 umask 之後呢﹐目錄會變為 755﹐而檔案則為 644 。那是怎麼得出來的呢﹖還是回到二進位吧﹐然後將完整權限和 umask 進行 NOT 和 AND 運算﹐就是最後的權限值。

在建立目錄的時候﹕
1) 首先﹐我們先對 unmask 進行 NOT 運算﹕
000,010,010 的 NOT 運算結果是﹕111,101,101 ﹔
2) 然後再和 777﹐也就是﹕111,111,111 進行 AND 運算﹔
3) 最後﹐我們會得到這樣的結果﹕111,101,101 ﹔
換成十進位就是 755。

而至於檔案的建立﹕
預設會把它的 x (001) 拿掉﹐其實也是先進行 NOT + AND 運算﹕
1) 先對 x 做 NOT 運算﹕001 NOT ==> 110
2) 然後和 111 做 AND 運算﹕
111,111,111
110,110,110  AND
-----------------
110,110,110      ===> 也就是 666﹐ 然後再和 umask 022 做 NOT 跟 AND 運算﹕
111,101,101  AND
-----------------
110,100,100      ===> 換成十進位是 644 ﹐這才是真正的結果。

 

我們的 umask 值是登入的時候﹐由 shell 的 profile 分配的(一般規則是:user 與 group 同名為 022﹐否則是 002)﹐我們可以在任何時候改變這個值﹕用 umask 命令以新的值作參數就可以了﹐如﹕umask 002 ﹐然後新建立的檔案就變成 664 的權限了。

tips﹕如果您不習慣用二進位進行計算﹐只能用十進位來算的話﹐可以簡單的這樣算﹕
目錄是用 777 扣掉 umask 的值﹔
檔案是用 666 扣掉 umask 的值。

 

不過﹐電腦上面真正的運算是二進位啦﹐這個和我們計算 IP subnet 的時候是一樣的原理。

不信﹖不妨用 033 的 umask 玩玩 ﹐看看會產生什麼樣的權限呢﹖

 

此外﹐我們不但可以改變檔案的權限﹐還可以使用 chown 來改變 user 和 group (也可以使用 chgrp 來單單改變 group)﹕

chown user1.group1 test.ls

這命令通常由 root 來執行﹐用“.”(或 : )將擁有者和群組分隔開就可以了﹐當然﹐user 和 group 必須要事先被建立好了的。

權限對目錄和檔案的影響有時候不盡相同。r 和 w 應該一樣﹐都是可以進行讀取和寫入(或修改)﹐但 x 則不一樣了﹕ x 對目錄而言﹐是具有查找的能力﹔而對檔案而言﹐則是可執行程式。例如﹕當您要建立﹑讀取﹑寫入一個檔案(或子目錄)的時候﹐從 / 到當前目錄所經過的所有目錄﹐都必須有 x 權限﹐而當前目錄則按照不同的行為具備不同的權限﹕建立需要 wx﹑讀取需要 r﹑寫入需要 w 。

用 chmod 和 chown 來改變一個目錄權限的時候﹐如果加上 -R 參數﹐那麼﹐目錄裡面的檔案和子目錄﹐都會更著被修改。有時候會很方便﹐但也非常冒險﹗小心使用就是了。

tips﹕例如﹐有些朋友在架設網頁伺服器的時候﹐明明已經建立好目錄和網頁了﹐為什麼還不能顯示﹖這是因為伺服器通常以 nobody 身份來讀取檔案系統的﹐如果從 / 到您存放網頁的目錄之間﹐只要其中一個目錄﹐對 others 來說沒有 x 的話﹐那就讀取不到網頁了。所以﹐當找到哪一個目錄沒有 x 權限﹐通常用 chmod o+x 就可以解決問題。

 

或者﹐您會在其它一些 chmod 範例中會看到用 4 個數字來設定權限的﹐比方說﹕chmod 1777 /tmp 。您或許會好奇究竟第 4 個(從右往左)數字代表什麼意思呢﹖

非常好的問題﹗不過﹐在解釋這個數字之前﹐先讓我們再認識兩個概念﹕SUIDSGID 。UID 和 GID 您應該知道了吧﹖您執行 id 這個命令就可以看出來自己是的 ID 是什麼。當您在 Linux 系統上面執行一個檔案的時候(具有 x permission)﹐這個檔案所執行的程式﹐所具備的權限﹐就以執行者的 ID 為準﹕如果您是 root﹐那麼這個程式也是以 root 的權限執行﹔如果您是 user1﹐那就以 user1 的權限執行。但如果﹐一個執行檔還具有 SUID 屬性的話﹐那這個程式所具有的權限﹐就不是命令的執行者﹐而是檔案的擁有者﹕如果一個檔案具備 SUID 屬性﹐它的 user 和 group 都是 root﹐而且 others 也具有 x 權限﹐那麼﹐當 user1 執行這個檔案的時候﹐程式所具有的權限就不是 user1 而是 root﹗同樣﹐如果 SGID 也打開了﹐那麼這個程式也具有檔案之 goup 群組相同的權限。

這樣的設計﹐是讓一些普通使用者以檔案擁有者的權限去執行某些程式。例如﹕某些程式﹐如 passwd (您不妨輸入 ls -l /usr/bin/passwd 看看)﹐需要寫入檔案系統中使用者本身不能存取的位置(如 /etc/shadow)﹐如果沒有 SUID 和 SGID 屬性﹐那這樣的設計是沒辦法做到的。不過﹐這樣的設計﹐也同時帶來了系統上的安全威脅。比方說﹕系統被植入一個擁有者為 root 的後門程式﹐它能抓取只有 root 才能讀取的密碼檔案。如果在沒有 SUID 的情況之下﹐就算是一般用戶執行它﹐也沒辦法達到目的﹐因為程式只具備一般用戶的身份而已﹔但如果這個程式有設定 SUID﹐就算一般用戶執行它﹐也能得逞﹗

有鑒於此﹐在我們使用的 shell script (我們後面再介紹)﹐預設上是取消 SUID 和 SGID 屬性的﹐就算您設了﹐shell 也不會執行它就是了。那麼﹐您或許會問﹕我們如何設定 SUID 和 SGID 呢﹖呵呵~~ 就是剛纔我們提到的 chmod 的第 4 個數字了﹕如果是 4 就是 SUID﹔如果是 2 就是 SGID﹔如果是 1﹐則為檔案設上一個特殊標籤﹕sticky bit (黏著位元)﹐當這個標籤打開的時候﹐只有檔案的擁有者才能刪除這個檔案(root 除外)﹐其它使用者就算具有 w 的權限﹐也只能修改檔案的內容﹐而不能將檔案刪除。如果一個目錄具有這個位元﹐那麼其下所建立的檔案﹐也具有這個屬性。

讀者不妨參考 Edward 兄的說明﹕

Edward G.J. Lee  wrote in message news:3g6A8i$GfM@bbs.ee.ntu.edu.tw...
> : > 請問chmod 指令中的特殊權限(SetUID、SetGID、sTicky)有何作用????
> : suid 應該是執行該程式,該程式會擁有其擁有者的權限。
> : 例如 aaa 擁有者是 root,而有 suid 權限,則執行它時,aaa 會擁有 root 的權限。
> : 如果此時 aaa 進行的動作是 rm -rf /,就爽了。  ~:Q
> : sgid 比較不清楚,意義類似?
> [...]
> 
>   對目錄而言,setuid 是沒有意義的,而 setgid 則會在該目錄下開檔時
>   擁有與該目錄相同的 group。
> 
>   對檔案而言,就比較複雜,非 script 的可執行檔如上述的作用,會轉變
>   身份為檔案擁有者或檔案群組。非可執行檔,則 setuid 沒有意義,但
>   setgid 則牽涉對該檔案的鎖定都是 mandatory locking 的作用,而非
>   advisory locking。
>   * 請參考:/usr/src/linux/Documentation/mandatory.txt。
> 
>   sticky bit 對檔案而言,在 Linux 是沒有作用的,會被忽略。
> 

 

事實上﹐您除了可以設定檔案的權限( permissions ) 之外﹐還可以設定檔案的屬性( attributes )。和 chmod 命令一樣﹐您可以使用 chattr 命令來改變一個檔案或目錄的屬性。常用的屬性大概有這些﹕

屬性 代表意思
a 在寫入的時候﹐只能延增﹐不能刪除現有內容。
c 核心會自動執行壓縮。
i 不能刪除﹑移動﹑link﹑寫入。
s 檔案刪除時﹐磁碟空間也會清理乾淨。
S 修改時直接寫入磁碟﹐而不是寫在 buffer 中。

善於運用檔案的屬性設定﹐可以更好的確保檔案的使用習性。例如﹐您或許不希望任何人修改 /bin 和 /sbin 裡面的檔案 (因為木馬程式通常都會修改那裡)﹐那您可以執行﹕

chattr +i /bin /sbin

然後﹐您試試在 /bin 和 /sbin 裡面新增或刪除檔案﹖應該不會成功的﹗如果您要看檔案或目錄的屬性﹐可以用 lsattr 命令﹕

lsattr -d /bin /sbin

如果拿掉 -d 就是看一般的檔案(和 ls 命令一樣)。而至於具體的屬性有哪些呢﹖您可以用 man chattr 來了解。