Unix許可權這點事

目錄

用戶和組

現實生活中的例子

文件的許可權

進程中的許可權

會員可以真正操控別人的替身

運行過程中變換身份

正文

Unix/Linux的許可權管理還是比較複雜的,別人說看高級環境編程得看2,3遍。我想這應該是在Linux有了一定基礎。我看的過程中覺得需要反覆推敲,有些地方得翻來覆去看上5,6遍甚至更多,下面是自己的一些對Unix許可權的理解,盡量翻譯成了大白話。如果有不對的地方,歡迎討論。

回到頂部

用戶和組

現實生活中的例子

關於用戶和組,對比現實生活中的例子。Linux系統好比一個大型的圖書館,裡面存放著各種書籍,文件和一些演示設備(像天體運行動態演示設備等等),還有電腦,普通人想進入圖書館進行學習必須註冊(useradd)為為會員(User),成為會員後圖書館管理員(root)會給會員發送門禁卡(password),會員進入圖書館刷門禁卡即可。會員在圖書館內可以閱讀書籍(read),也可以觸發演示設備,操作電腦(run)來進行學習。這些書籍,文件和設備的擁有者(owner)都是管理員,會員的許可權由管理員指定。另外,會員是可以在書籍中記(write)筆記的,但要獲得管理員的許可。

Advertisements

用戶

這個圖書館比較特殊,會員可以把屬於你自己的書籍,甚至電腦放(create)到圖書館中,會員自己的書籍可以自己決定是否有讀(read)和寫(write)的許可權,可以決定自己的電腦自己是否是可執行(run)的。既然會員把圖書和設備放到了圖書館中,管理員有權對這些書籍和設備進行讀寫和執行。

好了,總結一下,現在圖書館中的各種書籍和設備的擁有者分成兩類,一類是管理員,一類是會員。會員是管理員發放了門禁卡之後才能進入。到這裡你發現沒發現一個問題,一個會員的書籍只能夠給兩個人看,一個人是他自己,另一個是管理員。這樣的話就浪費了圖書館的資源,如今都講究共享,共享單車,共享充電寶,共享經濟(這個概念已經很老舊了,Linux/Unix中已經使用了這個概念)。。

Advertisements

如何才能解決資源共享的問題呢?共享也不是隨意共享的,有些會員的資源可能只願意給自己認識的人看,有的願意認識的人在自己的書籍中記筆記;有的人願意自己的資源只給對其感興趣的人讀和寫;而有的願意給所有人讀和寫。為了達到這種精確控制。管理員創建了一個規則:設定組(group)。管理員可以創建(groupadd)一個組,普通會員在獲得管理員許可后(sudo)也能創建組。

例如:會員A,B,C,D達成共識,咱們創建一個組吧,以後四個人的資源就可以自由共享了,於是他們向管理員申請創建組adGroup,管理員親自創建(groupadd)或者授權給(sudo groupadd)其中某一個人創建。創建完成之後把四個人加入(usermod)這個組即可。以後其他人可以申請加入這個組。一個人可以同時加入多個組。這裡會有個問題,既然一個人可以屬於多個組,那麼一個用戶往圖書管理放一本書,為這本書設置組許可權的時候,設置的許可權是哪個組的呢,好吧,我們首先設置一個默認組,會員進入圖書館的時候,拿進去的書籍開始都是屬於默認組(有效組)的,其餘的組叫做附屬組,可以把附屬組修改為當前有效組(newgrp)。書籍放到圖書館之後,所屬組就會記錄下來,這個組可以由書籍所有者修改(chgrp),修改之後,這本書的組許可權就變成新組的許可權了。

接著上面說,四個會員可以分別指定屬於自己資源的組許可權,會員A的書籍bookA屬於組adGroup,他可以指定屬於這個組的用戶可以讀寫。會員B有潔癖,他的書籍bookB屬於組adGroup,他只給組許可權設為只讀。會員C突然發現自己的書籍中藏有寶藏密碼,立即關閉了組讀寫許可權,和管理員一起研究寶藏密碼去了。。。

其它

