對話 UNIX,第 4 部分: UNIX 所有權和權限管理
從大約 50 年前電子時代的開始直到 1977 年出現了 Apple 計算機,完成計算工作的硬件設備一直很缺乏,并且購買和運行它們也非常的昂貴。當時,這些(相對)原始的系統非常珍貴,僅僅用來處理那些最復雜的問題。不同的項目之間必須競爭才能獲得機時,而最早的信息技術 (IT) 管理人員的任務是保持系統每天 24 小時、每個星期 7 天不間斷地進行工作。畢竟,每一秒的閑置都等于浪費金錢。
在理想的情況下,可以根據需要將這些浪費掉的 時間自動地分配給任何處于就緒狀態等待進行計算的任務。實際上,這正是分時 (time-sharing) 的基本思想(由 Robert Berner 在 1957 年提出)。在 Multics、RSTS/E 和后來的 Unix® 及其最新的變種中,都實現了分時或多任務,對計算機資源(CPU、輸入和輸出、以及內存)進行劃分,分配給多個等待執行的作業,使得看起來每個作業都獨占了計算機。可以在多任務大型機中附加一些虛擬終端,這樣每個終端都可以看作一臺個人計算機。
現在,您很可能擁有自己的 UNIX 計算機,或者與其他用戶共享功能更強大的多處理器系統。但無論是您的便攜式計算機、或者公共機房中的 UNIX 龐然大物,都可能需要進行同時訪問。UNIX 提供了健壯的工具和基礎結構,以便幫助您保護和共享信息。
本文介紹了用戶權限,特別是研究了如何對文件權限進行操作,以便對其他用戶限制或共享您的目錄和文件。如果您希望流暢地與 UNIX 進行對話,那么了解相關的權限是至關重要的。
ID 和 UID
在開始之前,讓我們來看看您使用的究竟是哪個用戶。在命令提示符處,輸入 whoami:
$ whoamistrike
我的計算機回答 strike,這是我的用戶名(即登錄時所使用的名稱)。您的 whoami 應該返回您的登錄名稱。
當然,您的用戶名是用戶 ID (UID) 的假名(pseudonym)。要查看您的 UID,可以輸入 id -u:
$ id -u501
在本示例中,我的 UID 為 501。
通常,盡可能地使用用戶名而不是 UID,因為用戶名易于閱讀和記憶。例如,如果您運行 ps uxf 命令以查看您的運行進程的列表,那么 ps 將顯示您的用戶名作為您的進程的所有者。
$ ps uxfUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDstrike 32346 0.0 0.1 6496 1832 ?S19:39 0:00 sshd: strike@pts/0strike 32347 0.0 0.1 2592 1476 pts/0Ss 19:39 0:00 _ -bashstrike 32358 0.0 0.0 2476 820 pts/0R+ 19:39 0:00 _ ps uxf
輸出結果中顯示了 3 個進程,分別是:一個 ssh 登錄進程,它產生了一個 bash Shell,而后者啟動了 ps 命令。類似地,如果您在自己的 home 目錄中運行 ls -alFG 以查看您的文件的所有者,那么將顯示您的用戶名而不是您的 UID。
通常,只有您可以中斷自己的任務。(當然,超級用戶 root 可以控制和操作所有的任務。)例如,joe(共享相同系統的另一個用戶)不能終止我正在運行的 Shell,即上面列表中的進程 32347:
$ whoamijoe$ kill -INT 32347-bash: kill: (32347) - Operation not permitted
其中,32347 是我的 Shell 的進程 ID,joe 可以通過運行 ps auxf 找到該信息。然而,因為該進程由我所擁有,所以 joe 不能終止它。與此相反,我當然可以結束自己的任何任務,如清單 1 所示。
清單 1. 結束自己的進程
$ ps uxf...strike 32347 0.0 0.1 2592 1488 pts/0Ss 19:39 0:00 _ -bashstrike 32733 39.5 0.0 1480 356 pts/0R19:50 0:01 _ yes$ kill -INT 32733$ ps uxf...strike 32347 0.0 0.1 2592 1488 pts/0Ss 19:39 0:00 _ -bash
在運行了 kill -INT 32733 之后,終止了進程 32733(yes 命令)。
盡管這是個比較簡單的概念,但嚴格的所有權和針對每個用戶的預置,這兩種特性使得 UNIX 遠比 Microsoft® Windows® 更加安全。
成員具有相應的權限
與您所啟動的作業一樣,您還擁有您所創建的目錄和文件。例如,在您的 home 目錄中運行 ls -alFG 命令和 $HOME 以查看您所擁有的內容,如清單 2 所示。
清單 2. 列出您在自己的 home 目錄中所擁有的內容
$ ls -alFG $HOME...-rw------- 1 strike 6175 Aug 25 07:03 .bash_history-rw------- 1 strike 567 Apr 20 2005 .bash_profile-rw------- 1 strike 1834 Apr 20 2005 .bashrcdrwx------ 2 strike 4096 Mar 8 10:54 .ssh/-rw------- 1 strike 9516 Aug 22 16:42 .viminfo-rw-r--r-- 1 strike 1529617 Jul 19 07:00 Archive.zipdrwxrwx--- 3 strike 4096 Aug 24 04:04 IBM/drwxr-xrwx 3 strike 4096 Jun 14 06:06 backups/...
UNIX 組中存在的問題
要在組中的所有成員之間共享文件,可以更改文件的組所有者,這是一種非常簡單的方法。例如,如果由您、jane 和 joe 組成了 scIEnce UNIX 組,并且您希望與這兩個用戶共享敏感的 nuclear.csv 數據文件,只需要將該文件的組所有者更改為 science 即可。
但是,如果 sam 和 bertha 也需要訪問該文件,而他們都不屬于 science 組,那又應該怎么辦呢?當然,您可以將這兩個用戶加到 science 中,但這樣做將允許他們訪問 science 組所擁有的所有 文件。
這是 UNIX 組實現中的一個局限性:一個文件有且只能有一個組所有者,而要實現復雜的共享方案通常會導致組的數目激增。(您可以為 joe、jane、sam 和 bertha 創建一個新的組,比如 jjsb。但是當 donald 也需要訪問時,又應該怎么辦呢?)
如果您需要使用復雜的訪問控制方案,可以考慮使用訪問控制列表 (ACL),許多 UNIX 實現都提供了這種機制。ACL 對標準的 UNIX 所有權模型進行了擴展,可以對每個用戶或每個組授予(或撤銷)特定的權限。ACL 就像是在門口設置了一個保鏢:可以讓您的伙伴、某些名流和經過篩選的客人進入,而將無業游民和其他烏合之眾拒之門外。
正如您看到的,我擁有我的 home 目錄中的所有目錄和文件。作為所有者,我可以刪除、重命名和移動我的任何文件和目錄,并且可以編輯我的任何文件。您對自己的文件(除非特別指明,這里的文件 同時表示文件和目錄)具有相同的權限。
另外,您可以決定與其他的用戶共享 您的文件。實際上,因為 UNIX 是一種多用戶系統,所以共享文件是該操作系統的基本理念之一。
除了特定的用戶所有者,每個文件和目錄還具有一個組 所有者。UNIX 組 只是一些用戶的集合,而您可以作為一個或多個組中的成員。使用 id 可以查看您的成員信息:
$ iduid=501(strike) gid=501(strike) groups=501(strike), 81(appserveradm), 79(appserverusr), 80(admin)
在我的系統中,我的主要組的組 id (GID) 為 501,該組名為 strike。我還屬于其他的 3 個組:
appserveradm
appserveruser
admin
在通常情況以及缺省情況下,您所創建的文件的組所有者為您的主要組,但是您可以將組所有者更改為您所屬的任何組。在您的 home 目錄中運行 ls -laF,可以顯示有關您的文件的更多信息,如清單 3 所示。
清單 3. 顯示有關您的文件的更多信息
-rw------- 1 strike strike 6118 Aug 27 21:59 .bash_history-rw-r--r-- 1 strike strike 567 Apr 20 2005 .bash_profile-rw-r--r-- 1 strike strike 1834 Apr 20 2005 .bashrcdrwx------ 2 strike strike 4096 Mar 8 10:54 .ssh/-rw------- 1 strike strike 9516 Aug 22 16:42 .viminfo-rw-r--r-- 1 strike strike 1529617 Jul 19 07:00 Archive.zipdrwxr-xr-x 3 strike strike 4096 Aug 24 04:04 IBM/drwxrwxr-x 3 strike admin 4096 Jun 14 06:06 backups/
注意: 清單 3 顯示了 ls -l 的典型輸出。清單 2 看起來有些不同,這是因為在前面的討論中出于簡化的目的,有意隱藏了組所有者的信息。您可以使用 -G 隱藏組所有者。
名為 backups 的目錄的組所有者為 admin,它將某些權限給予了組中所有的成員。同時,我的其他文件的組所有者為 strike。通常,一個用戶是他或她的同名組中的唯一成員,這個同名組有效地將訪問權限限制于該用戶。
細節內容
如果您回頭再看看上面的 ls 的輸出結果,您將注意到,每行內容的開頭有一個由 10 個字符組成的序列。每個字符都是一個開/關設置或位,后者表示了三類用戶(您本人、您的一個組和其他用戶)的某一種特定的權限。圖 1 顯示了每一位的用法。
圖 1. UNIX 文件的權限位
在圖 1 中:
起始位表示該文件是否為目錄(通常,起始位 表示該文件是否為特殊文件。如果該文件是特殊文件,起始字符 d 表示目錄、l 表示符號鏈接,等等)。這個設置是無法改變的。
接下來的三位(用藍色表示的)分別表示您 對該文件的讀、寫和執行權限。您可以禁用寫權限位,例如要防止刪除文件。(是的,要刪除一個文件,您需要寫權限。)
接下來的三位(用綠色表示的)表示組 對該文件的讀、寫和執行權限。
最后的三位(用橙色表示的)表示所有其他 用戶(即除了您自己以及您的組中的成員之外的所有用戶)的權限。
可以使用 ls -laF 的輸出作為示例查找上述內容:
只有我可以讀和寫 .bash_history、.bash_profile、.bashrc 和 .viminfo 文件。我可以查看、編輯和刪除這些文件。
只有我可以訪問 .ssh 目錄。第一位表示它是一個特殊的文件,d 表示目錄。我可以顯示該目錄中的內容,因為已經設置了它的用戶讀位。我可以在該目錄中添加和刪除文件,因為已經設置了它的用戶寫位。您可能奇怪為什么該目錄是用戶可執行的。除非設置了該位,否則無法遍歷目錄(進入目錄并列舉目錄)。(另外,正如本系列的第 3 部分中所提到的,您的 .ssh 目錄必須是您私有的,否則您的公鑰訪問無法正常工作。)
我可以讀和寫 Archive.zip 文件,并且其他用戶可以讀該文件。(當然,strike 組也可以讀該文件,但如果我是該組中唯一的成員,那么這個權限是沒有實際意義的。)
我可以列舉、讀和寫 IBM(另一個目錄)中的文件,而其他用戶可以列舉其中的內容。
最后,admin 組的成員和我可以列舉、讀和寫 backups 目錄中的文件,而其他用戶可以列舉和讀。
設置目錄的保護 (sticky) 位
如果您希望確保一個目錄持久,而不會被意外地刪除,那么可以使用 chmod +T 設置其保護 位。
$ ls -lFdrwxrwxrwx2 strike strike 68 Aug 28 06:21 dropbox/drwx------2 strike strike 68 Aug 28 06:21 mine/$ chmod +t dropbox$ ls -lFdrwxrwxrwt2 strike strike 68 Aug 28 06:21 dropbox/drwx------2 strike strike 68 Aug 28 06:21 mine/
設置保護位并將權限設置為所有用戶都可以讀、寫和執行,每個用戶都可以在 dropbox 目錄中放置文件,但只有我能夠刪除該目錄中的文件或該目錄本身。
如果您運行 ls -ld /tmp,這個用作應用程序臨時空間的系統范圍臨時目錄可能是保護的。
您可以使用 chmod(更改模式 change mode)命令修改相應的權限(除了目錄位之外)。您可以使用 chgrp(更改組 change group)命令來修改文件所屬的組。(超級用戶 root 也可以使用 chown 或 change owner 命令來更改文件所有權。)
下面是 chmod 的示例應用程序:
chmod u+x script.sh:如果您編寫了一個 Shell 腳本,并且希望執行它,那么需要設置其執行位。其中,短語 u+x 表示對用戶所有者 (u) 設置 (+) 執行位 (x)。chmod 的一般形式是 chmod,不指定用戶(即表示用戶)、一個或多個 u、g(表示組)、或 o(表示其他用戶),+ 或 -,以及一個或多個 r、w 和 x。
chmod go+rx IBM:這個命令為組和其他用戶設置了讀和執行權限。
chmod a+rx script.sh:除了 u、g 和 o 以外,您還可以使用修飾符 a 來表示所有用戶 或用戶、組和其他用戶。因此,這個命令為所有的三類用戶設置了讀和執行權限。
chgrp admin backups:這個命令將 backups 目錄的組所有者更改為 admin。
如果使用 + 添加權限,它將會添加指定的權限,但不會修改其他的權限。與之類似,如果使用 -(減號)撤消權限,它將會禁用某些權限,但不會修改其他的權限。如果您希望一次設置所有的權限,可以使用數值文件模式。(您還可以使用 chmod = 操作符。有關詳細的內容,請參見手冊頁面。)
注意: 數值文件模式 是從 0 到 7 的 8 進制數字,或三位的數值,其中每一位分別表示讀、寫和執行。因為對于每個文件都有三類用戶,所以完整地指定文件模式需要三個數字,如 400、644 或 777。下面提供了一些示例:
要讓一個目錄成為私有的,可以為自己設置權限,而撤銷組和其他用戶的權限:
$ mkdir example$ ls -ldrwxr-xr-x2 strike strike 68 Aug 28 11:27 example$ chmod 700 example$ ls -ldrwx------2 strike strike 68 Aug 28 11:27 example
模式 700 可以表示為用戶設置讀、寫和執行權限(開頭的 7),而禁用所有其他的權限(后面的兩個 0)。
如果您希望讓該計算機上其他的用戶可以讀取您的文件,可以為所有的三類用戶設置讀權限:
$ ls -l .aliases-rw------- 1 mstreich mstreich 79 Jul 26 17:08 .aliases$ chmod 644 .alias$ ls -l-rw-r--r-- 1 mstreich mstreich 79 Jul 26 17:08 .aliases
644 是一種縮寫,它表示為我設置讀和寫權限 (6),并為組 (4) 和其他用戶 (4) 設置讀權限。當然,如果您的 home 目錄中存在 .aliases 文件,那么必須將 $HOME 設置為允許列舉和讀。
表 1 給出了用戶所有者、組所有者和其他用戶的數值及其關聯的結果。只需在每個部分中加上相應的值,就可以找到合適的值進行設置。
表 1. 數值及其關聯的結果
某類用戶值結果用戶0400允許所有者讀。0200允許所有者寫。0100對于文件,允許所有者執行,對于目錄,允許所有者在該目錄中進行搜索。組0040允許組成員讀。0020允許組成員寫。0010對于文件,允許組成員執行,對于目錄,允許組成員在該目錄中進行搜索。其他用戶0004允許其他用戶讀。0002允許其他用戶寫。0001對于文件,允許其他用戶執行,對于目錄,允許其他用戶在該目錄中進行搜索。
例如,要為其他用戶設置讀和寫權限,可以將 0004 加上 0002 以產生 0006。對于用戶和組,可以進行類似的操作,可以將三個總數加在一起,以產生完全限定的數值模式。
權限是非常重要的
在 UNIX 系統中,需要不斷地設置和管理相關權限。通常,您需要對特定文件和目錄具有適當的權限,以便運行一些守護進程;只有設置了正確的權限,這些目錄(如 /tmp)才能正常工作;當然,要與其他用戶共享某些文件,或保護您的文件不讓其他用戶訪問,必須能夠設置、更改和讀取相應的權限。
本系列中的下一篇文章將繼續介紹文件,并研究在多臺計算機上對大量的文件進行管理的實用程序和技術。
相關文章: