歡迎光臨
每天分享高質量文章

“用戶組”在 Linux 上到底是怎麼工作的? | Linux 中國

我意識到之前我並沒有真正理解用戶和組是怎麼工作的,我信心滿滿的嘗試了下麵的內容並且驗證到底發生了什麼,事實證明現在我的理解才是對的。
— Julia Evans


致謝
編譯自 | 
https://jvns.ca/blog/2017/11/20/groups/
 
 作者 | Julia Evans
 譯者 | DavidChenLiang ??共計翻譯:7.0 篇 貢獻時間:56 天

嗨!就在上周,我還自認為對 Linux 上的用戶和組的工作機制瞭如指掌。我認為它們的關係是這樣的:

1. 每個行程都屬於一個用戶(比如用戶 julia
2. 當這個行程試圖讀取一個被某個組所擁有的檔案時, Linux 會 a. 先檢查用戶julia 是否有權限訪問檔案。(LCTT 譯註:此處應該是指檢查檔案的所有者是否就是 julia) b. 檢查 julia 屬於哪些組,併進一步檢查在這些組裡是否有某個組擁有這個檔案或者有權限訪問這個檔案。
3. 如果上述 a、b 任一為真(或者“其它”位設為有權限訪問),那麼這個行程就有權限訪問這個檔案。

比如說,如果一個行程被用戶 julia 擁有並且 julia 在awesome 組,那麼這個行程就能訪問下麵這個檔案。

  1. r--r--r-- 1 root awesome     6872 Sep 24 11:09 file.txt

然而上述的機制我並沒有考慮得非常清楚,如果你硬要我闡述清楚,我會說行程可能會在運行時去檢查 /etc/group 檔案里是否有某些組擁有當前的用戶。

然而這並不是 Linux 里“組”的工作機制

我在上個星期的工作中發現了一件有趣的事,事實證明我前面的理解錯了,我對組的工作機制的描述並不准確。特別是 Linux 並不會在行程每次試圖訪問一個檔案時就去檢查這個行程的用戶屬於哪些組。

我在讀了《Linux 編程接口[1]》這本書的第九章(“行程資格”)後才恍然大悟(這本書真是太棒了),這才是組真正的工作方式!我意識到之前我並沒有真正理解用戶和組是怎麼工作的,我信心滿滿的嘗試了下麵的內容並且驗證到底發生了什麼,事實證明現在我的理解才是對的。

用戶和組權限檢查是怎麼完成的

現在這些關鍵的知識在我看來非常簡單! 這本書的第九章上來就告訴我如下事實:用戶和組 ID 是行程的屬性,它們是:

◈ 真實用戶 ID 和組 ID;
◈ 有效用戶 ID 和組 ID;
◈ 儲存的 set-user-ID 和儲存的 set-group-ID;
◈ 檔案系統用戶 ID 和組 ID(特定於 Linux);
◈ 補充的組 ID;

這說明 Linux 實際上檢查一個行程能否訪問一個檔案所做的組檢查是這樣的:

◈ 檢查一個行程的組 ID 和補充組 ID(這些 ID 就在行程的屬性里,並不是實時在 /etc/group 里查找這些 ID)
◈ 檢查要訪問的檔案的訪問屬性里的組設置
◈ 確定行程對檔案是否有權限訪問(LCTT 譯註:即檔案的組是否是以上的組之一)

通常當訪問控制的時候使用的是有效用戶/組 ID,而不是真實用戶/組 ID。技術上來說當訪問一個檔案時使用的是檔案系統的 ID,它們通常和有效用戶/組 ID 一樣。(LCTT 譯註:這句話針對 Linux 而言。)

將一個用戶加入一個組並不會將一個已存在的行程(的用戶)加入那個組

下麵是一個有趣的例子:如果我創建了一個新的組:panda 組並且將我自己(bork)加入到這個組,然後運行 groups 來檢查我是否在這個組裡:結果是我(bork)竟然不在這個組?!

  1. [email protected]~> sudo addgroup panda

  2. Adding group `panda' (GID 1001) ...

  3. Done.

  4. [email protected]~> sudo adduser bork panda

  5. Adding user `bork' to group `panda' ...

  6. Adding user bork to group panda

  7. Done.

  8. [email protected]~> groups

  9. bork adm cdrom sudo dip plugdev lpadmin sambashare docker lxd

panda 並不在上面的組裡!為了再次確定我們的發現,讓我們建一個檔案,這個檔案被 panda 組擁有,看看我能否訪問它。

  1. $  touch panda-file.txt

  2. $  sudo chown root:panda panda-file.txt

  3. $  sudo chmod 660 panda-file.txt

  4. $  cat panda-file.txt

  5. cat: panda-file.txt: Permission denied

好吧,確定了,我(bork)無法訪問 panda-file.txt。這一點都不讓人吃驚,我的命令解釋器並沒有將 panda 組作為補充組 ID,運行 adduser bork panda 並不會改變這一點。

那行程一開始是怎麼得到用戶的組的呢?

這真是個非常令人困惑的問題,對嗎?如果行程會將組的信息預置到行程的屬性裡面,行程在初始化的時候怎麼取到組的呢?很明顯你無法給你自己指定更多的組(否則就會和 Linux 訪問控制的初衷相違背了……)

有一點還是很清楚的:一個新的行程是怎麼從我的命令列解釋器(/bash/fish)里被執行而得到它的組的。(新的)行程將擁有我的用戶 ID(bork),並且行程屬性里還有很多組 ID。從我的命令解釋器里執行的所有行程是從這個命令解釋器里 fork() 而來的,所以這個新行程得到了和命令解釋器同樣的組。

因此一定存在一個“第一個”行程來把你的組設置到行程屬性里,而所有由此行程而衍生的行程將都設置這些組。而那個“第一個”行程就是你的登錄程式login shell,在我的筆記本電腦上,它是由 login程式(/bin/login)實體化而來。登錄程式以 root 身份運行,然後呼叫了一個 C 的庫函式 —— initgroups 來設置你的行程的組(具體來說是通過讀取 /etc/group 檔案),因為登錄程式是以 root 運行的,所以它能設置你的行程的組。

讓我們再登錄一次

好了!假如說我們正處於一個登錄程式中,而我又想掃清我的行程的組設置,從我們前面所學到的行程是怎麼初始化組 ID 的,我應該可以通過再次運行登錄程式來掃清我的行程組並啟動一個新的登錄命令!

讓我們試試下邊的方法:

  1. $ sudo login bork

  2. $ groups

  3. bork adm cdrom sudo dip plugdev lpadmin sambashare docker lxd panda

  4. $ cat panda-file.txt # it works! I can access the file owned by `panda` now!

當然,成功了!現在由登錄程式衍生的程式的用戶是組 panda 的一部分了!太棒了!這並不會影響我其他的已經在運行的登錄程式(及其子行程),如果我真的希望“所有的”行程都能對 panda 組有訪問權限。我必須完全的重啟我的登錄會話,這意味著我必須退出我的視窗管理器然後再重新登錄。(LCTT 譯註:即更新行程樹的樹根行程,這裡是視窗管理器行程。)

newgrp 命令

在 Twitter 上有人告訴我如果只是想啟動一個掃清了組信息的命令解釋器的話,你可以使用 newgrp(LCTT 譯註:不啟動新的命令解釋器),如下:

  1. sudo addgroup panda

  2. sudo adduser bork panda

  3. newgrp panda # starts a new shell, and you don't have to be root to run it!

你也可以用 sg panda bash 來完成同樣的效果,這個命令能啟動一個bash 登錄程式,而這個程式就有 panda 組。

seduid 將設置有效用戶 ID

其實我一直對一個行程如何以 setuid root 的權限來運行意味著什麼有點似是而非。現在我知道了,事實上所發生的是:setuid 設置了 
“有效用戶 ID”! 如果我(julia)運行了一個 setuid root 的行程( 比如 passwd),那麼行程的真實用戶 ID 將為 julia,而有效用戶 ID 將被設置為 root

passwd 需要以 root 權限來運行,但是它能看到行程的真實用戶 ID 是 julia ,是 julia 啟動了這個行程,passwd 會阻止這個行程修改除了 julia 之外的用戶密碼。

就是這些了!

在《Linux 編程接口[1]》這本書里有很多 Linux 上一些功能的罕見使用方法以及 Linux 上所有的事物到底是怎麼運行的詳細解釋,這裡我就不一一展開了。那本書棒極了,我上面所說的都在該書的第九章,這章在 1300 頁的書里只占了 17 頁。

我最愛這本書的一點是我只用讀 17 頁關於用戶和組是怎麼工作的內容,而這區區 17 頁就能做到內容完備、詳實有用。我不用讀完所有的 1300 頁書就能得到有用的東西,太棒了!


via: https://jvns.ca/blog/2017/11/20/groups/

作者:Julia Evans[3] 譯者:DavidChen 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

赞(0)

分享創造快樂