我們看一下接下來的場景,會員E自己出了一本書,為了宣傳自己的新作,他想儘可能快的讓儘可能多的人看到這本書,並且得到反饋,他把這本書放到了圖書管,他加入了所有組,把這本書的所屬組設置為人數最多的一個組,並把組許可權設置為讀寫。看到沒有,儘管他加入了所有組,他的一本書籍只能為一個組設定組許可權。他有兩個選擇:

讓其它所有人加入最大的組,但是現在作者知名度不高,是你在做宣傳,誰會鳥你啊。

統計一下組的數量N,拿N本書到圖書館,每本書指定一個組,開放所有組的讀寫許可權。但是有個問題,以後有新創建的組改怎麼辦?

會員E的這種情況,我們給出一個解決方案,再加入一種特殊的組,況且這麼叫吧,就是其它(others),它能夠設定不在資源所屬組內會員的許可權。也就是其他人的許可權。上面的問題迎刃而解,E不用再加入每個組了,也不用特定把書所屬到人數最多的組,只需要把組許可權和其他許可權設為讀寫即可。

回到頂部

文件的許可權

繼續圖書館的例子,書籍是一個文件,我們已經知道的有關這個文件的許可權的屬性包括:

文件所屬者(Owner)

文件所屬組(Group)

文件所有者的許可權(u rwx)

文件所屬組的許可權(g rwx)

其它人的許可權(o rwx)

還有其它的會在這一節裡面詳細說。看官們繼續吧。。

我們知道,書籍是放在書架上的,書架是放在某個具體的屋子內的,屋子是坐落在圖書館內的。會員找到一本書,先得進入圖書館(login),然後進入某個屋子(cd),找到某本書籍所在的書架(繼續cd),最後看到書籍,然後打開進行讀和寫。

為了方便管理,除了書籍和設備本身的讀寫和執行許可權之外,圖書館可能會指定一下規章制度:

這個圖書館歷史比較悠久,有很多珍貴的資料單獨存放在一個屋子內,管理者只想讓少數的人進入屋子內瀏覽資料,其它人不用說看這些書了,屋子都不會讓你進去。但是有可能會讓你知道屋子裡面有什麼。

為了保證圖書館內圖書的分類正確,管理員不可能隨隨便便就讓一個人把書籍放到一個書架上。當然也不會讓一個人隨隨便便就把書拿出圖書館。

為了達到這種效果,聰明的規則制定者想出了一個辦法,給屋子和書架也分配上面的5種許可權。我們暫且把屋子和書架稱作容器(folder)。

我們把會員和管理員可以執行的操作分成一下幾種:

向某個屋子新加一個書架(mkdir)(加屋子不太可能。。),挪走一個書架(rm)。

拿一本書進來(touch cp ….),拿一本書出去(rm..)。

瀏覽(ls)屋子內(書架上)的書籍名稱。

讀寫(vim cat..)一本書籍,操作一個設備。

我們看一下上面的四種操作需要什麼許可權。

首先看一下普世法則,任何需要走到容器裡面才能進行的操作,對整條路徑上的容器都需要執行許可權(只有一個例外);改變容器格局的操作都需要寫許可權。

加減書架需要先走進圖書館(根),再走到屋子裡面才能進行,因此對圖書館和屋子都需要執行許可權。加書架屋子內東西多了,減書架屋子內東西少了,格局變了,因此都需要寫許可權。

拿書到書架上也一樣,手到了書架里才能操作,因此對書架的整條路徑需要執行許可權。當然也需要寫許可權。需要注意的是拿走一本書籍對書籍本書不需要讀或者寫的許可權。

瀏覽容器內的書籍和設備名字,這是第一條提到的例外,因為只是匆匆一撇,因此只需要路徑各個容器的讀許可權就可以了。這裡看到的只有書籍名字,其他信息一律獲取不到。

讀書籍除了對書籍本身要有讀許可權,對書籍所在路徑的所有容器都要有執行許可權;寫書籍出了對書籍本身要有寫許可權,對書籍所在路徑的所有容器都要有執行許可權;運行設備除了對設備本身要有執行許可權,對設備所在路徑的所有容器都要有執行許可權。

將第五條規則詳細說明

第五條規則裡面的對書籍本身要有讀寫許可權,那麼什麼情況下才會對書籍有讀寫許可權呢,我們詳細展開說明。

繼續圖書館中的例子,我們註冊成為圖書館的會員時,管理員是會給我們分配一個ID號的,這個ID號用來標識我們的身份。每次進入圖書館進行圖書的讀(read)和寫(write),以及操作(run)設備,檢查許可權的時候是通過這個ID號來檢查的:會員A進入圖書館,會員A的ID——r_id_a(real id)就會被記錄下來,會員A打開書籍bookA進行讀或者寫的時候,會使用id_a來進行檢查:

如果id_a=0,代表是管理員。管理員就是上帝,可以為所欲為。讀寫都可。

如果打開書籍的owner_id=id_a,說明這本書的擁有者就是會員A,接下來就看會員A給自己的這本書設置了什麼許可權,如果設置了自己可以讀或者寫,那就可以讀或者寫。反之,如果你認為這本書籍有害,設成了禁止自己讀和寫,你就不能讀寫。

如果id_a和bookA的owner_id在同一個組中,那麼,就要看這本書的owner如何設置組許可權了,如果設置的組內成員可以讀寫,則可以讀寫。否則,不能讀寫。

如果id_a既不等於owner_id,也不和owner_id在同一個組中,就需要看其它(others)設置的許可權了,如果設置成可以讀寫,則可以讀寫。否則,不能讀寫。

上面的四個步驟,如果走到其中一個步驟的判斷是允許或者拒絕,就不會再繼續往下判斷了。例如,如果bookA的owner_id=id_a,並且你設置的許可權是禁止自己讀寫。即使你所在的組設置的許可權為允許讀寫,結果也會是拒絕。

需要指出的是,上面的五條規則都是錯誤的,錯誤的地方在id_a上,我只是為了方便說明,實際上一個會員在圖書館里身份是可以通過某種方式進行變化的,也就是說會員在讀寫時,用來判斷許可權的id有可能不是id_a。接下來說明。

回到頂部

進程中的許可權

進程的概念是動態的。也就是說許可權這個東西是隨系統運行會發生變化的。繼續圖書館的例子,上一節最後我們說到了會員的身份問題。這裡詳細闡述一下,會員進入圖書館有一個ID(實際ID),這個ID確切標識了會員的身份,但是在會員進行活動時,操作某個設備(run)時,他這時的身份(有效ID)就有可能發生變化了。

糾正上一節中的錯誤:其實進行比較的不是id_a,而是身份變化后的ID——e_id_a(effective id)。

圖書館引入了一批機器人,這些機器人可以代替人進行圖書的讀和寫。這樣會員就可以直接通過電腦操控機器人。每個會員都可以擁有一個自己的機器人。這時候就可以把機器人看成會員的替身。當機器人進行讀寫書籍時,機器人的身份ID初始情況下就是會員本身的ID。會員的身份是如何通過機器人發生變化的呢?

會員可以真正操控別人的替身

一個會員是可以使用別人的機器人(run一個owner不是自己的程序)的,但是在通常情況下,e_id就是r_id。用真實身份去操控別人的機器人。許可權結果有上一節的條款而定。但是只可能通過組許可權或者其它許可權來獲得訪問權。因此有很大的局限性。如何把會員的身份偽裝成操控機器人的owner呢?

上一節我們提到了關於文件的5個屬性。這裡還要說兩個:

設置用戶ID

設置組ID

這兩個ID是做什麼用的?如果機器人(機器人是可以運行的文件)設置了設置用戶ID,別的用戶在操控這個機器人時,r_id會變成機器人的ownner_id。這就可以用機器人擁有者的身份來操控機器人呢了。有人有疑問,如果有其它會員搞破壞會怎麼辦?其實管理權真正在owner手裡,替身還是替身,並不是owner本人。替身的功能是可以限制的,owner在設置替身的功能時,如果設置了設置用戶ID,可以自定義機器人可以讀寫哪些書籍。

設置組ID是相同的道理。

需要注意的是,如果會員結束操控別人的機器人?這時的r_id會如何變化呢?答案是會變回原來的r_id。但是原來的r_id和g_r_id保存在什麼地方呢?這裡有另外兩個ID來臨時保存這兩個ID:

保存的設置用戶ID

保存的設置組ID

運行過程中變換身份

上面的身份變換是機器人開始運行時就發生變化的,那麼在運行過程中可以發生變化么?也是可以的。

Advertisements

你可能會喜歡