天天看點

第十四章、Linux 賬号管理與 ACL 權限配置

要登陸 Linux 系統一定要有賬号與密碼才行,否則怎麼登陸,您說是吧?不過, 不同的使用者應該要擁有不同的權限才行吧?我們還可以透過 user/group 的特殊權限配置, 來規範出不同的群組開發項目呢~在 Linux 的環境下,我們可以透過很多方式來限制使用者能夠使用的系統資源, 包括 十一章、bash 提到的 ulimit 限制、還有特殊權限限制,如 umask 等等。 透過這些舉動,我們可以規範出不同使用者的使用資源。另外,還記得系統管理者的賬号嗎?對! 就是 root 。請問一下,除了 root 之外,是否可以有其他的系統管理者賬号? 為什麼大家都要盡量避免使用數字型态的賬号?如何修改使用者相關的資訊呢?這些我們都得要了解了解的!

1. Linux 的賬号與群組

  1.1 使用者辨別符: UID 與 GID

  1.2 使用者賬号:/etc/passwd 檔案結構, /etc/shadow 檔案結構

  1.3 關于群組: /etc/group 檔案結構, 有效與初始群組, groups, newgrp,/etc/gshadow

2. 賬号管理

  2.1 新增與移除使用者: useradd, useradd 參考檔, passwd, chage, usermod, userdel

  2.2 使用者功能:finger, chfn, chsh, id

  2.3 新增與移除群組:groupadd, groupmod, groupdel, gpasswd 群組管理者

  2.4 賬号管理執行個體

3. 主機的細部權限規劃:ACL 的使用

  3.1 什麼是 ACL

  3.2 如何啟動 ACL

  3.3 ACL 的配置技巧: setfacl, getfacl, ACL 的配置(user, group mask, default)

4. 使用者身份切換

  4.1 su

  4.2 sudo: sudo 指令, visudo (/etc/sudoers) ( 賬号, 群組, 限制指令, 别名, 時間間隔, 配合 su )

5. 使用者的特殊 shell 與 PAM 子產品

  5.1 特殊的 shell :/sbin/nologin, nologin.txt

  5.2 PAM 子產品簡介

  5.3 PAM 子產品配置文法:驗證類别(type)、控制标準(flag)、子產品與參數

  5.4 常用子產品簡介: securetty, nologin, pam_cracklib, login流程

  5.5 其他相關檔案: limits.conf,

6. Linux 主機上的使用者資訊傳遞

  6.1 查詢使用者: w, who, last, lastlog

  6.2 使用者對談: write, mesg, wall

  6.3 使用者郵件信箱: mail

7. 手動新增使用者

  7.1 一些檢查工具:pwck, pwconv, pwunconv, chpasswd

  7.2 特殊賬号,如純數字賬号的手工建立

  7.3 大量建置賬号模闆(适用 passwd --stdin 選項)

  7.4 大量建置賬号的範例(适用于連續數字,如學号)

8. 重點回顧

9. 本章習題

10. 參考資料與延伸閱讀

11. 針對本文的建議:http://phorum.vbird.org/viewtopic.php?t=23887

第十四章、Linux 賬号管理與 ACL 權限配置

Linux 的賬号與群組

管理者的工作中,相當重要的一環就是『管理賬号』啦!因為整個系統都是你在管理的, 并且所有一般使用者的賬号申請,都必須要透過你的協助才行!是以你就必須要了解一下如何管理好一個伺服器主機的賬号啦! 在管理 Linux 主機的賬号時,我們必須先來了解一下 Linux 到底是如何辨識每一個使用者的!

第十四章、Linux 賬号管理與 ACL 權限配置

使用者辨別符: UID 與 GID

雖然我們登陸 Linux 主機的時候,輸入的是我們的賬号,但是其實 Linux 主機并不會直接認識你的『賬号名稱』的,他僅認識 ID 啊 (ID 就是一組号碼啦)。 由于計算機僅認識 0 與 1,是以主機對于數字比較有概念的;至于賬号隻是為了讓人們容易記憶而已。 而你的 ID 與賬号的對應就在 /etc/passwd 當中哩。

Tips:

如果你曾經在網絡上下載下傳過 tarball 類型的檔案, 那麼應該不難發現,在解壓縮之後的檔案中,檔案擁有者的字段竟然顯示『不明的數字』?奇怪吧?這沒什麼好奇怪的,因為 Linux 說實在話,他真的隻認識代表你身份的号碼而已!

第十四章、Linux 賬号管理與 ACL 權限配置

那麼到底有幾種 ID 呢?還記得我們在第六章内有提到過, 每一個檔案都具有『擁有人與擁有群組』的屬性嗎?沒錯啦~每個登陸的使用者至少都會取得兩個 ID ,一個是使用者 ID (User ID ,簡稱 UID)、一個是群組 ID (Group ID ,簡稱 GID)。

那麼檔案如何判别他的擁有者與群組呢?其實就是利用 UID 與 GID 啦!每一個檔案都會有所謂的擁有者 ID 與擁有群組 ID ,當我們有要顯示檔案屬性的需求時,系統會依據 /etc/passwd 與 /etc/group 的内容, 找到 UID / GID 對應的賬号與組名再顯示出來!我們可以作個小實驗,你可以用 root 的身份 vi /etc/passwd ,然後将你的一般身份的使用者的 ID 随便改一個号碼,然後再到你的一般身份的目錄下看看原先該賬号擁有的檔案,你會發現該檔案的擁有人變成了 『數字了』呵呵!這樣可以了解了嗎?來看看底下的例子:

# 1. 先察看一下,系統裡面有沒有一個名為 dmtsai 的使用者?
[[email protected] ~]# grep 'dmtsai' /etc/passwd
dmtsai:x:503:504::/home/dmtsai:/bin/bash   <==是有這個賬号喔!
[[email protected] ~]# ll -d /home/dmtsai
drwx------ 4 dmtsai dmtsai 4096 Feb  6 18:25 /home/dmtsai
# 瞧一瞧,使用者的字段正是 dmtsai 本身喔!

# 2. 修改一下,将剛剛我們的 dmtsai 的 503 UID 改為 2000 看看:
[[email protected] ~]# vi /etc/passwd
....(前面省略)....
dmtsai:x:2000:504::/home/dmtsai:/bin/bash <==修改一下特殊字型部分,由 503 改過來
[[email protected] ~]# ll -d /home/dmtsai
drwx------ 4 503 dmtsai 4096 Feb  6 18:25 /home/dmtsai
# 很害怕吧!怎麼變成 503 了?因為檔案隻會記錄數字而已!
# 因為我們亂改,是以導緻 503 找不到對應的賬号,是以顯示數字!

# 3. 記得将剛剛的 2000 改回來!
[[email protected] ~]# vi /etc/passwd
....(前面省略)....
dmtsai:x:503:504::/home/dmtsai:/bin/bash <==趕緊改回來!
      

你一定要了解的是,上面的例子僅是在說明 UID 與賬号的對應性,在一部正常運作的 Linux 主機環境下,上面的動作不可随便進行, 這是因為系統上已經有很多的資料被建立存在了,随意修改系統上某些賬号的 UID 很可能會導緻某些程式無法進行,這将導緻系統無法順利運作的結果。 因為權限的問題啊!是以,了解了之後,請趕快回到 /etc/passwd 裡面,将數字改回來喔!

Tips:

舉例來說,如果上面的測試最後一個步驟沒有将 2000 改回原本的 UID,那麼當 dmtsai 下次登陸時将沒有辦法進入自己的家目錄! 因為他的 UID 已經改為 2000 ,但是他的家目錄 (/home/dmtsai) 卻記錄的是 503 ,由于權限是 700 , 是以他将無法進入原本的家目錄!是否非常嚴重啊?

第十四章、Linux 賬号管理與 ACL 權限配置
第十四章、Linux 賬号管理與 ACL 權限配置

使用者賬号

Linux 系統上面的使用者如果需要登陸主機以取得 shell 的環境來工作時,他需要如何進行呢? 首先,他必須要在計算機前面利用 tty1~tty7 的終端機提供的 login 接口,并輸入賬号與密碼後才能夠登陸。 如果是透過網絡的話,那至少使用者就得要學習 ssh 這個功能了 (伺服器篇再來談)。 那麼你輸入賬号密碼後,系統幫你處理了什麼呢?

  1. 先找尋 /etc/passwd 裡面是否有你輸入的賬号?如果沒有則跳出,如果有的話則将該賬号對應的 UID 與 GID (在 /etc/group 中) 讀出來,另外,該賬号的家目錄與 shell 配置也一并讀出;
  2. 再來則是核對密碼表啦!這時 Linux 會進入 /etc/shadow 裡面找出對應的賬号與 UID,然後核對一下你剛剛輸入的密碼與裡頭的密碼是否相符?
  3. 如果一切都 OK 的話,就進入 Shell 控管的階段啰!

大緻上的情況就像這樣,是以當你要登陸你的 Linux 主機的時候,那個 /etc/passwd 與 /etc/shadow 就必須要讓系統讀取啦 (這也是很多攻擊者會将特殊賬号寫到 /etc/passwd 裡頭去的緣故),是以呢,如果你要備份 Linux 的系統的賬号的話,那麼這兩個檔案就一定需要備份才行呦!

由上面的流程我們也知道,跟使用者賬号有關的有兩個非常重要的檔案,一個是管理使用者 UID/GID 重要參數的 /etc/passwd ,一個則是專門管理密碼相關資料的 /etc/shadow 啰!那這兩個檔案的内容就非常值得進行研究啦! 底下我們會簡單的介紹這兩個檔案,詳細的說明可以參考 man 5 passwd 及 man 5 shadow (注1)。

  • /etc/passwd 檔案結構

這個檔案的構造是這樣的:每一行都代表一個賬号,有幾行就代表有幾個賬号在你的系統中! 不過需要特别留意的是,裡頭很多賬号本來就是系統正常運作所必須要的,我們可以簡稱他為系統賬号, 例如 bin, daemon, adm, nobody 等等,這些賬号請不要随意的殺掉他呢! 這個檔案的内容有點像這樣:

Tips:

鳥哥在接觸 Linux 之前曾經碰過 Solaris 系統 (1999 年),當時鳥哥啥也不清楚!由于『聽說』Linux 上面的賬号越複雜會導緻系統越危險!是以鳥哥就将 /etc/passwd 上面的賬号全部删除到隻剩下 root 與鳥哥自己用的一般賬号!結果你猜發生什麼事?那就是....呼叫升陽的工程師來維護系統 @_@!糗到一個不行!大家不要學啊!

第十四章、Linux 賬号管理與 ACL 權限配置
[[email protected] ~]# head -n 4 /etc/passwd
root:x:0:0:root:/root:/bin/bash  <==等一下做為底下說明用
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
      

我們先來看一下每個 Linux 系統都會有的第一行,就是 root 這個系統管理者那一行好了, 你可以明顯的看出來,每一行使用『:』分隔開,共有七個咚咚,分别是:

  1. 賬号名稱:

    就是賬号啦!用來對應 UID 的。例如 root 的 UID 對應就是 0 (第三字段);

  2. 密碼:

    早期 Unix 系統的密碼就是放在這字段上!但是因為這個檔案的特性是所有的程式都能夠讀取,這樣一來很容易造成密碼資料被竊取, 是以後來就将這個字段的密碼資料給他改放到 /etc/shadow 中了。是以這裡你會看到一個『 x 』,呵呵!

  3. UID:

    這個就是使用者辨別符啰!通常 Linux 對于 UID 有幾個限制需要說給您了解一下:

    id 範圍 該 ID 使用者特性
    (系統管理者) 當 UID 是 0 時,代表這個賬号是『系統管理者』! 是以當你要讓其他的賬号名稱也具有 root 的權限時,将該賬号的 UID 改為 0 即可。 這也就是說,一部系統上面的系統管理者不見得隻有 root 喔! 不過,很不建議有多個賬号的 UID 是 0 啦~

    1~499

    (系統賬号)

    保留給系統使用的 ID,其實除了 0 之外,其他的 UID 權限與特性并沒有不一樣。預設 500 以下的數字讓給系統作為保留賬号隻是一個習慣。

    由于系統上面啟動的服務希望使用較小的權限去運作,是以不希望使用 root 的身份去運作這些服務, 是以我們就得要提供這些運作中程式的擁有者賬号才行。這些系統賬号通常是不可登陸的, 是以才會有我們在第十一章提到的 /sbin/nologin 這個特殊的 shell 存在。

    根據系統賬号的由來,通常系統賬号又約略被區分為兩種:

    1~99:由 distributions 自行建立的系統賬号;

    100~499:若使用者有系統賬号需求時,可以使用的賬号 UID。

    500~65535

    (可登陸賬号)

    給一般使用者用的。事實上,目前的 linux 核心 (2.6.x 版)已經可以支援到 4294967295 (2^32-1) 這麼大的 UID 号碼喔!
    上面這樣說明可以了解了嗎?是的, UID 為 0 的時候,就是 root 呦!是以請特别留意一下你的 /etc/passwd 檔案!
  4. GID:

    這個與 /etc/group 有關!其實 /etc/group 的觀念與 /etc/passwd 差不多,隻是他是用來規範組名與 GID 的對應而已!

  5. 使用者資訊說明欄:

    這個字段基本上并沒有什麼重要用途,隻是用來解釋這個賬号的意義而已!不過,如果您提供使用 finger 的功能時, 這個字段可以提供很多的資訊呢!本章後面的 chfn 指令會來解釋這裡的說明。

  6. 家目錄:

    這是使用者的家目錄,以上面為例, root 的家目錄在 /root ,是以當 root 登陸之後,就會立刻跑到 /root 目錄裡頭啦!呵呵! 如果你有個賬号的使用空間特别的大,你想要将該賬号的家目錄移動到其他的硬碟去該怎麼作? 沒有錯!可以在這個字段進行修改呦!預設的使用者家目錄在 /home/yourIDname

  7. Shell:

    我們在第十一章 BASH 提到很多次,當使用者登陸系統後就會取得一個 Shell 來與系統的核心溝通以進行使用者的操作任務。那為何預設 shell 會使用 bash 呢?就是在這個字段指定的啰! 這裡比較需要注意的是,有一個 shell 可以用來替代成讓賬号無法取得 shell 環境的登陸動作!那就是 /sbin/nologin 這個東西!這也可以用來制作純 pop 郵件賬号者的資料呢!

  • /etc/shadow 檔案結構

我們知道很多程式的運作都與權限有關,而權限與 UID/GID 有關!是以各程式當然需要讀取 /etc/passwd 來了解不同賬号的權限。 是以 /etc/passwd 的權限需配置為 -rw-r--r-- 這樣的情況, 雖然早期的密碼也有加密過,但卻放置到 /etc/passwd 的第二個字段上!這樣一來很容易被有心人士所竊取的, 加密過的密碼也能夠透過暴力破解法去 try and error (試誤) 找出來!

因為這樣的關系,是以後來發展出将密碼移動到 /etc/shadow 這個檔案分隔開來的技術, 而且還加入很多的密碼限制參數在 /etc/shadow 裡頭呢!在這裡,我們先來了解一下這個檔案的構造吧! 鳥哥的 /etc/shadow 檔案有點像這樣:

[[email protected] ~]# head -n 4 /etc/shadow
root:$1$/30QpE5e$y9N/D0bh6rAACBEz.hqo00:14126:0:99999:7:::  <==底下說明用
bin:*:14126:0:99999:7:::
daemon:*:14126:0:99999:7:::
adm:*:14126:0:99999:7:::
      

基本上, shadow 同樣以『:』作為分隔符,如果數一數,會發現共有九個字段啊,這九個字段的用途是這樣的:

  1. 賬号名稱:

    由于密碼也需要與賬号對應啊~是以,這個檔案的第一欄就是賬号,必須要與 /etc/passwd 相同才行!

  2. 密碼:

    這個字段内的資料才是真正的密碼,而且是經過編碼的密碼 (加密) 啦! 你隻會看到有一些特殊符号的字母就是了!需要特别留意的是,雖然這些加密過的密碼很難被解出來, 但是『很難』不等于『不會』,是以,這個檔案的預設權限是『-rw-------』或者是『-r--------』,亦即隻有 root 才可以讀寫就是了!你得随時注意,不要不小心更動了這個檔案的權限呢!

    另外,由于各種密碼編碼的技術不一樣,是以不同的編碼系統會造成這個字段的長度不相同。 舉例來說,舊式的 DES 編碼系統産生的密碼長度就與目前慣用的 MD5 不同(注2)!MD5 的密碼長度明顯的比較長些。由于固定的編碼系統産生的密碼長度必須一緻,是以『當你讓這個字段的長度改變後,該密碼就會失效(算不出來)』。 很多軟體透過這個功能,在此字段前加上 ! 或 * 改變密碼字段長度,就會讓密碼『暫時失效』了。 

  3. 最近更動密碼的日期:

    這個字段記錄了『更動密碼那一天』的日期,不過,很奇怪呀!在我的例子中怎麼會是 14126 呢?呵呵,這個是因為計算 Linux 日期的時間是以 1970 年 1 月 1 日作為 1 而累加的日期,1971 年 1 月 1 日則為 366 啦! 得注意一下這個資料呦!上述的 14126 指的就是 2008-09-04 那一天啦!了解乎? 而想要了解該日期可以使用本章後面 chage 指令的幫忙!至于想要知道某個日期的累積日數, 可使用如下的程式計算:

    [[email protected] ~]# echo $(($(date --date="2008/09/04" +%s)/86400+1))
    14126
          
    上述指令中,2008/09/04 為你想要計算的日期,86400 為每一天的秒數, %s 為 1970/01/01 以來的累積總秒數。 由于 bash 僅支援整數,是以最終需要加上 1 補齊 1970/01/01 當天。
  4. 密碼不可被更動的天數:(與第 3 字段相比)

    第四個字段記錄了:這個賬号的密碼在最近一次被更改後需要經過幾天才可以再被變更!如果是 0 的話, 表示密碼随時可以更動的意思。這的限制是為了怕密碼被某些人一改再改而設計的!如果配置為 20 天的話,那麼當你配置了密碼之後, 20 天之内都無法改變這個密碼呦!

  5. 密碼需要重新變更的天數:(與第 3 字段相比)

    經常變更密碼是個好習慣!為了強制要求使用者變更密碼,這個字段可以指定在最近一次更改密碼後, 在多少天數内需要再次的變更密碼才行。你必須要在這個天數内重新配置你的密碼,否則這個賬号的密碼将會『變為過期特性』。 而如果像上面的 99999 (計算為 273 年) 的話,那就表示,呵呵,密碼的變更沒有強制性之意。

  6. 密碼需要變更期限前的警告天數:(與第 5 字段相比)

    當賬号的密碼有效期限快要到的時候 (第 5 字段),系統會依據這個字段的配置,發出『警告』言論給這個賬号,提醒他『再過 n 天你的密碼就要過期了,請盡快重新配置你的密碼呦!』,如上面的例子,則是密碼到期之前的 7 天之内,系統會警告該使用者。

  7. 密碼過期後的賬号寬限時間(密碼失效日):(與第 5 字段相比)

    密碼有效日期為『更新日期(第3字段)』+『重新變更日期(第5字段)』,過了該期限後使用者依舊沒有更新密碼,那該密碼就算過期了。 雖然密碼過期但是該賬号還是可以用來進行其他工作的,包括登陸系統取得 bash 。不過如果密碼過期了, 那當你登陸系統時,系統會強制要求你必須要重新配置密碼才能登陸繼續使用喔,這就是密碼過期特性。

    那這個字段的功能是什麼呢?是在密碼過期幾天後,如果使用者還是沒有登陸更改密碼,那麼這個賬号的密碼将會『失效』, 亦即該賬号再也無法使用該密碼登陸了。要注意密碼過期與密碼失效并不相同。

  8. 賬号失效日期:

    這個日期跟第三個字段一樣,都是使用 1970 年以來的總日數配置。這個字段表示: 這個賬号在此字段規定的日期之後,将無法再使用。 就是所謂的『賬号失效』,此時不論你的密碼是否有過期,這個『賬号』都不能再被使用! 這個字段會被使用通常應該是在『收費服務』的系統中,你可以規定一個日期讓該賬号不能再使用啦!

  9. 保留:

    最後一個字段是保留的,看以後有沒有新功能加入。

舉個例子來說好了,假如我的 dmtsai 這個使用者的密碼欄如下所示:

dmtsai:$1$vyUuj.eX$omt6lKJvMcIZHx4H7RI1V.:14299:5:60:7:5:14419:
      

這表示什麼呢?先要注意的是 14299 是 2009/02/24 。是以 dmtsai 這個使用者的密碼相關意義是:

  • 由于密碼幾乎僅能單向運算(由明碼計算成為密碼,無法由密碼反推回明碼),是以由上表的資料我們無法得知 dmstai 的實際密碼明文;
  • 此賬号最近一次更動密碼的日期是 2009/02/24 (14299);
  • 能夠再次修改密碼的時間是 5 天以後,也就是 2009/03/01 以前 dmtsai 不能修改自己的密碼;如果使用者還是嘗試要更動自己的密碼,系統就會出現這樣的資訊:
    You must wait longer to change your password
    passwd: Authentication token manipulation error
          
    畫面中告訴我們:你必須要等待更久的時間才能夠變更密碼之意啦!
  • 由于密碼過期日期定義為 60 天後,亦即累積日數為: 14299+60=14359,經過計算得到此日數代表日期為 2009/04/25。 這表示:『使用者必須要在 2009/03/01 到 2009/04/25 之間的 60 天限制内去修改自己的密碼,若 2009/04/25 之後還是沒有變更密碼時,該密碼就宣告為過期』了!
  • 警告日期設為 7 天,亦即是密碼過期日前的 7 天,在本例中則代表 2009/04/19 ~ 2009/04/25 這七天。 如果使用者一直沒有更改密碼,那麼在這 7 天中,隻要 dmtsai 登陸系統就會發現如下的資訊:
    Warning: your password will expire in 5 days
          
  • 如果該賬号一直到 2009/04/25 都沒有更改密碼,那麼密碼就過期了。但是由于有 5 天的寬限天數, 是以dmtsai 在 2009/04/30 前都還可以使用舊密碼登陸主機。 不過登陸時會出現強制更改密碼的情況,畫面有點像底下這樣:
    You are required to change your password immediately (password aged)
    WARNING: Your password has expired.
    You must change your password now and login again!
    Changing password for user dmtsai.
    Changing password for dmtsai
    (current) UNIX password:
          
    你必須要輸入一次舊密碼以及兩次新密碼後,才能夠開始使用系統的各項資源。如果你是在 2009/04/30 以後嘗試以 dmtsai 登陸的話,那麼就會出現如下的錯誤資訊且無法登陸,因為此時你的密碼就失效去啦!
    Your account has expired; please contact your system administrator
          
  • 如果使用者在 2009/04/25 以前變更過密碼,那麼第 3 個字段的那個 14299 的天數就會跟着改變,是以, 所有的限制日期也會跟着相對變動喔!^_^
  • 無論使用者如何動作,到了 14419 (大約是 2009/07/24 左右) 該賬号就失效了~

透過這樣的說明,您應該會比較容易了解了吧?由于 shadow 有這樣的重要性,是以可不能随意修改喔! 但在某些情況底下你得要使用各種方法來處理這個檔案的!舉例來說,常常聽到人家說:『我的密碼忘記了』, 或者是『我的密碼不曉得被誰改過,跟原先的不一樣了』,這個時候怎麼辦?

  • 一般使用者的密碼忘記了:這個最容易解決,請系統管理者幫忙, 他會重新配置好你的密碼而不需要知道你的舊密碼!利用 root 的身份使用 passwd 指令來處理即可。
  • root 密碼忘記了:這就麻煩了!因為你無法使用 root 的身份登陸了嘛! 但我們知道 root 的密碼在 /etc/shadow 當中,是以你可以使用各種可行的方法啟動進入 Linux 再去修改。 例如重新啟動進入單人維護模式(第二十章)後,系統會主動的給予 root 權限的 bash 接口, 此時再以 passwd 修改密碼即可;或以 Live CD 啟動後挂載根目錄去修改 /etc/shadow,将裡面的 root 的密碼字段清空, 再重新啟動後 root 将不用密碼即可登陸!登陸後再趕快以 passwd 指令去配置 root 密碼即可。

Tips:

曾經聽過一則笑話,某位老師主要是在教授 Linux 作業系統,但是他是兼任的老師,是以對于該系的計算機環境不熟。 由于當初安裝該計算機教室 Linux 作業系統的人員已經離職且找不到聯絡方式了,也就是說 root 密碼已經沒有人曉得了! 此時該老師就對學生說:『在 Linux 裡面 root 密碼不見了,我們隻能重新安裝』...感覺有點無力~ 又是個被 Windows 制約的人才!

第十四章、Linux 賬号管理與 ACL 權限配置
第十四章、Linux 賬号管理與 ACL 權限配置

關于群組: 有效與初始群組、groups, newgrp

認識了賬号相關的兩個檔案 /etc/passwd 與 /etc/shadow 之後,你或許還是會覺得奇怪, 那麼群組的配置檔案在哪裡?還有,在 /etc/passwd 的第四欄不是所謂的 GID 嗎?那又是啥? 呵呵~此時就需要了解 /etc/group 與 /etc/gshadow 啰~

  • /etc/group 檔案結構

這個檔案就是在記錄 GID 與組名的對應了~鳥哥測試機的 /etc/group 内容有點像這樣:

[[email protected] ~]# head -n 4 /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
      

這個檔案每一行代表一個群組,也是以冒号『:』作為字段的分隔符,共分為四欄,每一字段的意義是:

  1. 組名:

    就是組名啦!

  2. 群組密碼:

    通常不需要配置,這個配置通常是給『群組管理者』使用的,目前很少有這個機會配置群組管理者啦! 同樣的,密碼已經移動到 /etc/gshadow 去,是以這個字段隻會存在一個『x』而已;

  3. GID:

    就是群組的 ID 啊。我們 /etc/passwd 第四個字段使用的 GID 對應的群組名,就是由這裡對應出來的!

  4. 此群組支援的賬号名稱:

    我們知道一個賬号可以加入多個群組,那某個賬号想要加入此群組時,将該賬号填入這個字段即可。 舉例來說,如果我想要讓 dmtsai 也加入 root 這個群組,那麼在第一行的最後面加上『,dmtsai』,注意不要有空格, 使成為『 root:x:0:root,dmtsai 』就可以啰~

談完了 /etc/passwd, /etc/shadow, /etc/group 之後,我們可以使用一個簡單的圖示來了解一下 UID / GID 與密碼之間的關系, 圖示如下。其實重點是 /etc/passwd 啦,其他相關的資料都是根據這個檔案的字段去找尋出來的。 下圖中, root 的 UID 是 0 ,而 GID 也是 0 ,去找 /etc/group 可以知道 GID 為 0 時的組名就是 root 哩。 至于密碼的尋找中,會找到 /etc/shadow 與 /etc/passwd 内同賬号名稱的那一行,就是密碼相關資料啰。

第十四章、Linux 賬号管理與 ACL 權限配置

圖 1.3.1 、賬号相關檔案之間的 UID/GID 與密碼相關性示意圖

至于在 /etc/group 比較重要的特色在于第四欄啦,因為每個使用者都可以擁有多個支援的群組,這就好比在學校念書的時候, 我們可以加入多個社團一樣! ^_^。不過這裡你或許會覺得奇怪的,那就是:『假如我同時加入多個群組,那麼我在作業的時候,到底是以那個群組為準?』 底下我們就來談一談這個『有效群組』的概念。

  • 有效群組(effective group)與初始群組(initial group)

還記得每個使用者在他的 /etc/passwd 裡面的第四欄有所謂的 GID 吧?那個 GID 就是所謂的『初始群組 (initial group) 』!也就是說,當使用者一登陸系統,立刻就擁有這個群組的相關權限的意思。 舉例來說,我們上面提到 dmtsai 這個使用者的 /etc/passwd 與 /etc/group 還有 /etc/gshadow 相關的内容如下:

[[email protected] ~]# usermod -G users dmtsai  <==先配置好次要群組
[[email protected] ~]# grep dmtsai /etc/passwd /etc/group /etc/gshadow
/etc/passwd:dmtsai:x:503:504::/home/dmtsai:/bin/bash
/etc/group:users:x:100:dmtsai  <==次要群組的配置
/etc/group:dmtsai:x:504:       <==因為是初始群組,是以第四字段不需要填入賬号
/etc/gshadow:users:::dmtsai    <==次要群組的配置
/etc/gshadow:dmtsai:!::
      

仔細看到上面這個表格,在 /etc/passwd 裡面,dmtsai 這個使用者所屬的群組為 GID=504 ,搜尋一下 /etc/group 得到 504 是那個名為 dmtsai 的群組啦!這就是 initial group。因為是初始群組, 使用者一登陸就會主動取得,不需要在 /etc/group 的第四個字段寫入該賬号的!

但是非 initial group 的其他群組可就不同了。舉上面這個例子來說,我将 dmtsai 加入 users 這個群組當中,由于 users 這個群組并非是 dmtsai 的初始群組,是以, 我必須要在 /etc/group 這個檔案中,找到 users 那一行,并且将 dmtsai 這個賬号加入第四欄, 這樣 dmtsai 才能夠加入 users 這個群組啊。

那麼在這個例子當中,因為我的 dmtsai 賬号同時支援 dmtsai 與 users 這兩個群組, 是以,在讀取/寫入/運作檔案時,針對群組部分,隻要是 users 與 dmtsai 這兩個群組擁有的功能, 我 dmtsai 這個使用者都能夠擁有喔!這樣瞭呼?不過,這是針對已經存在的檔案而言, 如果今天我要建立一個新的檔案或者是新的目錄,請問一下,新檔案的群組是 dmtsai 還是 users ?呵呵!這就得要檢查一下當時的有效群組了 (effective group)。

  • groups: 有效與支援群組的觀察

如果我以 dmtsai 這個使用者的身份登陸後,該如何知道我所有支援的群組呢? 很簡單啊,直接輸入 groups 就可以了!注意喔,是 groups 有加 s 呢!結果像這樣:

[[email protected] ~]$ groups
dmtsai users
      

在這個輸出的資訊中,可知道 dmtsai 這個使用者同時屬于 dmtsai 及 users 這個兩個群組,而且, 第一個輸出的群組即為有效群組 (effective group) 了。 也就是說,我的有效群組為 dmtsai 啦~此時,如果我以 touch 去建立一個新檔,例如: 『 touch test 』,那麼這個檔案的擁有者為 dmtsai ,而且群組也是 dmtsai 的啦。

[[email protected] ~]$ touch test
[[email protected] ~]$ ll
-rw-rw-r-- 1 dmtsai dmtsai 0 Feb 24 17:26 test
      

這樣是否可以了解什麼是有效群組了?通常有效群組的作用是在建立檔案啦!那麼有效群組是否能夠變換?

  • newgrp: 有效群組的切換

那麼如何變更有效群組呢?就使用 newgrp 啊!不過使用 newgrp 是有限制的,那就是你想要切換的群組必須是你已經有支援的群組。舉例來說, dmtsai 可以在 dmtsai/users 這兩個群組間切換有效群組,但是 dmtsai 無法切換有效群組成為 sshd 啦!使用的方式如下:

[[email protected] ~]$ newgrp users
[[email protected] ~]$ groups
users dmtsai
[[email protected] ~]$ touch test2
[[email protected] ~]$ ll
-rw-rw-r-- 1 dmtsai dmtsai 0 Feb 24 17:26 test
-rw-r--r-- 1 dmtsai users  0 Feb 24 17:33 test2
      

此時,dmtsai 的有效群組就成為 users 了。 我們額外的來讨論一下 newgrp 這個指令,這個指令可以變更目前使用者的有效群組, 而且是另外以一個 shell 來提供這個功能的喔,是以,以上面的例子來說, dmtsai 這個使用者目前是以另一個 shell 登陸的,而且新的 shell 給予 dmtsai 有效 GID 為 users 就是了。如果以圖示來看就是如下所示:

第十四章、Linux 賬号管理與 ACL 權限配置

圖 1.3.2 、newgrp 的運作示意圖

雖然使用者的環境配置(例如環境變量等等其他資料)不會有影響,但是使用者的『群組權限』将會重新被計算。 但是需要注意,由于是新取得一個 shell ,是以如果你想要回到原本的環境中,請輸入 exit 回到原本的 shell 喔!

既然如此,也就是說,隻要我的使用者有支援的群組就是能夠切換成為有效群組!好了, 那麼如何讓一個賬号加入不同的群組就是問題的所在啰。你要加入一個群組有兩個方式,一個是透過系統管理者 (root) 利用 usermod 幫你加入,如果 root 太忙了而且你的系統有配置群組管理者,那麼你可以透過群組管理者以 gpasswd 幫你加入他所管理的群組中!詳細的作法留待下一小節再來介紹啰!

  • /etc/gshadow

剛剛講了很多關于『有效群組』的概念,另外,也提到 newgrp 這個指令的用法, 但是,如果 /etc/gshadow 這個配置沒有搞懂得話,那麼 newgrp 是無法動作的呢! 鳥哥測試機的 /etc/gshadow 的内容有點像這樣:

[[email protected] ~]# head -n 4 /etc/gshadow
root:::root
bin:::root,bin,daemon
daemon:::root,bin,daemon
sys:::root,bin,adm
      

這個檔案内同樣還是使用冒号『:』來作為字段的分隔字元,而且你會發現,這個檔案幾乎與 /etc/group 一模一樣啊!是這樣沒錯~不過,要注意的大概就是第二個字段吧~第二個字段是密碼欄, 如果密碼欄上面是『!』時,表示該群組不具有群組管理者!至于第四個字段也就是支援的賬号名稱啰~ 這四個字段的意義為:

  1. 組名
  2. 密碼欄,同樣的,開頭為 ! 表示無合法密碼,是以無群組管理者
  3. 群組管理者的賬号 (相關資訊在 gpasswd 中介紹)
  4. 該群組的所屬賬号 (與 /etc/group 内容相同!)

以系統管理者的角度來說,這個 gshadow 最大的功能就是建立群組管理者啦! 那麼什麼是群組管理者呢?由于系統上面的賬号可能會很多,但是我們 root 可能平時太忙碌,是以當有使用者想要加入某些群組時, root 或許會沒有空管理。此時如果能夠建立群組管理者的話,那麼該群組管理者就能夠将那個賬号加入自己管理的群組中! 可以免去 root 的忙碌啦!不過,由于目前有類似 sudo 之類的工具, 是以這個群組管理者的功能已經很少使用了。我們會在後續的 gpasswd 中介紹這個實作。

第十四章、Linux 賬号管理與 ACL 權限配置

賬号管理

好啦!既然要管理賬号,當然是由新增與移除使用者開始的啰~底下我們就分别來談一談如何新增、 移除與更改使用者的相關資訊吧~

第十四章、Linux 賬号管理與 ACL 權限配置

新增與移除使用者: useradd, 相關配置檔案, passwd, usermod, userdel

要如何在 Linux 的系統新增一個使用者啊?呵呵~真是太簡單了~我們登陸系統時會輸入 (1)賬号與 (2)密碼, 是以建立一個可用的賬号同樣的也需要這兩個資料。那賬号可以使用 useradd 來建立使用者,密碼的給予則使用 passwd 這個指令!這兩個指令下達方法如下:

  • useradd
[[email protected] ~]# useradd [-u UID] [-g 初始群組] [-G 次要群組] [-mM]\
>  [-c 說明欄] [-d 家目錄絕對路徑] [-s shell] 使用者賬号名
選項與參數:
-u  :後面接的是 UID ,是一組數字。直接指定一個特定的 UID 給這個賬号;
-g  :後面接的那個組名就是我們上面提到的 initial group 啦~
      該群組的 GID 會被放置到 /etc/passwd 的第四個字段内。
-G  :後面接的組名則是這個賬号還可以加入的群組。
      這個選項與參數會修改 /etc/group 内的相關資料喔!
-M  :強制!不要建立使用者家目錄!(系統賬号預設值)
-m  :強制!要建立使用者家目錄!(一般賬号預設值)
-c  :這個就是 /etc/passwd 的第五欄的說明内容啦~可以随便我們配置的啦~
-d  :指定某個目錄成為家目錄,而不要使用預設值。務必使用絕對路徑!
-r  :建立一個系統的賬号,這個賬号的 UID 會有限制 (參考 /etc/login.defs)
-s  :後面接一個 shell ,若沒有指定則預設是 /bin/bash 的啦~
-e  :後面接一個日期,格式為『YYYY-MM-DD』此項目可寫入 shadow 第八字段,
      亦即賬号失效日的配置項目啰;
-f  :後面接 shadow 的第七字段項目,指定密碼是否會失效。0為立刻失效,
      -1 為永遠不失效(密碼隻會過期而強制于登陸時重新配置而已。)

範例一:完全參考預設值建立一個使用者,名稱為 vbird1
[[email protected] ~]# useradd vbird1
[[email protected] ~]# ll -d /home/vbird1
drwx------ 4 vbird1 vbird1 4096 Feb 25 09:38 /home/vbird1
# 預設會建立使用者家目錄,且權限為 700 !這是重點!

[[email protected] ~]# grep vbird1 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird1:x:504:505::/home/vbird1:/bin/bash
/etc/shadow:vbird1:!!:14300:0:99999:7:::
/etc/group:vbird1:x:505:    <==預設會建立一個與賬号一模一樣的群組名
      

其實系統已經幫我們規定好非常多的預設值了,是以我們可以簡單的使用『 useradd 賬号 』來建立使用者即可。 CentOS 這些預設值主要會幫我們處理幾個項目:

  • 在 /etc/passwd 裡面建立一行與賬号相關的資料,包括建立 UID/GID/家目錄等;
  • 在 /etc/shadow 裡面将此賬号的密碼相關參數填入,但是尚未有密碼;
  • 在 /etc/group 裡面加入一個與賬号名稱一模一樣的組名;
  • 在 /home 底下建立一個與賬号同名的目錄作為使用者家目錄,且權限為 700

由于在 /etc/shadow 内僅會有密碼參數而不會有加密過的密碼資料,是以我們在建立使用者賬号時, 還需要使用『 passwd 賬号 』來給予密碼才算是完成了使用者建立的流程。如果由于特殊需求而需要改變使用者相關參數時, 就得要透過上述表格中的選項來進行建立了,參考底下的案例:

範例二:假設我已知道我的系統當中有個組名為 users ,且 UID 700 并不存在,
        請用 users 為初始群組,以及 uid 為 700 來建立一個名為 vbird2 的賬号
[[email protected] ~]# useradd -u 700 -g users vbird2
[[email protected] ~]# ll -d /home/vbird2
drwx------ 4 vbird2 users 4096 Feb 25 09:59 /home/vbird2

[[email protected] ~]# grep vbird2 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird2:x:700:100::/home/vbird2:/bin/bash
/etc/shadow:vbird2:!!:14300:0:99999:7:::
# 看一下,UID 與 initial group 确實改變成我們需要的了!
      

在這個範例中,我們建立的是指定一個已經存在的群組作為使用者的初始群組,因為群組已經存在, 是以在 /etc/group 裡面就不會主動的建立與賬号同名的群組了! 此外,我們也指定了特殊的 UID 來作為使用者的專屬 UID 喔!了解了一般賬号後,我們來瞧瞧那啥是系統賬号 (system account) 吧!

範例三:建立一個系統賬号,名稱為 vbird3
[[email protected] ~]# useradd -r vbird3
[[email protected] ~]# ll -d /home/vbird3
ls: /home/vbird3: No such file or directory  <==不會主動建立家目錄

[[email protected] ~]# grep vbird3 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird3:x:100:103::/home/vbird3:/bin/bash
/etc/shadow:vbird3:!!:14300::::::
/etc/group:vbird3:x:103:
      

我們在談到 UID 的時候曾經說過一般賬号應該是 500 号以後,那使用者自己建立的系統賬号則一般是由 100 号以後起算的。 是以在這裡我們加上 -r 這個選項以後,系統就會主動将賬号與賬号同名群組的 UID/GID 都指定小于 500 以下, 在本案例中則是使用 100(UID) 與 103(GID) 啰!此外,由于系統賬号主要是用來進行運作系統所需服務的權限配置, 是以系統賬号預設都不會主動建立家目錄的!

由這幾個範例我們也會知道,使用 useradd 建立使用者賬号時,其實會更改不少地方,至少我們就知道底下幾個檔案:

  • 使用者賬号與密碼參數方面的檔案:/etc/passwd, /etc/shadow
  • 使用者群組相關方面的檔案:/etc/group, /etc/gshadow
  • 使用者的家目錄:/home/賬号名稱

那請教一下,你有沒有想過,為何『 useradd vbird1 』會主動在 /home/vbird1 建立起使用者的家目錄?家目錄内有什麼資料且來自哪裡?為何預設使用的是 /bin/bash 這個 shell ?為何密碼字段已經都規範好了 (0:99999:7 那一串)?呵呵!這就得要說明一下 useradd 所使用的參考檔案啰!

  • useradd 參考檔

其實 useradd 的預設值可以使用底下的方法呼叫出來:

[[email protected] ~]# useradd -D
GROUP=100		<==預設的群組
HOME=/home		<==預設的家目錄所在目錄
INACTIVE=-1		<==密碼失效日,在 shadow 内的第 7 欄
EXPIRE=			<==賬号失效日,在 shadow 内的第 8 欄
SHELL=/bin/bash		<==預設的 shell
SKEL=/etc/skel		<==使用者家目錄的内容資料參考目錄
CREATE_MAIL_SPOOL=yes   <==是否主動幫使用者建立郵件信箱(mailbox)
      

這個資料其實是由 /etc/default/useradd 呼叫出來的!你可以自行用 vim 去觀察該檔案的内容。搭配上頭剛剛談過的範例一的運作結果,上面這些配置項目所造成的行為分别是:

  • GROUP=100:建立賬号的初始群組使用 GID 為 100 者

    系統上面 GID 為 100 者即是 users 這個群組,此配置項目指的就是讓新設使用者賬号的初始群組為 users 這一個的意思。 但是我們知道 CentOS 上面并不是這樣的,在 CentOS 上面預設的群組為與賬号名相同的群組。 舉例來說, vbird1 的初始群組為 vbird1 。怎麼會這樣啊?這是因為針對群組的角度有兩種不同的機制所緻, 這兩種機制分别是:

    • 私有群組機制:系統會建立一個與賬号一樣的群組給使用者作為初始群組。 這種群組的配置機制會比較有保密性,這是因為使用者都有自己的群組,而且家目錄權限将會配置為 700 (僅有自己可進入自己的家目錄) 之故。使用這種機制将不會參考 GROUP=100 這個配置值。代表性的 distributions 有 RHEL, Fedora, CentOS 等;
    • 公共群組機制:就是以 GROUP=100 這個配置值作為建立賬号的初始群組,是以每個賬号都屬于 users 這個群組, 且預設家目錄通常的權限會是『 drwxr-xr-x ... username users ... 』,由于每個賬号都屬于 users 群組,是以大家都可以互相分享家目錄内的資料之故。代表 distributions 如 SuSE等。
    由于我們的 CentOS 使用私有群組機制,是以這個配置項目是不會生效的!不要太緊張啊!
  • HOME=/home:使用者家目錄的基準目錄(basedir)

    使用者的家目錄通常是與賬号同名的目錄,這個目錄将會擺放在此配置值的目錄後。是以 vbird1 的家目錄就會在 /home/vbird1/ 了!很容易了解吧!

  • INACTIVE=-1:密碼過期後是否會失效的配置值

    我們在 shadow 檔案結構當中談過,第七個字段的配置值将會影響到密碼過期後, 在多久時間内還可使用舊密碼登陸。這個項目就是在指定該日數啦!如果是 0 代表密碼過期立刻失效, 如果是 -1 則是代表密碼永遠不會失效,如果是數字,如 30 ,則代表過期 30 天後才失效。

  • EXPIRE=:賬号失效的日期

    就是 shadow 内的第八字段,你可以直接配置賬号在哪個日期後就直接失效,而不理會密碼的問題。 通常不會配置此項目,但如果是付費的會員制系統,或許這個字段可以配置喔!

  • SHELL=/bin/bash:預設使用的 shell 程式檔案名

    系統預設的 shell 就寫在這裡。假如你的系統為 mail server ,你希望每個賬号都隻能使用 email 的收發信件功能, 而不許使用者登陸系統取得 shell ,那麼可以将這裡配置為 /sbin/nologin ,如此一來,建立的使用者預設就無法登陸! 也免去後續使用 usermod 進行修改的手續!

  • SKEL=/etc/skel:使用者家目錄參考基準目錄

    這個咚咚就是指定使用者家目錄的參考基準目錄啰~舉我們的範例一為例, vbird1 家目錄 /home/vbird1 内的各項資料,都是由 /etc/skel 所複制過去的~是以呢,未來如果我想要讓新增使用者時,該使用者的環境變量 ~/.bashrc 就配置妥當的話,您可以到 /etc/skel/.bashrc 去編輯一下,也可以建立 /etc/skel/www 這個目錄,那麼未來新增使用者後,在他的家目錄下就會有 www 那個目錄了!這樣瞭呼?

  • CREATE_MAIL_SPOOL=yes:建立使用者的 mailbox

    你可以使用『 ll /var/spool/mail/vbird1 』看一下,會發現有這個檔案的存在喔!這就是使用者的郵件信箱!

除了這些基本的賬号配置值之外, UID/GID 還有密碼參數又是在哪裡參考的呢?那就得要看一下 /etc/login.defs 啦! 這個檔案的内容有點像底下這樣:

MAIL_DIR        /var/spool/mail	<==使用者預設郵件信箱放置目錄

PASS_MAX_DAYS   99999	<==/etc/shadow 内的第 5 欄,多久需變更密碼日數
PASS_MIN_DAYS   0	<==/etc/shadow 内的第 4 欄,多久不可重新配置密碼日數
PASS_MIN_LEN    5	<==密碼最短的字元長度,已被 pam 子產品取代,失去效用!
PASS_WARN_AGE   7	<==/etc/shadow 内的第 6 欄,過期前會警告的日數

UID_MIN         500	<==使用者最小的 UID,意即小于 500 的 UID 為系統保留
UID_MAX       60000	<==使用者能夠用的最大 UID
GID_MIN         500	<==使用者自定義組的最小 GID,小于 500 為系統保留
GID_MAX       60000	<==使用者自定義組的最大 GID

CREATE_HOME     yes	<==在不加 -M 及 -m 時,是否主動建立使用者家目錄?
UMASK           077     <==使用者家目錄建立的 umask ,是以權限會是 700
USERGROUPS_ENAB yes     <==使用 userdel 删除時,是否會删除初始群組
MD5_CRYPT_ENAB yes      <==密碼是否經過 MD5 的加密機制處理
      

這個檔案規範的資料則是如下所示:

  • mailbox 所在目錄:

    使用者的預設 mailbox 檔案放置的目錄在 /var/spool/mail,是以 vbird1 的 mailbox 就是在 /var/spool/mail/vbird1 啰!

  • shadow 密碼第 4, 5, 6 字段内容:

    透過 PASS_MAX_DAYS 等等配置值來指定的!是以你知道為何預設的 /etc/shadow 内每一行都會有『 0:99999:7 』的存在了嗎?^_^!不過要注意的是,由于目前我們登陸時改用 PAM 子產品來進行密碼檢驗,是以那個 PASS_MIN_LEN 是失效的!

  • UID/GID 指定數值:

    雖然 Linux 核心支援的賬号可高達 232 這麼多個,不過一部主機要作出這麼多賬号在管理上也是很麻煩的! 是以在這裡就針對 UID/GID 的範圍進行規範就是了。上表中的 UID_MIN 指的就是可登陸系統的一般賬号的最小 UID ,至于 UID_MAX 則是最大 UID 之意。

    要注意的是,系統給予一個賬号 UID 時,他是 (1)先參考 UID_MIN 配置值取得最小數值; (2)由 /etc/passwd 搜尋最大的 UID 數值, 将 (1) 與 (2) 相比,找出最大的那個再加一就是新賬号的 UID 了。我們上面已經作出 UID 為 700 的 vbird2 , 如果再使用『 useradd vbird4 』時,你猜 vbird4 的 UID 會是多少?答案是: 701 。 是以中間的 505~699 的号碼就空下來啦!

    而如果我是想要建立系統用的賬号,是以使用 useradd -r sysaccount 這個 -r 的選項時,就會找『比 500 小的最大的那個 UID + 1 』就是了。 ^_^

  • 使用者家目錄配置值:

    為何我們系統預設會幫使用者建立家目錄?就是這個『CREATE_HOME = yes』的配置值啦!這個配置值會讓你在使用 useradd 時, 主動加入『 -m 』這個産生家目錄的選項啊!如果不想要建立使用者家目錄,就隻能強制加上『 -M 』的選項在 useradd 指令運作時啦!至于建立家目錄的權限配置呢?就透過 umask 這個配置值啊!因為是 077 的預設配置,是以使用者家目錄預設權限才會是『 drwx------ 』哩!

  • 使用者删除與密碼配置值:

    使用『USERGROUPS_ENAB yes』這個配置值的功能是: 如果使用 userdel 去删除一個賬号時,且該賬号所屬的初始群組已經沒有人隸屬于該群組了, 那麼就删除掉該群組,舉例來說,我們剛剛有建立 vbird4 這個賬号,他會主動建立 vbird4 這個群組。 若 vbird4 這個群組并沒有其他賬号将他加入支援的情況下,若使用 userdel vbird4 時,該群組也會被删除的意思。 至于『MD5_CRYPT_ENAB yes』則表示使用 MD5 來加密密碼明文,而不使用舊式的 DES(注2) 。

現在你知道啦,使用 useradd 這支程式在建立 Linux 上的賬号時,至少會參考:

  • /etc/default/useradd
  • /etc/login.defs
  • /etc/skel/*

這些檔案,不過,最重要的其實是建立 /etc/passwd, /etc/shadow, /etc/group, /etc/gshadow 還有使用者家目錄就是了~是以,如果你了解整個系統運作的狀态,也是可以手動直接修改這幾個檔案就是了。 OK!賬号建立了,接下來處理一下使用者的密碼吧!

  • passwd

剛剛我們講到了,使用 useradd 建立了賬号之後,在預設的情況下,該賬号是暫時被封鎖的, 也就是說,該賬号是無法登陸的,你可以去瞧一瞧 /etc/shadow 内的第二個字段就曉得啰~ 那該如何是好?怕什麼?直接給他配置新密碼就好了嘛!對吧~配置密碼就使用 passwd 啰!

[[email protected] ~]# passwd [--stdin]  <==所有人均可使用來改自己的密碼
[[email protected] ~]# passwd [-l] [-u] [--stdin] [-S] \
>  [-n 日數] [-x 日數] [-w 日數] [-i 日期] 賬号 <==root 功能
選項與參數:
--stdin :可以透過來自前一個管線的資料,作為密碼輸入,對 shell script 有幫助!
-l  :是 Lock 的意思,會将 /etc/shadow 第二欄最前面加上 ! 使密碼失效;
-u  :與 -l 相對,是 Unlock 的意思!
-S  :列出密碼相關參數,亦即 shadow 檔案内的大部分資訊。
-n  :後面接天數,shadow 的第 4 字段,多久不可修改密碼天數
-x  :後面接天數,shadow 的第 5 字段,多久内必須要更動密碼
-w  :後面接天數,shadow 的第 6 字段,密碼過期前的警告天數
-i  :後面接『日期』,shadow 的第 7 字段,密碼失效日期

範例一:請 root 給予 vbird2 密碼
[[email protected] ~]# passwd vbird2
Changing password for user vbird2.
New UNIX password: <==這裡直接輸入新的密碼,螢幕不會有任何反應
BAD PASSWORD: it is WAY too short <==密碼太簡單或過短的錯誤!
Retype new UNIX password:  <==再輸入一次同樣的密碼
passwd: all authentication tokens updated successfully.  <==竟然還是成功修改了!
      

root 果然是最偉大的人物!當我們要給予使用者密碼時,透過 root 來配置即可。 root 可以配置各式各樣的密碼,系統幾乎一定會接受!是以您瞧瞧,如同上面的範例一,明明鳥哥輸入的密碼太短了, 但是系統依舊可接受 vbird2 這樣的密碼配置。這個是 root 幫忙配置的結果,那如果是使用者自己要改密碼呢? 包括 root 也是這樣修改的喔!

範例二:用 vbird2 登陸後,修改 vbird2 自己的密碼
[[email protected] ~]$ passwd   <==後面沒有加賬号,就是改自己的密碼!
Changing password for user vbird2.
Changing password for vbird2
(current) UNIX password: <==這裡輸入『原有的舊密碼』
New UNIX password: <==這裡輸入新密碼
BAD PASSWORD: it is based on a dictionary word <==密碼檢驗不通過,請再想個新密碼
New UNIX password: <==這裡再想個來輸入吧
Retype new UNIX password: <==通過密碼驗證!是以重複這個密碼的輸入
passwd: all authentication tokens updated successfully. <==有無成功看關鍵詞
      

passwd 的使用真的要很注意,尤其是 root 先生啊!鳥哥在課堂上每次講到這裡,說是要幫自己的一般賬号建立密碼時, 有一小部分的學生就是會忘記加上賬号,結果就變成改變 root 自己的密碼,最後.... root 密碼就這樣不見去!唉~ 要幫一般賬号建立密碼需要使用『 passwd 賬号 』的格式,使用『 passwd 』表示修改自己的密碼!拜托!千萬不要改錯!

與 root 不同的是,一般賬号在更改密碼時需要先輸入自己的舊密碼 (亦即 current 那一行),然後再輸入新密碼 (New 那一行)。 要注意的是,密碼的規範是非常嚴格的,尤其新的 distributions 大多使用 PAM 子產品來進行密碼的檢驗,包括太短、 密碼與賬号相同、密碼為字典常見字元串等,都會被 PAM 子產品檢查出來而拒絕修改密碼,此時會再重複出現『 New 』這個關鍵詞! 那時請再想個新密碼!若出現『 Retype 』才是你的密碼被接受了!重複輸入新密碼并且看到『 successfully 』這個關鍵詞時才是修改密碼成功喔!

Tips:

與一般使用者不同的是, root 并不需要知道舊密碼就能夠幫使用者或 root 自己建立新密碼! 但如此一來有困擾~就是如果你的親密夫妻老是告訴你『我的密碼真難記,幫我配置簡單一點的!』時, 千萬不要妥協啊!這是為了系統安全...

第十四章、Linux 賬号管理與 ACL 權限配置

為何使用者要設訂自己的密碼會這麼麻煩啊?這是因為密碼的安全性啦!如果密碼配置太簡單, 一些有心人士就能夠很簡單的猜到你的密碼,如此一來人家就可能使用你的一般賬号登陸你的主機或使用其他主機資源, 對主機的維護會造成困擾的!是以新的 distributions 是使用較嚴格的 PAM 子產品來管理密碼,這個管理的機制寫在 /etc/pam.d/passwd 當中。而該檔案與密碼有關的測試子產品就是使用:pam_cracklib.so,這個子產品會檢驗密碼相關的資訊, 并且取代 /etc/login.defs 内的 PASS_MIN_LEN 的配置啦!關于 PAM 我們在本章後面繼續介紹,這裡先談一下, 理論上,你的密碼最好符合如下要求:

  • 密碼不能與賬号相同;
  • 密碼盡量不要選用字典裡面會出現的字元串;
  • 密碼需要超過 8 個字元;
  • 密碼不要使用個人資訊,如身份證、手機号碼、其他電話号碼等;
  • 密碼不要使用簡單的關系式,如 1+1=2, Iamvbird 等;
  • 密碼盡量使用大小寫字元、數字、特殊字元($,_,-等)的組合。

為了友善系統管理,新版的 passwd 還加入了很多創意選項喔!鳥哥個人認為最好用的大概就是這個『 --stdin 』了! 舉例來說,你想要幫 vbird2 變更密碼成為 abc543CC ,可以這樣下達指令呢!

範例三:使用 standard input 建立使用者的密碼
[[email protected] ~]# echo "abc543CC" | passwd --stdin vbird2
Changing password for user vbird2.
passwd: all authentication tokens updated successfully.
      

這個動作會直接更新使用者的密碼而不用再次的手動輸入!好處是友善處理,缺點是這個密碼會保留在指令中, 未來若系統被攻破,人家可以在 /root/.bash_history 找到這個密碼呢!是以這個動作通常僅用在 shell script 的大量建立使用者賬号當中!要注意的是,這個選項并不存在所有 distributions 版本中, 請使用 man passwd 确認你的 distribution 是否有支援此選項喔!

如果你想要讓 vbird2 的密碼具有相當的守則,舉例來說你要讓 vbird2 每 60 天需要變更密碼, 密碼過期後 10 天未使用就宣告密碼失效,那該如何處理?

範例四:管理 vbird2 的密碼使具有 60 天變更、10 天密碼失效的配置
[[email protected] ~]# passwd -S vbird2
vbird2 PS 2009-02-26 0 99999 7 -1 (Password set, MD5 crypt.)
# 上面說明密碼建立時間 (2009-02-26)、0 最小天數、99999 變更天數、7 警告日數
# 與密碼不會失效 (-1) 。

[[email protected] ~]# passwd -x 60 -i 10 vbird2
[[email protected] ~]# passwd -S vbird2
vbird2 PS 2009-02-26 0 60 7 10 (Password set, MD5 crypt.)
      

那如果我想要讓某個賬号暫時無法使用密碼登陸主機呢?舉例來說, vbird2 這家夥最近老是胡亂在主機亂來, 是以我想要暫時讓她無法登陸的話,最簡單的方法就是讓她的密碼變成不合法 (shadow 第 2 字段長度變掉)! 處理的方法就更簡單的!

範例五:讓 vbird2 的賬号失效,觀察完畢後再讓她失效
[[email protected] ~]# passwd -l vbird2
[[email protected] ~]# passwd -S vbird2
vbird2 LK 2009-02-26 0 60 7 10 (Password locked.)
# 嘿嘿!狀态變成『 LK, Lock 』了啦!無法登陸喔!
[[email protected] ~]# grep vbird2 /etc/shadow
vbird2:!!$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10::
# 其實隻是在這裡加上 !! 而已!

[[email protected] ~]# passwd -u vbird2
[[email protected] ~]# grep vbird2 /etc/shadow
vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10::
# 密碼字段恢複正常!
      

是否很有趣啊!您可以自行管理一下你的賬号的密碼相關參數喔!接下來讓我們用更簡單的方法來查閱密碼參數喔! 

  • chage

除了使用 passwd -S 之外,有沒有更詳細的密碼參數顯示功能呢?有的!那就是 chage 了! 他的用法如下:

[[email protected] ~]# chage [-ldEImMW] 賬号名
選項與參數:
-l :列出該賬号的詳細密碼參數;
-d :後面接日期,修改 shadow 第三字段(最近一次更改密碼的日期),格式 YYYY-MM-DD
-E :後面接日期,修改 shadow 第八字段(賬号失效日),格式 YYYY-MM-DD
-I :後面接天數,修改 shadow 第七字段(密碼失效日期)
-m :後面接天數,修改 shadow 第四字段(密碼最短保留天數)
-M :後面接天數,修改 shadow 第五字段(密碼多久需要進行變更)
-W :後面接天數,修改 shadow 第六字段(密碼過期前警告日期)

範例一:列出 vbird2 的詳細密碼參數
[[email protected] ~]# chage -l vbird2
Last password change                               : Feb 26, 2009
Password expires                                   : Apr 27, 2009
Password inactive                                  : May 07, 2009
Account expires                                    : never
Minimum number of days between password change     : 0
Maximum number of days between password change     : 60
Number of days of warning before password expires  : 7
      

我們在 passwd 的介紹中談到了處理 vbird2 這個賬号的密碼屬性流程,使用 passwd -S 卻無法看到很清楚的說明。如果使用 chage 那可就明白多了!如上表所示,我們可以清楚的知道 vbird2 的詳細參數呢! 如果想要修改其他的配置值,就自己參考上面的選項,或者自行 man chage 一下吧!^_^

chage 有一個功能很不錯喔!如果你想要讓『使用者在第一次登陸時, 強制她們一定要更改密碼後才能夠使用系統資源』,可以利用如下的方法來處理的!

範例二:建立一個名為 agetest 的賬号,該賬号第一次登陸後使用預設密碼,
        但必須要更改過密碼後,使用新密碼才能夠登陸系統使用 bash 環境
[[email protected] ~]# useradd agetest
[[email protected] ~]# echo "agetest" | passwd --stdin agetest
[[email protected] ~]# chage -d 0 agetest
# 此時此賬号的密碼建立時間會被改為 1970/1/1 ,是以會有問題!

範例三:嘗試以 agetest 登陸的情況
You are required to change your password immediately (root enforced)
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user agetest.
Changing password for agetest
(current) UNIX password:  <==這個賬号被強制要求必須要改密碼!
      

非常有趣吧!你會發現 agetest 這個賬号在第一次登陸時可以使用與賬号同名的密碼登陸, 但登陸時就會被要求立刻更改密碼,更改密碼完成後就會被踢出系統。再次登陸時就能夠使用新密碼登陸了! 這個功能對學校老師非常有幫助!因為我們不想要知道學生的密碼,那麼在初次上課時就使用與學号相同的賬号/密碼給學生, 讓她們登陸時自行配置她們的密碼,如此一來就能夠避免其他同學随意使用别人的賬号,也能夠保證學生知道如何更改自己的密碼! 

  • usermod

所謂這『人有失手,馬有亂蹄』,您說是吧?是以啰,當然有的時候會『不小心』在 useradd 的時候加入了錯誤的配置資料。或者是,在使用 useradd 後,發現某些地方還可以進行細部修改。 此時,當然我們可以直接到 /etc/passwd 或 /etc/shadow 去修改相對應字段的資料, 不過,Linux 也有提供相關的指令讓大家來進行賬号相關資料的微調呢~那就是 usermod 啰~

[[email protected] ~]# usermod [-cdegGlsuLU] username
選項與參數:
-c  :後面接賬号的說明,即 /etc/passwd 第五欄的說明欄,可以加入一些賬号的說明。
-d  :後面接賬号的家目錄,即修改 /etc/passwd 的第六欄;
-e  :後面接日期,格式是 YYYY-MM-DD 也就是在 /etc/shadow 内的第八個字段資料啦!
-f  :後面接天數,為 shadow 的第七字段。
-g  :後面接初始群組,修改 /etc/passwd 的第四個字段,亦即是 GID 的字段!
-G  :後面接次要群組,修改這個使用者能夠支援的群組,修改的是 /etc/group 啰~
-a  :與 -G 合用,可『添加次要群組的支援』而非『配置』喔!
-l  :後面接賬号名稱。亦即是修改賬号名稱, /etc/passwd 的第一欄!
-s  :後面接 Shell 的實際檔案,例如 /bin/bash 或 /bin/csh 等等。
-u  :後面接 UID 數字啦!即 /etc/passwd 第三欄的資料;
-L  :暫時将使用者的密碼當機,讓他無法登陸。其實僅改 /etc/shadow 的密碼欄。
-U  :将 /etc/shadow 密碼欄的 ! 拿掉,解凍啦!
      

如果你仔細的比對,會發現 usermod 的選項與 useradd 非常類似! 這是因為 usermod 也是用來微調 useradd 添加的使用者參數嘛!不過 usermod 還是有新增的選項, 那就是 -L 與 -U ,不過這兩個選項其實與 passwd 的 -l, -u 是相同的!而且也不見得會存在所有的 distribution 當中!接下來,讓我們談談一些變更參數的執行個體吧!

範例一:修改使用者 vbird2 的說明欄,加上『VBird's test』的說明。
[[email protected] ~]# usermod -c "VBird's test" vbird2
[[email protected] ~]# grep vbird2 /etc/passwd
vbird2:x:700:100:VBird's test:/home/vbird2:/bin/bash

範例二:使用者 vbird2 密碼在 2009/12/31 失效。
[[email protected] ~]# usermod -e "2009-12-31" vbird2
[[email protected] ~]# grep vbird2 /etc/shadow
vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10:14609:

範例三:我們建立 vbird3 這個系統賬号時并沒有給予家目錄,請建立他的家目錄
[[email protected] ~]# ll -d ~vbird3
ls: /home/vbird3: No such file or directory  <==确認一下,确實沒有家目錄的存在!
[[email protected] ~]# cp -a /etc/skel /home/vbird3
[[email protected] ~]# chown -R vbird3:vbird3 /home/vbird3
[[email protected] ~]# chmod 700 /home/vbird3
[[email protected] ~]# ll -a ~vbird3
drwx------  4 vbird3 vbird3 4096 Sep  4 18:15 .  <==使用者家目錄權限
drwxr-xr-x 11 root   root   4096 Feb 26 11:45 ..
-rw-r--r--  1 vbird3 vbird3   33 May 25  2008 .bash_logout
-rw-r--r--  1 vbird3 vbird3  176 May 25  2008 .bash_profile
-rw-r--r--  1 vbird3 vbird3  124 May 25  2008 .bashrc
drwxr-xr-x  3 vbird3 vbird3 4096 Sep  4 18:11 .kde
drwxr-xr-x  4 vbird3 vbird3 4096 Sep  4 18:15 .mozilla
# 使用 chown -R 是為了連同家目錄底下的使用者/群組屬性都一起變更的意思;
# 使用 chmod 沒有 -R ,是因為我們僅要修改目錄的權限而非内部檔案的權限!
      
  • userdel

這個功能就太簡單了,目的在删除使用者的相關資料,而使用者的資料有:

  • 使用者賬号/密碼相關參數:/etc/passwd, /etc/shadow
  • 使用者群組相關參數:/etc/group, /etc/gshadow
  • 使用者個人檔案資料: /home/username, /var/spool/mail/username..

整個指令的文法非常簡單:

[[email protected] ~]# userdel [-r] username
選項與參數:
-r  :連同使用者的家目錄也一起删除

範例一:删除 vbird2 ,連同家目錄一起删除
[[email protected] ~]# userdel -r vbird2
      

這個指令下達的時候要小心了!通常我們要移除一個賬号的時候,你可以手動的将 /etc/passwd 與 /etc/shadow 裡頭的該賬号取消即可!一般而言,如果該賬号隻是『暫時不激活』的話,那麼将 /etc/shadow 裡頭賬号失效日期 (第八字段) 配置為 0 就可以讓該賬号無法使用,但是所有跟該賬号相關的資料都會留下來! 使用 userdel 的時機通常是『你真的确定不要讓該使用者在主機上面使用任何資料了!』

另外,其實使用者如果在系統上面操作過一陣子了,那麼該使用者其實在系統内可能會含有其他檔案的。 舉例來說,他的郵件信箱 (mailbox) 或者是例行性工作排程 (crontab, 十六章) 之類的檔案。 是以,如果想要完整的将某個賬号完整的移除,最好可以在下達 userdel -r username 之前, 先以『 find / -user username 』查出整個系統内屬于 username 的檔案,然後再加以删除吧!

第十四章、Linux 賬号管理與 ACL 權限配置

使用者功能

不論是 useradd/usermod/userdel ,那都是系統管理者所能夠使用的指令, 如果我是一般身份使用者,那麼我是否除了密碼之外,就無法更改其他的資料呢? 當然不是啦!這裡我們介紹幾個一般身份使用者常用的賬号資料變更與查詢指令啰!

  • finger

finger 的中文字面意義是:『手指』或者是『指紋』的意思。這個 finger 可以查閱很多使用者相關的資訊喔! 大部分都是在 /etc/passwd 這個檔案裡面的資訊啦!我們就先來檢查檢查使用者資訊吧!

[[email protected] ~]# finger [-s] username
選項與參數:
-s  :僅列出使用者的賬号、全名、終端機代号與登陸時間等等;
-m  :列出與後面接的賬号相同者,而不是利用部分比對 (包括全名部分)

範例一:觀察 vbird1 的使用者相關賬号屬性
[[email protected] ~]# finger vbird1
Login: vbird1                           Name: (null)
Directory: /home/vbird1                 Shell: /bin/bash
Never logged in.
No mail.
No Plan.
      

由于 finger 類似指紋的功能,他會将使用者的相關屬性列出來!如上表所示,其實他列出來的幾乎都是 /etc/passwd 檔案裡面的東西。列出的資訊說明如下:

  • Login:為使用者賬号,亦即 /etc/passwd 内的第一字段;
  • Name:為全名,亦即 /etc/passwd 内的第五字段(或稱為批注);
  • Directory:就是家目錄了;
  • Shell:就是使用的 Shell 檔案所在;
  • Never logged in.:figner 還會調查使用者登陸主機的情況喔!
  • No mail.:調查 /var/spool/mail 當中的信箱資料;
  • No Plan.:調查 ~vbird1/.plan 檔案,并将該檔案取出來說明!

不過是否能夠查閱到 Mail 與 Plan 則與權限有關了!因為 Mail / Plan 都是與使用者自己的權限配置有關, root 當然可以查閱到使用者的這些資訊,但是 vbird1 就不見得能夠查到 vbird3 的資訊, 因為 /var/spool/mail/vbird3 與 /home/vbird3/ 的權限分别是 660, 700 ,那 vbird1 當然就無法查閱的到! 這樣解釋可以了解吧?此外,我們可以建立自己想要運作的預定計劃,當然,最多是給自己看的!可以這樣做:

範例二:利用 vbird1 建立自己的計劃檔
[[email protected] ~]$ echo "I will study Linux during this year." > ~/.plan
[[email protected] ~]$ finger vbird1
Login: vbird1                           Name: (null)
Directory: /home/vbird1                 Shell: /bin/bash
Never logged in.
No mail.
Plan:
I will study Linux during this year.

範例三:找出目前在系統上面登陸的使用者與登陸時間
[[email protected] ~]$ finger
Login     Name       Tty      Idle  Login Time   Office     Office Phone
root      root       tty1           Feb 26 09:53
vbird1               tty2           Feb 26 15:21
      

在範例三當中,我們發現輸出的資訊還會有 Office, Office Phone 等資訊,那這些資訊要如何記錄呢? 底下我們會介紹 chfn 這個指令!來看看如何修改使用者的 finger 資料吧!

  • chfn

chfn 有點像是: change finger 的意思!這玩意的使用方法如下:

[[email protected] ~]# chfn [-foph] [賬号名]
選項與參數:
-f  :後面接完整的大名;
-o  :您辦公室的房間号碼;
-p  :辦公室的電話号碼;
-h  :家裡的電話号碼!

範例一:vbird1 自己更改一下自己的相關資訊!
[[email protected] ~]$ chfn
Changing finger information for vbird1.
Password:                        <==确認身份,是以輸入自己的密碼
Name []: VBird Tsai test         <==輸入你想要呈現的全名
Office []: Dic in Ksu. Tainan    <==辦公室号碼
Office Phone []: 06-2727175#356  <==辦公室電話
Home Phone []: 06-1234567        <==家裡電話号碼

Finger information changed.
[[email protected] ~]$ grep vbird1 /etc/passwd
vbird1:x:504:505:VBird Tsai test,Dic in Ksu. Tainan,06-2727175#356,06-1234567:
/home/vbird1:/bin/bash
# 其實就是改到第五個字段,該字段裡面用多個『 , 』分隔就是了!

[[email protected] ~]$ finger vbird1
Login: vbird1                           Name: VBird Tsai test
Directory: /home/vbird1                 Shell: /bin/bash
Office: Dic in Ksu. Tainan              Office Phone: 06-2727175#356
Home Phone: 06-1234567
On since Thu Feb 26 15:21 (CST) on tty2
No mail.
Plan:
I will study Linux during this year.
# 就是上面特殊字型呈現的那些地方是由 chfn 所修改出來的!
      

這個指令說實在的,除非是你的主機有很多的使用者,否則倒真是用不着這個程式!這就有點像是 bbs 裡頭更改你『個人屬性』的那一個資料啦!不過還是可以自己玩一玩!尤其是用來提醒自己相關資料啦! ^_^

  • chsh

這就是 change shell 的簡寫!使用方法就更簡單了!

[[email protected] ~]$ chsh [-ls]
選項與參數:
-l  :列出目前系統上面可用的 shell ,其實就是 /etc/shells 的内容!
-s  :配置修改自己的 Shell 啰

範例一:用 vbird1 的身份列出系統上所有合法的 shell,并且指定 csh 為自己的 shell
[[email protected] ~]$ chsh -l
/bin/sh
/bin/bash
/sbin/nologin  <==所謂:合法不可登陸的 Shell 就是這玩意!
/bin/tcsh
/bin/csh       <==這就是 C shell 啦!
/bin/ksh
# 其實上面的資訊就是我們在 bash 中談到的 /etc/shells 啦!

[[email protected] ~]$ chsh -s /bin/csh; grep vbird1 /etc/passwd
Changing shell for vbird1.
Password:  <==确認身份,請輸入 vbird1 的密碼
Shell changed.
vbird1:x:504:505:VBird Tsai test,Dic in Ksu. Tainan,06-2727175#356,06-1234567:
/home/vbird1:/bin/csh

[[email protected] ~]$ chsh -s /bin/bash
# 測試完畢後,立刻改回來!

[[email protected] ~]$ ll $(which chsh)
-rws--x--x 1 root root 19128 May 25  2008 /usr/bin/chsh
      

不論是 chfn 與 chsh ,都是能夠讓一般使用者修改 /etc/passwd 這個系統檔案的!是以你猜猜,這兩個檔案的權限是什麼? 一定是 SUID 的功能啦!看到這裡,想到前面! 這就是 Linux 的學習方法~ ^_^

  • id

id 這個指令則可以查詢某人或自己的相關 UID/GID 等等的資訊,他的參數也不少,不過, 都不需要記~反正使用 id 就全部都列出啰~ ^_^

[[email protected] ~]# id [username]

範例一:查閱 root 自己的相關 ID 資訊!
[[email protected] ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),
10(wheel) context=root:system_r:unconfined_t:SystemLow-SystemHigh
# 上面資訊其實是同一行的資料!包括會顯示 UID/GID 以及支援的所有群組!
# 至于後面那個 context=... 則是 SELinux 的内容,先不要理會他!

範例二:查閱一下 vbird1 吧~
[[email protected] ~]# id vbird1
uid=504(vbird1) gid=505(vbird1) groups=505(vbird1) context=root:system_r:
unconfined_t:SystemLow-SystemHigh

[[email protected] ~]# id vbird100
id: vbird100: No such user  <== id 這個指令也可以用來判斷系統上面有無某賬号!
      
第十四章、Linux 賬号管理與 ACL 權限配置

新增與移除群組

OK!了解了賬号的新增、删除、更動與查詢後,再來我們可以聊一聊群組的相關内容了。 基本上,群組的内容都與這兩個檔案有關:/etc/group, /etc/gshadow。 群組的内容其實很簡單,都是上面兩個檔案的新增、修改與移除而已, 不過,如果再加上有效群組的概念,那麼 newgrp 與 gpasswd 則不可不知呢!

  • groupadd
[[email protected] ~]# groupadd [-g gid] [-r] 組名
選項與參數:
-g  :後面接某個特定的 GID ,用來直接給予某個 GID ~
-r  :建立系統群組啦!與 /etc/login.defs 内的 GID_MIN 有關。

範例一:建立一個群組,名稱為 group1
[[email protected] ~]# groupadd group1
[[email protected] ~]# grep group1 /etc/group /etc/gshadow
/etc/group:group1:x:702:
/etc/gshadow:group1:!::
# 群組的 GID 也是會由 500 以上最大 GID+1 來決定!
      

曾經有某些版本的教育訓練手冊談到,為了讓使用者的 UID/GID 成對,她們建議建立的與使用者私有群組無關的其他群組時,使用小于 500 以下的 GID 為宜。 也就是說,如果要建立群組的話,最好能夠使用『 groupadd -r 群組名』的方式來建立啦! 不過,這見仁見智啦!看你自己的抉擇啰!

  • groupmod

跟 usermod 類似的,這個指令僅是在進行 group 相關參數的修改而已。

[[email protected] ~]# groupmod [-g gid] [-n group_name] 群組名
選項與參數:
-g  :修改既有的 GID 數字;
-n  :修改既有的組名

範例一:将剛剛上個指令建立的 group1 名稱改為 mygroup , GID 為 201
[[email protected] ~]# groupmod -g 201 -n mygroup group1
[[email protected] ~]# grep mygroup /etc/group /etc/gshadow
/etc/group:mygroup:x:201:
/etc/gshadow:mygroup:!::
      

不過,還是那句老話,不要随意的更動 GID ,容易造成系統資源的錯亂喔!

  • groupdel

呼呼! groupdel 自然就是在删除群組的啰~用法很簡單:

[[email protected] ~]# groupdel [groupname]

範例一:将剛剛的 mygroup 删除!
[[email protected] ~]# groupdel mygroup

範例二:若要删除 vbird1 這個群組的話?
[[email protected] ~]# groupdel vbird1
groupdel: cannot remove user's primary group.
      

為什麼 mygroup 可以删除,但是 vbird1 就不能删除呢?原因很簡單,『有某個賬号 (/etc/passwd) 的 initial group 使用該群組!』 如果查閱一下,你會發現在 /etc/passwd 内的 vbird1 第四欄的 GID 就是 /etc/group 内的 vbird1 那個群組的 GID ,是以啰,當然無法删除~否則 vbird1 這個使用者登陸系統後, 就會找不到 GID ,那可是會造成很大的困擾的!那麼如果硬要删除 vbird1 這個群組呢? 你『必須要确認 /etc/passwd 内的賬号沒有任何人使用該群組作為 initial group 』才行喔!是以,你可以:

  • 修改 vbird1 的 GID ,或者是:
  • 删除 vbird1 這個使用者。
  • gpasswd:群組管理者功能

如果系統管理者太忙碌了,導緻某些賬号想要加入某個項目時找不到人幫忙!這個時候可以建立『群組管理者』喔! 什麼是群組管理者呢?就是讓某個群組具有一個管理者,這個群組管理者可以管理哪些賬号可以加入/移出該群組! 那要如何『建立一個群組管理者』呢?就得要透過 gpasswd 啰!

# 關于系統管理者(root)做的動作:
[[email protected] ~]# gpasswd groupname
[[email protected] ~]# gpasswd [-A user1,...] [-M user3,...] groupname
[[email protected] ~]# gpasswd [-rR] groupname
選項與參數:
    :若沒有任何參數時,表示給予 groupname 一個密碼(/etc/gshadow)
-A  :将 groupname 的主要權交由後面的使用者管理(該群組的管理者)
-M  :将某些賬号加入這個群組當中!
-r  :将 groupname 的密碼移除
-R  :讓 groupname 的密碼欄失效

# 關于群組管理者(Group administrator)做的動作:
[[email protected] ~]$ gpasswd [-ad] user groupname
選項與參數:
-a  :将某位使用者加入到 groupname 這個群組當中!
-d  :将某位使用者移除出 groupname 這個群組當中。

範例一:建立一個新群組,名稱為 testgroup 且群組交由 vbird1 管理:
[[email protected] ~]# groupadd testgroup  <==先建立群組
[[email protected] ~]# gpasswd testgroup   <==給這個群組一個密碼吧!
Changing the password for group testgroup
New Password:
Re-enter new password:
# 輸入兩次密碼就對了!
[[email protected] ~]# gpasswd -A vbird1 testgroup  <==加入群組管理者為 vbird1
[[email protected] ~]# grep testgroup /etc/group /etc/gshadow
/etc/group:testgroup:x:702:
/etc/gshadow:testgroup:$1$I5ukIY1.$o5fmW.cOsc8.K.FHAFLWg0:vbird1:
# 很有趣吧!此時 vbird1 則擁有 testgroup 的主要權喔!身份有點像闆主啦!

範例二:以 vbird1 登陸系統,并且讓他加入 vbird1, vbird3 成為 testgroup 成員
[[email protected] ~]$ id
uid=504(vbird1) gid=505(vbird1) groups=505(vbird1) ....
# 看得出來,vbird1 尚未加入 testgroup 群組喔!

[[email protected] ~]$ gpasswd -a vbird1 testgroup
[[email protected] ~]$ gpasswd -a vbird3 testgroup
[[email protected] ~]$ grep testgroup /etc/group
testgroup:x:702:vbird1,vbird3
      

很有趣的一個小實驗吧!我們可以讓 testgroup 成為一個可以公開的群組,然後建立起群組管理者, 群組管理者可以有多個。在這個案例中,我将 vbird1 配置為 testgroup 的群組管理者,是以 vbird1 就可以自行添加群組成員啰~呼呼!然後,該群組成員就能夠使用 newgrp 啰~

第十四章、Linux 賬号管理與 ACL 權限配置

賬号管理執行個體

賬号管理不是随意建置幾個賬号就算了!有時候我們需要考慮到一部主機上面可能有多個賬号在協同工作! 舉例來說,在大學任教時,我們學校的專題生是需要分組的,這些同一組的同學間必須要能夠互相修改對方的資料檔案, 但是同時這些同學又需要保留自己的私密資料,是以直接公開家目錄是不适宜的。那該如何是好? 為此,我們底下提供幾個例子來讓大家思考看看啰:

任務一:單純的完成上頭交代的任務,假設我們需要的賬号資料如下,你該如何實作?

賬号名稱 賬号全名 支援次要群組 是否可登陸主機 密碼
myuser1 1st user mygroup1 可以 password
myuser2 2nd user mygroup1 可以 password
myuser3 3rd user 無額外支援 不可以 password

處理的方法如下所示:

# 先處理賬号相關屬性的資料:
[[email protected] ~]# groupadd mygroup1
[[email protected] ~]# useradd -G mygroup1 -c "1st user" myuser1
[[email protected] ~]# useradd -G mygroup1 -c "2nd user" myuser2
[[email protected] ~]# useradd -c "3rd user" -s /sbin/nologin myuser3

# 再處理賬号的密碼相關屬性的資料:
[[email protected] ~]# echo "password" | passwd --stdin myuser1
[[email protected] ~]# echo "password" | passwd --stdin myuser2
[[email protected] ~]# echo "password" | passwd --stdin myuser3
      

要注意的地方主要有:myuser1 與 myuser2 都有支援次要群組,但該群組不見得會存在,是以需要先手動建立他! 然後 myuser3 是『不可登陸系統』的賬号,是以需要使用 /sbin/nologin 這個 shell 來給予,這樣該賬号就無法登陸啰! 這樣是否了解啊!接下來再來讨論比較難一些的環境!如果是專題環境該如何制作?

任務二:我的使用者 pro1, pro2, pro3 是同一個項目計劃的開發人員,我想要讓這三個使用者在同一個目錄底下工作, 但這三個使用者還是擁有自己的家目錄與基本的私有群組。假設我要讓這個項目計劃在 /srv/projecta 目錄下開發, 可以如何進行?

# 1. 假設這三個賬号都尚未建立,可先建立一個名為 projecta 的群組,
#    再讓這三個使用者加入其次要群組的支援即可:
[[email protected] ~]# groupadd projecta
[[email protected] ~]# useradd -G projecta -c "projecta user" pro1
[[email protected] ~]# useradd -G projecta -c "projecta user" pro2
[[email protected] ~]# useradd -G projecta -c "projecta user" pro3
[[email protected] ~]# echo "password" | passwd --stdin pro1
[[email protected] ~]# echo "password" | passwd --stdin pro2
[[email protected] ~]# echo "password" | passwd --stdin pro3

# 2. 開始建立此項目的開發目錄:
[[email protected] ~]# mkdir /srv/projecta
[[email protected] ~]# chgrp projecta /srv/projecta
[[email protected] ~]# chmod 2770 /srv/projecta
[[email protected] ~]# ll -d /srv/projecta
drwxrws--- 2 root projecta 4096 Feb 27 11:29 /srv/projecta
      

由于此項目計劃隻能夠給 pro1, pro2, pro3 三個人使用,是以 /srv/projecta 的權限配置一定要正确才行! 是以該目錄群組一定是 projecta ,但是權限怎麼會是 2770 呢還記得第七章談到的 SGID 吧?為了讓三個使用者能夠互相修改對方的檔案, 這個 SGID 是必須要存在的喔!如果連這裡都能夠了解,嘿嘿!您的賬号管理已經有一定程度的概念啰! ^_^

但接下來有個困擾的問題發生了!假如任務一的 myuser1 是 projecta 這個項目的助理,他需要這個項目的内容, 但是他『不可以修改』項目目錄内的任何資料!那該如何是好?你或許可以這樣做:

  • 将 myuser1 加入 projecta 這個群組的支援,但是這樣會讓 myuser1 具有完整的 /srv/projecta 的權限, myuser1 是可以删除該目錄下的任何資料的!這樣是有問題的;
  • 将 /srv/projecta 的權限改為 2775 ,讓 myuser1 可以進入查閱資料。但此時會發生所有其他人均可進入該目錄查閱的困擾! 這也不是我們要的環境。

真要命!傳統的 Linux 權限無法針對某個個人配置專屬的權限嗎?其實是可以啦!接下來我們就來談談這個功能吧!

第十四章、Linux 賬号管理與 ACL 權限配置

主機的細部權限規劃:ACL 的使用

從第六章開始,我們就一直強調 Linux 的權限概念是非常重要的! 但是傳統的權限僅有三種身份 (owner, group, others) 搭配三種權限 (r,w,x) 而已,并沒有辦法單純的針對某一個使用者或某一個群組來配置特定的權限需求,例如前一小節最後的那個任務! 此時就得要使用 ACL 這個機制啦!這玩意挺有趣的,底下我們就來談一談:

第十四章、Linux 賬号管理與 ACL 權限配置

什麼是 ACL

ACL 是 Access Control List 的縮寫,主要的目的是在提供傳統的 owner,group,others 的 read,write,execute 權限之外的細部權限配置。ACL 可以針對單一使用者,單一檔案或目錄來進行 r,w,x 的權限規範,對于需要特殊權限的使用狀況非常有幫助。

那 ACL 主要可以針對哪些方面來控制權限呢?他主要可以針對幾個項目:

  • 使用者 (user):可以針對使用者來配置權限;
  • 群組 (group):針對群組為對象來配置其權限;
  • 預設屬性 (mask):還可以針對在該目錄下在建立新檔案/目錄時,規範新資料的預設權限;

好了,再來看看如何讓你的檔案系統可以支援 ACL 吧!

第十四章、Linux 賬号管理與 ACL 權限配置

如何啟動 ACL

由于 ACL 是傳統的 Unix-like 作業系統權限的額外支援項目,是以要使用 ACL 必須要有檔案系統的支援才行。目前絕大部分的檔案系統都有支援 ACL 的功能,包括 ReiserFS, EXT2/EXT3, JFS, XFS 等等。在我們的 CentOS 5.x 當中,預設使用 Ext3 是啟動 ACL 支援的!至于察看你的檔案系統是否支援 ACL 可以這樣看:

[[email protected] ~]# mount  <==直接查閱挂載參數的功能
/dev/hda2 on / type ext3 (rw)
/dev/hda3 on /home type ext3 (rw)
# 其他項目鳥哥都将他省略了!假設我們隻要看這兩個裝置。但沒有看到 acl 喔!

[[email protected] ~]# dumpe2fs -h /dev/hda2  <==由 superblock 内容去查詢
....(前面省略)....
Default mount options:    user_xattr acl
....(後面省略)....
      

由 mount 單純去查閱不見得可以看到實際的項目,由于目前新的 distributions 常常會主動加入某些預設功能, 如上表所示,其實 CentOS 5.x 在預設的情況下 (Default mount options:) 就幫你加入 acl 的支援了! 那如果你的系統預設不會幫你加上 acl 的支援呢?那你可以這樣做:

[[email protected] ~]# mount -o remount,acl /
[[email protected] ~]# mount
/dev/hda2 on / type ext3 (rw,acl)
# 這樣就加入了!但是如果想要每次啟動都生效,那就這樣做:

[[email protected] ~]# vi /etc/fstab
LABEL=/1   /   ext3    defaults,acl    1 1
      

如果你不确定或者是不會使用 dumpe2fs 觀察你的檔案系統,那麼建議直接将上述的 /etc/fstab 裡面的内容修改一下即可!

第十四章、Linux 賬号管理與 ACL 權限配置

ACL 的配置技巧: getfacl, setfacl

好了,讓你的 filesystem 啟動 ACL 支援後,接下來該如何配置與觀察 ACL 呢? 很簡單,利用這兩個指令就可以了:

  • getfacl:取得某個檔案/目錄的 ACL 配置項目;
  • setfacl:配置某個目錄/檔案的 ACL 規範。

先讓我們來瞧一瞧 setfacl 如何使用吧!

  • setfacl 指令用法
[[email protected] ~]# setfacl [-bkRd] [{-m|-x} acl參數] 目标檔案名
選項與參數:
-m :配置後續的 acl 參數給檔案使用,不可與 -x 合用;
-x :删除後續的 acl 參數,不可與 -m 合用;
-b :移除所有的 ACL 配置參數;
-k :移除預設的 ACL 參數,關于所謂的『預設』參數于後續範例中介紹;
-R :遞歸配置 acl ,亦即包括次目錄都會被配置起來;
-d :配置『預設 acl 參數』的意思!隻對目錄有效,在該目錄建立的資料會引用此預設值
      

上面談到的是 acl 的選項功能,那麼如何配置 ACL 的特殊權限呢?特殊權限的配置方法有很多, 我們先來談談最常見的,就是針對單一使用者的配置方式:

# 1. 針對特定使用者的方式:
# 配置規範:『 u:[使用者賬号清單]:[rwx] 』,例如針對 vbird1 的權限規範 rx :
[[email protected] ~]# touch acl_test1
[[email protected] ~]# ll acl_test1
-rw-r--r-- 1 root root 0 Feb 27 13:28 acl_test1
[[email protected] ~]# setfacl -m u:vbird1:rx acl_test1
[[email protected] ~]# ll acl_test1
-rw-r-xr--+ 1 root root 0 Feb 27 13:28 acl_test1
# 權限部分多了個 + ,且與原本的權限 (644) 看起來差異很大!但要如何查閱呢?

[[email protected] ~]# setfacl -m u::rwx acl_test1
[[email protected] ~]# ll acl_test1
-rwxr-xr--+ 1 root root 0 Feb 27 13:28 acl_test1
# 無使用者清單,代表配置該檔案擁有者,是以上面顯示 root 的權限成為 rwx 了!
      

上述動作為最簡單的 ACL 配置,利用『 u:使用者:權限 』的方式來配置的啦!配置前請加上 -m 這個選項。 如果一個檔案配置了 ACL 參數後,他的權限部分就會多出一個 + 号了!但是此時你看到的權限與實際權限可能就會有點誤差! 那要如何觀察呢?就透過 getfacl 吧!

  • getfacl 指令用法
[[email protected] ~]# getfacl filename
選項與參數:
getfacl 的選項幾乎與 setfacl 相同!是以鳥哥這裡就免去了選項的說明啊!

# 請列出剛剛我們配置的 acl_test1 的權限内容:
[[email protected] ~]# getfacl acl_test1
# file: acl_test1   <==說明檔名而已!
# owner: root       <==說明此檔案的擁有者,亦即 ll 看到的第三使用者字段
# group: root       <==此檔案的所屬群組,亦即 ll 看到的第四群組字段
user::rwx           <==使用者清單欄是空的,代表檔案擁有者的權限
user:vbird1:r-x     <==針對 vbird1 的權限配置為 rx ,與擁有者并不同!
group::r--          <==針對檔案群組的權限配置僅有 r 
mask::r-x           <==此檔案預設的有效權限 (mask)
other::r--          <==其他人擁有的權限啰!
      

上面的資料非常容易查閱吧?顯示的資料前面加上 # 的,代表這個檔案的預設屬性,包括檔案名、檔案擁有者與檔案所屬群組。 底下出現的 user, group, mask, other 則是屬于不同使用者、群組與有效權限(mask)的配置值。 以上面的結果來看,我們剛剛配置的 vbird1 對于這個檔案具有 r 與 x 的權限啦!這樣看的懂嗎? 如果看的懂的話,接下來讓我們在測試其他類型的 setfacl 配置吧!

# 2. 針對特定群組的方式:
# 配置規範:『 g:[群組清單]:[rwx] 』,例如針對 mygroup1 的權限規範 rx :
[[email protected] ~]# setfacl -m g:mygroup1:rx acl_test1
[[email protected] ~]# getfacl acl_test1
# file: acl_test1
# owner: root
# group: root
user::rwx
user:vbird1:r-x
group::r--
group:mygroup1:r-x  <==這裡就是新增的部分!多了這個群組的權限配置!
mask::r-x
other::r--
      

基本上,群組與使用者的配置并沒有什麼太大的差異啦!如上表所示,非常容易了解意義。不過,你應該會覺得奇怪的是, 那個 mask 是什麼東西啊?其實他有點像是『有效權限』的意思!他的意義是: 使用者或群組所配置的權限必須要存在于 mask 的權限配置範圍内才會生效,此即『有效權限 (effective permission)』 我們舉個例子來看,如下所示:

# 3. 針對有效權限 mask 的配置方式:
# 配置規範:『 m:[rwx] 』,例如針對剛剛的檔案規範為僅有 r :
[[email protected] ~]# setfacl -m m:r acl_test1
[[email protected] ~]# getfacl acl_test1
# file: acl_test1
# owner: root
# group: root
user::rwx
user:vbird1:r-x        #effective:r-- <==vbird1+mask均存在者,僅有 r 而已!
group::r--
group:mygroup1:r-x     #effective:r--
mask::r--
other::r--
      

您瞧,vbird1 與 mask 的集合發現僅有 r 存在,是以 vbird1 僅具有 r 的權限而已,并不存在 x 權限!這就是 mask 的功能了!我們可以透過使用 mask 來規範最大允許的權限,就能夠避免不小心開放某些權限給其他使用者或群組了。 不過,通常鳥哥都是将 mask 配置為 rwx 啦!然後再分别依據不同的使用者/群組去規範她們的權限就是了。

例題: 将前一小節任務二中 /srv/projecta 這個目錄,讓 myuser1 可以進入查閱,但 myuser1 不具有修改的權力。 答: 由于 myuser1 是獨立的使用者與群組,而 /srv 是附屬于 / 之下的,是以 /srv 已經具有 acl 的功能。 透過如下的配置即可搞定:
# 1. 先測試看看,使用 myuser1 能否進入該目錄?
[[email protected] ~]$ cd /srv/projecta
-bash: cd: /srv/projecta: Permission denied  <==确實不可進入!

# 2. 開始用 root 的身份來配置一下該目錄的權限吧!
[[email protected] ~]# setfacl -m u:myuser1:rx /srv/projecta
[[email protected] ~]# getfacl /srv/projecta
# file: srv/projecta
# owner: root
# group: projecta
user::rwx
user:myuser1:r-x  <==還是要看看有沒有配置成功喔!
group::rwx
mask::rwx
other::---

# 3. 還是得要使用 myuser1 去測試看看結果!
[[email protected] ~]$ cd /srv/projecta
[[email protected] projecta]$ ll -a
drwxrws---+ 2 root projecta 4096 Feb 27 11:29 .  <==确實可以查詢檔名
drwxr-xr-x  4 root root     4096 Feb 27 11:29 ..

[[email protected] projecta]$ touch testing
touch: cannot touch `testing': Permission denied <==确實不可以寫入!
      
請注意,上述的 1, 3 步驟使用 myuser1 的身份,2步驟才是使用 root 去配置的!

上面的配置我們就完成了之前任務二的後續需求喔!這麼簡單呢!接下來讓我們來測試一下,如果我用 root 或者是 pro1 的身份去 /srv/projecta 添加檔案或目錄時,該檔案或目錄是否能夠具有 ACL 的配置? 意思就是說,ACL 的權限配置是否能夠被次目錄所『繼承?』先試看看:

[[email protected] ~]# cd /srv/projecta
[[email protected] ~]# touch abc1
[[email protected] ~]# mkdir abc2
[[email protected] ~]# ll -d abc*
-rw-r--r-- 1 root projecta    0 Feb 27 14:37 abc1
drwxr-sr-x 2 root projecta 4096 Feb 27 14:37 abc2
      

你可以明顯的發現,權限後面都沒有 + ,代表這個 acl 屬性并沒有繼承喔!如果你想要讓 acl 在目錄底下的資料都有繼承的功能,那就得如下這樣做了!

# 4. 針對預設權限的配置方式:
# 配置規範:『 d:[ug]:使用者清單:[rwx] 』

# 讓 myuser1 在 /srv/projecta 底下一直具有 rx 的預設權限!
[[email protected] ~]# setfacl -m d:u:myuser1:rx /srv/projecta
[[email protected] ~]# getfacl /srv/projecta
# file: srv/projecta
# owner: root
# group: projecta
user::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---

[[email protected] ~]# cd /srv/projecta
[[email protected] projecta]# touch zzz1
[[email protected] projecta]# mkdir zzz2
[[email protected] projecta]# ll -d zzz*
-rw-rw----+ 1 root projecta    0 Feb 27 14:57 zzz1
drwxrws---+ 2 root projecta 4096 Feb 27 14:57 zzz2
# 看吧!确實有繼承喔!然後我們使用 getfacl 再次确認看看!

[[email protected] projecta]# getfacl zzz2
# file: zzz2
# owner: root
# group: projecta
user::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---
      

透過這個『針對目錄來配置的預設 ACL 權限配置值』的項目,我們可以讓這些屬性繼承到次目錄底下呢! 非常友善啊!那如果想要讓 ACL 的屬性全部消失又要如何處理?透過『 setfacl -b 檔名 』即可啦! 太簡單了!鳥哥就不另外介紹了!請自行測試測試吧!

第十四章、Linux 賬号管理與 ACL 權限配置

使用者身份切換

什麼?在 Linux 系統當中還要作身份的變換?這是為啥?可能有底下幾個原因啦!

  • 使用一般賬号:系統平日操作的好習慣

    事實上,為了安全的緣故,一些老人家都會建議你,盡量以一般身份使用者來操作 Linux 的日常作業!等到需要配置系統環境時, 才變換身份成為 root 來進行系統管理,相對比較安全啦!避免作錯一些嚴重的指令,例如恐怖的『 rm -rf / 』(千萬作不得!)

  • 用較低權限啟動系統服務

    相對于系統安全,有的時候,我們必須要以某些系統賬号來進行程式的運作。 舉例來說, Linux 主機上面的一套軟體,名稱為 apache ,我們可以額外建立一個名為 apache 的使用者來啟動 apache 軟體啊,如此一來,如果這個程式被攻破,至少系統還不至于就損毀了~

  • 軟體本身的限制

    在遠古時代的 telnet 程式中,該程式預設是不許使用 root 的身份登陸的,telnet 會判斷登陸者的 UID, 若 UID 為 0 的話,那就直接拒絕登陸了。是以,你隻能使用一般使用者來登陸 Linux 伺服器。 此外, ssh(注3) 也可以配置拒絕 root 登陸喔!那如果你有系統配置需求該如何是好啊?就變換身份啊!

由于上述考慮,是以我們都是使用一般賬号登陸系統的,等有需要進行系統維護或軟體更新時才轉為 root 的身份來動作。 那如何讓一般使用者轉變身份成為 root 呢?主要有兩種方式喔:

  • 以『 su - 』直接将身份變成 root 即可,但是這個指令卻需要 root 的密碼,也就是說,如果你要以 su 變成 root 的話,你的一般使用者就必須要有 root 的密碼才行;
  • 以『 sudo 指令 』運作 root 的指令串,由于 sudo 需要事先配置妥當,且 sudo 需要輸入使用者自己的密碼, 是以多人共管同一部主機時, sudo 要比 su 來的好喔!至少 root 密碼不會流出去!

底下我們就來說一說 su 跟 sudo 的用法啦!

第十四章、Linux 賬号管理與 ACL 權限配置

su

su 是最簡單的身份切換指令了,他可以進行任何身份的切換唷!方法如下:

[[email protected] ~]# su [-lm] [-c 指令] [username]
選項與參數:
-   :單純使用 - 如『 su - 』代表使用 login-shell 的變量檔案讀取方式來登陸系統;
      若使用者名稱沒有加上去,則代表切換為 root 的身份。
-l  :與 - 類似,但後面需要加欲切換的使用者賬号!也是 login-shell 的方式。
-m  :-m 與 -p 是一樣的,表示『使用目前的環境配置,而不讀取新使用者的配置檔案』
-c  :僅進行一次指令,是以 -c 後面可以加上指令喔!
      

上表的解釋當中有出現之前第十一章談過的 login-shell 配置檔案讀取方式,如果你忘記那是啥東西, 請先回去第十一章瞧瞧再回來吧!這個 su 的用法當中,有沒有加上那個減号『 - 』差很多喔! 因為涉及 login-shell 與 non-login shell 的變量讀取方法。這裡讓我們以一個小例子來說明吧!

範例一:假設你原本是 vbird1 的身份,想要使用 non-login shell 的方式變成 root
[vbird1@www ~]$ su       <==注意提示字元,是 vbird1 的身份喔!
Password:                <==這裡輸入 root 的密碼喔!
[[email protected] vbird1]# id    <==提示字元的目錄是 vbird1 喔!
uid=0(root) gid=0(root) groups=0(root),1(bin),...   <==确實是 root 的身份!
[[email protected] vbird1]# env | grep 'vbird1'
USER=vbird1
PATH=/usr/local/bin:/bin:/usr/bin:/home/vbird1/bin  <==這個影響最大!
MAIL=/var/spool/mail/vbird1                         <==收到的 mailbox 是 vbird1
PWD=/home/vbird1                                    <==并非 root 的家目錄
LOGNAME=vbird1
# 雖然你的 UID 已經是具有 root 的身份,但是看到上面的輸出資訊嗎?
# 還是有一堆變量為原本 vbird1 的身份,是以很多資料還是無法直接利用。
[[email protected] vbird1]# exit   <==這樣可以離開 su 的環境!
      

單純使用『 su 』切換成為 root 的身份,讀取的變量配置方式為 non-login shell 的方式,這種方式很多原本的變量不會被改變, 尤其是我們之前談過很多次的 PATH 這個變量,由于沒有改變成為 root 的環境 (一堆 /sbin, /usr/sbin 等目錄都沒有被包含進來), 是以很多 root 慣用的指令就隻能使用絕對路徑來運作咯。其他的還有 MAIL 這個變量,你輸入 mail 時, 收到的郵件竟然還是 vbird1 的,而不是 root 本身的郵件!是否覺得很奇怪啊!是以切換身份時,請務必使用如下的範例二:

範例二:使用 login shell 的方式切換為 root 的身份并觀察變量
[[email protected] ~]$ su -
Password:   <==這裡輸入 root 的密碼喔!
[[email protected] ~]# env | grep root
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=root
# 了解差異了吧?下次變換成為 root 時,記得最好使用 su - 喔!
[[email protected] ~]# exit   <==這樣可以離開 su 的環境!
      

上述的作法是讓使用者的身份變成 root 并開始作業系統,如果想要離開 root 的身份則得要利用 exit 離開才行。 那我如果隻是想要運作『一個隻有 root 才能進行的指令,且運作完畢就恢複原本的身份』呢?那就可以加上 -c 這個選項啰! 請參考底下範例三!

範例三:vbird1 想要運作『 head -n 3 /etc/shadow 』一次,且已知 root 密碼
[[email protected] ~]$ head -n 3 /etc/shadow
head: cannot open `/etc/shadow' for reading: Permission denied
[[email protected] ~]$ su - -c "head -n 3 /etc/shadow"
Password: <==這裡輸入 root 的密碼喔!
root:$1$/30QpEWEBEZXRD0bh6rAABCEQD.BAH0:14126:0:99999:7:::
bin:*:14126:0:99999:7:::
daemon:*:14126:0:99999:7:::
[[email protected] ~]$ <==注意看,身份還是 vbird1 喔!繼續使用舊的身份進行系統操作!
      

由于 /etc/shadow 權限的關系,該檔案僅有 root 可以查閱。為了查閱該檔案,是以我們必須要使用 root 的身份工作。 但我隻想要進行一次該指令而已,此時就使用類似上面的文法吧!好,那接下來,如果我是 root 或者是其他人, 想要變更成為某些特殊賬号,可以使用如下的方法來切換喔!

範例四:原本是 vbird1 這個使用者,想要變換身份成為 dmtsai 時?
[[email protected] ~]$ su -l dmtsai
Password: <==這裡輸入 dmtsai 的密碼喔!
[dmtsai@www ~]$ su -
Password: <==這裡輸入 root 的密碼喔!
[root@www ~]# id sshd
uid=74(sshd) gid=74(sshd) groups=74(sshd) ... <==确實有存在此人
[[email protected] ~]# su -l sshd
This account is currently not available.      <==竟然說此人無法切換?
[[email protected] ~]# finger sshd
Login: sshd                             Name: Privilege-separated SSH
Directory: /var/empty/sshd              Shell: /sbin/nologin
[[email protected] ~]# exit    <==離開第二次的 su 
[[email protected] ~]$ exit  <==離開第一次的 su 
[[email protected] ~]$ exit  <==這才是最初的環境! 
      

su 就這樣簡單的介紹完畢,總結一下他的用法是這樣的:

  • 若要完整的切換到新使用者的環境,必須要使用『 su - username 』或『 su -l username 』, 才會連同 PATH/USER/MAIL 等變量都轉成新使用者的環境;
  • 如果僅想要運作一次 root 的指令,可以利用『 su - -c "指令串" 』的方式來處理;
  • 使用 root 切換成為任何使用者時,并不需要輸入新使用者的密碼;

雖然使用 su 很友善啦,不過缺點是,當我的主機是多人共管的環境時,如果大家都要使用 su 來切換成為 root 的身份,那麼不就每個人都得要知道 root 的密碼,這樣密碼太多人知道可能會流出去, 很不妥當呢!怎辦?透過 sudo 來處理即可!

第十四章、Linux 賬号管理與 ACL 權限配置

sudo

相對于 su 需要了解新切換的使用者密碼 (常常是需要 root 的密碼), sudo 的運作則僅需要自己的密碼即可! 甚至可以配置不需要密碼即可運作 sudo 呢!由于 sudo 可以讓你以其他使用者的身份運作指令 (通常是使用 root 的身份來運作指令),是以并非所有人都能夠運作 sudo , 而是僅有規範到 /etc/sudoers 内的使用者才能夠運作 sudo 這個指令喔!說的這麼神奇,底下就來瞧瞧那 sudo 如何使用?

  • sudo 的指令用法

由于一開始系統預設僅有 root 可以運作 sudo ,是以底下的範例我們先以 root 的身份來運作,等到談到 visudo 時,再以一般使用者來讨論其他 sudo 的用法吧! sudo 的文法如下:

[[email protected] ~]# sudo [-b] [-u 新使用者賬号]
選項與參數:
-b  :将後續的指令放到背景中讓系統自行運作,而不與目前的 shell 産生影響
-u  :後面可以接欲切換的使用者,若無此項則代表切換身份為 root 。

範例一:你想要以 sshd 的身份在 /tmp 底下建立一個名為 mysshd 的檔案
[[email protected] ~]# sudo -u sshd touch /tmp/mysshd
[[email protected] ~]# ll /tmp/mysshd
-rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd
# 特别留意,這個檔案的權限是由 sshd 所建立的情況喔!

範例二:你想要以 vbird1 的身份建立 ~vbird1/www 并于其中建立 index.html 檔案
[[email protected] ~]# sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
>  echo 'This is index.html file' > index.html"
[[email protected] ~]# ll -a ~vbird1/www
drwxr-xr-x 2 vbird1 vbird1 4096 Feb 28 17:51 .
drwx------ 5 vbird1 vbird1 4096 Feb 28 17:51 ..
-rw-r--r-- 1 vbird1 vbird1   24 Feb 28 17:51 index.html
# 要注意,建立者的身份是 vbird1 ,且我們使用 sh -c "一串指令" 來運作的!
      

sudo 可以讓你切換身份來進行某項任務,例如上面的兩個範例。範例一中,我們的 root 使用 sshd 的權限去進行某項任務! 要注意,因為我們無法使用『 su - sshd 』去切換系統賬号 (因為系統賬号的 shell 是 /sbin/nologin), 這個時候 sudo 真是他 X 的好用了!立刻以 sshd 的權限在 /tmp 底下建立檔案!查閱一下檔案權限你就了解意義啦! 至于範例二則更使用多重指令串 (透過分号 ; 來延續指令進行),使用 sh -c 的方法來運作一連串的指令, 如此真是好友善!

但是 sudo 預設僅有 root 能使用啊!為什麼呢?因為 sudo 的運作是這樣的流程:

  1. 當使用者運作 sudo 時,系統于 /etc/sudoers 檔案中搜尋該使用者是否有運作 sudo 的權限;
  2. 若使用者具有可運作 sudo 的權限後,便讓使用者『輸入使用者自己的密碼』來确認;
  3. 若密碼輸入成功,便開始進行 sudo 後續接的指令(但 root 運作 sudo 時,不需要輸入密碼);
  4. 若欲切換的身份與運作者身份相同,那也不需要輸入密碼。

是以說,sudo 運作的重點是:『能否使用 sudo 必須要看 /etc/sudoers 的配置值, 而可使用 sudo 者是透過輸入使用者自己的密碼來運作後續的指令串』喔!由于能否使用與 /etc/sudoers 有關, 是以我們當然要去編輯 sudoers 檔案啦!不過,因為該檔案的内容是有一定的規範的,是以直接使用 vi 去編輯是不好的。 此時,我們得要透過 visudo 去修改這個檔案喔!

  • visudo 與 /etc/sudoers

從上面的說明我們可以知道,除了 root 之外的其他賬号,若想要使用 sudo 運作屬于 root 的權限指令,則 root 需要先使用 visudo 去修改 /etc/sudoers ,讓該賬号能夠使用全部或部分的 root 指令功能。為什麼要使用 visudo 呢?這是因為 /etc/sudoers 是有配置文法的,如果配置錯誤那會造成無法使用 sudo 指令的不良後果。是以才會使用 visudo 去修改, 并在結束離開修改畫面時,系統會去檢驗 /etc/sudoers 的文法就是了。

一般來說,visudo 的配置方式有幾種簡單的方法喔,底下我們以幾個簡單的例子來分别說明:

  1. 單一使用者可進行 root 所有指令,與 sudoers 檔案文法:

    假如我們要讓 vbird1 這個賬号可以使用 root 的任何指令,那麼可以簡單的這樣進行修改即可:

    [[email protected] ~]# visudo
    ....(前面省略)....
    root    ALL=(ALL)       ALL  <==找到這一行,大約在 76 行左右
    vbird1  ALL=(ALL)       ALL  <==這一行是你要新增的!
    ....(前面省略)....
          
    有趣吧!其實 visudo 隻是利用 vi 将 /etc/sudoers 檔案呼叫出來進行修改而已,是以這個檔案就是 /etc/sudoers 啦! 這個檔案的配置其實很簡單,如上面所示,如果你找到 76 行 (有 root 配置的那行) 左右,看到的資料就是:
    使用者賬号  登陸者的來源主機名=(可切換的身份)  可下達的指令
    root                         ALL=(ALL)           ALL   <==這是預設值
          
    上面這一行的四個元件意義是:
    1. 系統的哪個賬号可以使用 sudo 這個指令的意思,預設為 root 這個賬号;
    2. 當這個賬号由哪部主機聯機到本 Linux 主機,意思是這個賬号可能是由哪一部網絡主機聯機過來的, 這個配置值可以指定用戶端計算機(信任使用者的意思)。預設值 root 可來自任何一部網絡主機
    3. 這個賬号可以切換成什麼身份來下達後續的指令,預設 root 可以切換成任何人;
    4. 可用該身份下達什麼指令?這個指令請務必使用絕對路徑撰寫。 預設 root 可以切換任何身份且進行任何指令之意。
    那個 ALL 是特殊的關鍵詞,代表任何身份、主機或指令的意思。是以,我想讓 vbird1 可以進行任何身份的任何指令, 就如同上表特殊字型寫的那樣,其實就是複制上述預設值那一行,再将 root 改成 vbird1 即可啊! 此時『vbird1 不論來自哪部主機登陸,他可以變換身份成為任何人,且可以進行系統上面的任何指令』之意。 修改完請儲存後離開 vi,并以 vbird1 登陸系統後,進行如下的測試看看:
    [[email protected] ~]$ tail -n 1 /etc/shadow  <==注意!身份是 vbird1
    tail: cannot open `/etc/shadow' for reading: Permission denied
    # 因為不是 root 嘛!是以當然不能查詢 /etc/shadow
    
    [[email protected] ~]$ sudo tail -n 1 /etc/shadow <==透過 sudo
    
    We trust you have received the usual lecture from the local System
    Administrator. It usually boils down to these three things:
    
        #1) Respect the privacy of others.  <==這裡僅是一些說明與警示項目
        #2) Think before you type.
        #3) With great power comes great responsibility.
    
    Password: <==注意啊!這裡輸入的是『 vbird1 自己的密碼 』
    pro3:$1$GfinyJgZ$9J8IdrBXXMwZIauANg7tW0:14302:0:99999:7::: 
    # 看!vbird1 竟然可以查詢 shadow !
          
    注意到了吧!vbird1 輸入自己的密碼就能夠運作 root 的指令!是以,系統管理者當然要了解 vbird1 這個使用者的『操守』才行!否則随便配置一個使用者,他惡搞系統怎辦?另外,一個一個配置太麻煩了, 能不能使用群組的方式來配置呢?參考底下的方式吧。
  2. 利用群組以及免密碼的功能處理 visudo

    我們在本章前面曾經建立過 pro1, pro2, pro3 ,這三個使用者能否透過群組的功能讓這三個人可以管理系統? 可以的,而且很簡單!同樣我們使用實際案例來說明:

    [[email protected] ~]# visudo  <==同樣的,請使用 root 先配置
    ....(前面省略)....
    %wheel     ALL=(ALL)    ALL <==大約在 84 行左右,請将這行的 # 拿掉!
    # 在最左邊加上 % ,代表後面接的是一個『群組』之意!改完請儲存後離開
    
    [[email protected] ~]# usermod -a -G wheel pro1 <==将 pro1 加入 wheel 的支援
          
    上面的配置值會造成『任何加入 wheel 這個群組的使用者,就能夠使用 sudo 切換任何身份來操作任何指令』的意思。 你當然可以将 wheel 換成你自己想要的群組名。接下來,請分别切換身份成為 pro1 及 pro2 試看看 sudo 的運作。
    [[email protected] ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro1
    ....(前面省略)....
    Password:  <==輸入 pro1 的密碼喔!
    pro3:$1$GfinyJgZ$9J8IdrBXXMwZIauANg7tW0:14302:0:99999:7:::
    
    [[email protected] ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro2
    Password:
    pro2 is not in the sudoers file.  This incident will be reported.
    # 仔細看錯誤資訊他是說這個 pro2 不在 /etc/sudoers 的配置中!
          
    這樣了解群組了吧?如果你想要讓 pro3 也支援這個 sudo 的話,不需要重新使用 visudo ,隻要利用usermod 去修改 pro3 的群組支援,讓 wheel 也支援 pro3 的話,那他就能夠進行 sudo 啰! 簡單吧!不過,既然我們都信任這些 sudo 的使用者了,能否提供『不需要密碼即可使用 sudo 』呢? 就透過如下的方式:
    [[email protected] ~]# visudo  <==同樣的,請使用 root 先配置
    ....(前面省略)....
    %wheel     ALL=(ALL)   NOPASSWD: ALL <==大約在 87 行左右,請将 # 拿掉!
    # 在最左邊加上 % ,代表後面接的是一個『群組』之意!改完請儲存後離開
          
    重點是那個 NOPASSWD 啦!該關鍵詞是免除密碼輸入的意思喔!
  3. 有限制的指令操作:

    上面兩點都會讓使用者能夠利用 root 的身份進行任何事情!這樣總是不太好~如果我想要讓使用者僅能夠進行部分系統任務, 比方說,系統上面的 myuser1 僅能夠幫 root 修改其他使用者的密碼時,亦即『當使用者僅能使用 passwd 這個指令幫忙 root 修改其他使用者的密碼』時,你該如何撰寫呢?可以這樣做:

    [[email protected] ~]# visudo  <==注意是 root 身份
    myuser1	ALL=(root)  /usr/bin/passwd  <==最後指令務必用絕對路徑
          
    上面的配置值指的是『myuser1 可以切換成為 root 使用 passwd 這個指令』的意思。其中要注意的是:指令字段必須要填寫絕對路徑才行!否則 visudo 會出現文法錯誤的狀況發生! 此外,上面的配置是有問題的!我們使用底下的指令操作來讓您了解:
    [[email protected] ~]$ sudo passwd myuser3  <==注意,身份是 myuser1
    Password:  <==輸入 myuser1 的密碼
    Changing password for user myuser3. <==底下改的是 myuser3 的密碼喔!這樣是正确的
    New UNIX password:
    Retype new UNIX password:
    passwd: all authentication tokens updated successfully.
    
    [[email protected] ~]$ sudo passwd
    Changing password for user root.  <==見鬼!怎麼會去改 root 的密碼?
          
    恐怖啊!我們竟然讓 root 的密碼被 myuser3 給改變了!下次 root 回來竟無法登陸系統...欲哭無淚~怎辦? 是以我們必須要限制使用者的指令參數!修改的方法為将上述的那行改一改先:
    [[email protected] ~]# visudo  <==注意是 root 身份
    myuser1	ALL=(root)  !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \
                        !/usr/bin/passwd root
          
    由于螢幕一行寫不完,我将這行寫成兩行,是以上面第一行最後加上反斜杠啰。加上驚歎号『 ! 』代表『不可運作』的意思。 是以上面這一行會變成:可以運作『 passwd 任意字元』,但是『 passwd 』與『 passwd root 』這兩個指令例外! 如此一來 myuser1 就無法改變 root 的密碼了!這樣這位使用者可以具有 root 的能力幫助你修改其他使用者的密碼, 而且也不能随意改變 root 的密碼!很有用處的!
  4. 透過别名建置 visudo:

    如上述第三點,如果我有 15 個使用者需要加入剛剛的管理者行列,那麼我是否要将上述那長長的配置寫入 15 行啊? 而且如果想要修改指令或者是新增指令時,那我每行都需要重新配置,很麻煩ㄟ!有沒有更簡單的方式? 是有的!透過别名即可!我們 visudo 的别名可以是『指令别名、帳戶别名、主機名稱』等。不過這裡我們僅介紹帳戶别名, 其他的配置值有興趣的話,可以自行玩玩!

    假設我的 pro1, pro2, pro3 與 myuser1, myuser2 要加入上述的密碼管理者的 sudo 清單中, 那我可以創立一個帳戶别名稱為 ADMPW 的名稱,然後将這個名稱處理一下即可。處理的方式如下:

    [[email protected] ~]# visudo  <==注意是 root 身份
    User_Alias ADMPW = pro1, pro2, pro3, myuser1, myuser2
    Cmnd_Alias ADMPWCOM = !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \
                          !/usr/bin/passwd root
    ADMPW   ALL=(root)  ADMPWCOM
          
    我透過 User_Alias 建立出一個新賬号,這個賬号名稱一定要使用大寫字元來處理,包括 Cmnd_Alias(指令别名)、Host_Alias(來源主機名别名) 都需要使用大寫字元的!這個 ADMPW 代表後面接的那些實際賬号。 而該賬号能夠進行的指令就如同 ADMPWCOM 後面所指定的那樣!上表最後一行則寫入這兩個别名 (賬号與指令别名), 未來要修改時,我隻要修改 User_Alias 以及 Cmnd_Alias 這兩行即可!配置方面會比較簡單有彈性喔!
  5. sudo 的時間間隔問題:

    或許您已經發現了,那就是,如果我使用同一個賬号在短時間内重複操作 sudo 來運作指令的話, 在第二次運作 sudo 時,并不需要輸入自己的密碼!sudo 還是會正确的運作喔!為什麼呢? 第一次運作 sudo 需要輸入密碼,是擔心由于使用者暫時離開座位,但有人跑來你的座位使用你的賬号作業系統之故。 是以需要你輸入一次密碼重新确認一次身份。

    兩次運作 sudo 的間隔在五分鐘内,那麼再次運作 sudo 時就不需要再次輸入密碼了, 這是因為系統相信你在五分鐘内不會離開你的作業,是以運作 sudo 的是同一個人!呼呼!真是很人性化的設計啊~ ^_^。不過如果兩次 sudo 操作的間隔超過 5 分鐘,那就得要重新輸入一次你的密碼了 (注4)

    另外要注意的是,因為使用一般賬号時,理論上不會使用到 /sbin, /usr/sbin 等目錄内的指令,是以 $PATH 變量不會含有這些目錄,是以很多管理指令需要使用絕對路徑來下達比較妥當喔!

  6. sudo 搭配 su 的使用方式:

    很多時候我們需要大量運作很多 root 的工作,是以一直使用 sudo 覺得很煩ㄟ!那有沒有辦法使用 sudo 搭配 su , 一口氣将身份轉為 root ,而且還用使用者自己的密碼來變成 root 呢?是有的!而且方法簡單的會讓你想笑! 我們建立一個 ADMINS 帳戶别名,然後這樣做:

    [[email protected] ~]# visudo
    User_Alias  ADMINS = pro1, pro2, pro3, myuser1
    ADMINS ALL=(root)  /bin/su -
          
    接下來,上述的 pro1, pro2, pro3, myuser1 這四個人,隻要輸入『 sudo su - 』并且輸入『自己的密碼』後, 立刻變成 root 的身份!不但 root 密碼不會外流,使用者的管理也變的非常友善! 這也是實務上面多人共管一部主機時常常使用的技巧呢!這樣管理确實友善,不過還是要強調一下大前提, 那就是『這些你加入的使用者,全部都是你能夠信任的使用者』!
第十四章、Linux 賬号管理與 ACL 權限配置

使用者的特殊 shell 與 PAM 子產品

我們前面一直談到的大多是一般身份使用者與系統管理者 (root) 的相關操作, 而且大多是讨論關于可登陸系統的賬号來說。那麼換個角度想,如果我今天想要建立的, 是一個『僅能使用 mail server 相關郵件服務的賬号,而該賬号并不能登陸 Linux 主機』呢?如果不能給予該賬号一個密碼,那麼該賬号就無法使用系統的各項資源,當然也包括 mail 的資源, 而如果給予一個密碼,那麼該賬号就可能可以登陸 Linux 主機啊!呵呵~傷腦筋吧~ 是以,底下讓我們來談一談這些有趣的話題啰!

另外,在本章之前談到過 /etc/login.defs 檔案中,關于密碼長度應該預設是 5 個字元串長度,但是我們上面也談到,該配置值已經被 PAM 子產品所取代了,那麼 PAM 是什麼?為什麼他可以影響我們使用者的登陸呢?這裡也要來談談的!

第十四章、Linux 賬号管理與 ACL 權限配置

特殊的 shell, /sbin/nologin

在本章一開頭的 passwd 檔案結構裡面我們就談過系統賬号這玩意兒,這玩意兒的 shell 就是使用 /sbin/nologin ,重點在于系統賬号是不需要登陸的!是以我們就給他這個無法登陸的合法 shell。 使用了這個 shell 的使用者即使有了密碼,你想要登陸時他也無法登陸,因為會出現如下的資訊喔:

This account is currently not available.
      

我們所謂的『無法登陸』指的僅是:『這個使用者無法使用 bash 或其他 shell 來登陸系統』而已, 并不是說這個賬号就無法使用其他的系統資源喔! 舉例來說,各個系統賬号,列印作業由 lp 這個賬号在管理, WWW 服務由 apache 這個賬号在管理, 他們都可以進行系統程式的工作,但是『就是無法登陸主機』而已啦!^_^

換個角度來想,如果我的 Linux 主機提供的是郵件服務,是以說,在這部 Linux 主機上面的賬号, 其實大部分都是用來收受主機的信件而已,并不需要登陸主機的呢! 這個時候,我們就可以考慮讓單純使用 mail 的賬号以 /sbin/nologin 做為他們的 shell , 這樣,最起碼當我的主機被嘗試想要登陸系統以取得 shell 環境時,可以拒絕該賬号呢!

另外,如果我想要讓某個具有 /sbin/nologin 的使用者知道,他們不能登陸主機時, 其實我可以建立『/etc/nologin.txt 』這個檔案, 并且在這個檔案内說明不能登陸的原因,那麼下次當這個使用者想要登陸系統時, 螢幕上出現的就會是 /etc/nologin.txt 這個檔案的内容,而不是預設的内容了!

例題: 當使用者嘗試利用純 mail 賬号 (例如 myuser3) 時,利用 /etc/nologin.txt 告知使用者不要利用該賬号登陸系統。 答: 直接以 vi 編輯該檔案,内容可以是這樣:
[[email protected] ~]# vi /etc/nologin.txt
This account is system account or mail account.
Please DO NOT use this account to login my Linux server.
      
想要測試時,可以使用 myuser3 (此賬号的 shell 是 /sbin/nologin) 來測試看看!
[[email protected] ~]# su - myuser3
This account is system account or mail account.
Please DO NOT use this account to login my Linux server.
[[email protected] ~]#
      
結果會發現與原本的預設資訊不一樣喔! ^_^
第十四章、Linux 賬号管理與 ACL 權限配置

PAM 子產品簡介

在過去,我們想要對一個使用者進行認證 (authentication),得要要求使用者輸入賬号密碼, 然後透過自行撰寫的程式來判斷該賬号密碼是否正确。也因為如此,我們常常得使用不同的機制來判斷賬号密碼, 是以搞的一部主機上面擁有多個各别的認證系統,也造成賬号密碼可能不同步的驗證問題! 為了解決這個問題是以有了 PAM (Pluggable Authentication Modules, 嵌入式子產品) 的機制!

PAM 可以說是一套應用程式程式設計接口 (Application Programming Interface, API),他提供了一連串的驗證機制,隻要使用者将驗證階段的需求告知 PAM 後, PAM 就能夠回報使用者驗證的結果 (成功或失敗)。由于 PAM 僅是一套驗證的機制,又可以提供給其他程式所呼叫引用,是以不論你使用什麼程式,都可以使用 PAM 來進行驗證,如此一來,就能夠讓賬号密碼或者是其他方式的驗證具有一緻的結果!也讓程式設計師友善處理驗證的問題喔! (注5)

第十四章、Linux 賬号管理與 ACL 權限配置

圖 5.2.1、 PAM 子產品與其他程式的相關性

如上述的圖示, PAM 是一個獨立的 API 存在,隻要任何程式有需求時,可以向 PAM 發出驗證要求的通知, PAM 經過一連串的驗證後,将驗證的結果回報給該程式,然後該程式就能夠利用驗證的結果來進行可登陸或顯示其他無法使用的資訊。 這也就是說,你可以在寫程式的時候将 PAM 子產品的功能加入,就能夠利用 PAM 的驗證功能啰。 是以目前很多程式都會利用 PAM 喔!是以我們才要來學習他啊!

PAM 用來進行驗證的資料稱為子產品 (Modules),每個 PAM 子產品的功能都不太相同。舉例來說, 還記得我們在本章使用 passwd 指令時,如果随便輸入字典上面找的到的字元串, passwd 就會回報錯誤資訊了!這是為什麼呢?這就是 PAM 的 pam_cracklib.so 子產品的功能!他能夠判斷該密碼是否在字典裡面! 并回報給密碼修改程式,此時就能夠了解你的密碼強度了。

是以,當你有任何需要判斷是否在字典當中的密碼字元串時,就可以使用 pam_cracklib.so 這個子產品來驗證! 并根據驗證的回報結果來撰寫你的程式呢!這樣說,可以了解 PAM 的功能了吧?沒錯! PAM 的子產品也是很重要的一環!

第十四章、Linux 賬号管理與 ACL 權限配置

PAM 子產品配置文法

PAM 藉由一個與程式相同檔案名的配置檔案來進行一連串的認證分析需求。我們同樣以 passwd 這個指令的呼叫 PAM 來說明好了。 當你運作 passwd 後,這支程式呼叫 PAM 的流程是:

  1. 使用者開始運作 /usr/bin/passwd 這支程式,并輸入密碼;
  2. passwd 呼叫 PAM 子產品進行驗證;
  3. PAM 子產品會到 /etc/pam.d/ 找尋與程式 (passwd) 同名的配置檔案;
  4. 依據 /etc/pam.d/passwd 内的配置,引用相關的 PAM 子產品逐漸進行驗證分析;
  5. 将驗證結果 (成功、失敗以及其他資訊) 回傳給 passwd 這支程式;
  6. passwd 這支程式會根據 PAM 回傳的結果決定下一個動作 (重新輸入新密碼或者通過驗證!)

從上頭的說明,我們會知道重點其實是 /etc/pam.d/ 裡面的配置檔案,以及配置檔案所呼叫的 PAM 子產品進行的驗證工作! 既然一直談到 passwd 這個密碼修改指令,那我們就來看看 /etc/pam.d/passwd 這個配置檔案的内容是怎樣吧!

[[email protected] ~]# cat /etc/pam.d/passwd
#%PAM-1.0  <==PAM版本的說明而已!
auth       include      system-auth <==每一行都是一個驗證的過程
account    include      system-auth
password   include      system-auth
驗證類别   控制标準     PAM 子產品與該子產品的參數
      

在這個配置檔案當中,除了第一行宣告 PAM 版本之外,其他任何『 # 』開頭的都是批注,而每一行都是一個獨立的驗證流程, 每一行可以區分為三個字段,分别是驗證類别(type)、控制标準(flag)、PAM的子產品與該子產品的參數。 底下我們先來談談驗證類别與控制标準這兩項資料吧!

Tips:

你會發現在我們上面的表格當中出現的是『 include (包括) 』這個關鍵詞,他代表的是『請呼叫後面的檔案來作為這個類别的驗證』, 是以,上述的每一行都要重複呼叫 /etc/pam.d/system-auth 那個檔案來進行驗證的意思!

第十四章、Linux 賬号管理與 ACL 權限配置
  • 第一個字段:驗證類别 (Type)

驗證類别主要分為四種,分别說明如下:

  • auth

    是 authentication (認證) 的縮寫,是以這種類别主要用來檢驗使用者的身份驗證,這種類别通常是需要密碼來檢驗的, 是以後續接的子產品是用來檢驗使用者的身份。

  • account

    account (賬号) 則大部分是在進行 authorization (授權),這種類别則主要在檢驗使用者是否具有正确的權限, 舉例來說,當你使用一個過期的密碼來登陸時,當然就無法正确的登陸了。

  • session

    session 是會議期間的意思,是以 session 管理的就是使用者在這次登陸 (或使用這個指令) 期間,PAM 所給予的環境配置。 這個類别通常用在記錄使用者登陸與登出時的資訊!例如,如果你常常使用 su 或者是 sudo 指令的話, 那麼應該可以在 /var/log/secure 裡面發現很多關于 pam 的說明,而且記載的資料是『session open, session close』的資訊! 

  • password

    password 就是密碼嘛!是以這種類别主要在提供驗證的修訂工作,舉例來說,就是修改/變更密碼啦!

這四個驗證的類型通常是有順序的,不過也有例外就是了。 會有順序的原因是,(1)我們總是得要先驗證身份 (auth) 後, (2)系統才能夠藉由使用者的身份給予适當的授權與權限配置 (account),而且(3)登陸與登出期間的環境才需要配置, 也才需要記錄登陸與登出的資訊 (session)。如果在運作期間需要密碼修訂時,(4)才給予 password 的類别。這樣說起來, 自然是需要有點順序吧!

  • 第二個字段:驗證的控制旗标 (control flag)

那麼『驗證的控制旗标(control flag)』又是什麼?簡單的說,他就是『驗證通過的标準』啦! 這個字段在管控該驗證的放行方式,主要也分為四種控制方式:

  • required

    此驗證若成功則帶有 success (成功) 的标志,若失敗則帶有 failure 的标志,但不論成功或失敗都會繼續後續的驗證流程。 由于後續的驗證流程可以繼續進行,是以相當有利于資料的登入 (log) ,這也是 PAM 最常使用 required 的原因。

  • requisite

    若驗證失敗則立刻回報原程式 failure 的标志,并終止後續的驗證流程。若驗證成功則帶有 success 的标志并繼續後續的驗證流程。 這個項目與 required 最大的差異,就在于失敗的時候還要不要繼續驗證下去?由于 requisite 是失敗就終止, 是以失敗時所産生的 PAM 資訊就無法透過後續的子產品來記錄了。

  • sufficient

    若驗證成功則立刻回傳 success 給原程式,并終止後續的驗證流程;若驗證失敗則帶有 failure 标志并繼續後續的驗證流程。 這玩意兒與 requisits 剛好相反!

  • optional

    這個子產品控件目大多是在顯示資訊而已,并不是用在驗證方面的。

如果将這些控制旗标以圖示的方式配合成功與否的條件繪圖,會有點像底下這樣:

第十四章、Linux 賬号管理與 ACL 權限配置

圖 5.3.1、 PAM 控制旗标所造成的回報流程

程式運作過程中遇到驗證時才會去呼叫 PAM ,而 PAM 驗證又分很多類型與控制,不同的控制旗标所回報的資訊并不相同。 如上圖所示, requisite 失敗就回報了并不會繼續,而 sufficient 則是成功就回報了也不會繼續。 至于驗證結束後所回報的資訊通常是『succes 或 failure 』而已,後續的流程還需要該程式的判斷來繼續運作才行。

第十四章、Linux 賬号管理與 ACL 權限配置

常用子產品簡介

談完了配置檔案的文法後,現在讓我們來查閱一下 CentOS 5.x 提供的 PAM 預設檔案的内容是啥吧! 由于我們常常需要透過各種方式登陸 (login) 系統,是以就來看看登陸所需要的 PAM 流程為何:

[[email protected] ~]# cat /etc/pam.d/login
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth       include      system-auth
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    include      system-auth
session    required     pam_loginuid.so
session    optional     pam_console.so
# pam_selinux.so open should only be followed by sessions...
session    required     pam_selinux.so open
session    optional     pam_keyinit.so force revoke
# 我們可以看到,其實 login 也呼叫多次的 system-auth ,是以底下列出該配置檔案

[[email protected] ~]# cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth     required     pam_env.so
auth     sufficient   pam_unix.so nullok try_first_pass
auth     requisite    pam_succeed_if.so uid >= 500 quiet
auth     required     pam_deny.so

account  required     pam_unix.so
account  sufficient   pam_succeed_if.so uid < 500 quiet
account  required     pam_permit.so

password requisite    pam_cracklib.so try_first_pass retry=3
password sufficient   pam_unix.so md5 shadow nullok try_first_pass use_authtok
password required     pam_deny.so

session  optional     pam_keyinit.so revoke
session  required     pam_limits.so
session  [success=1 default=ignore] pam_succeed_if.so service in crond quiet \
                      use_uid
session  required     pam_unix.so
      

上面這個表格當中使用到非常多的 PAM 子產品,每個子產品的功能都不太相同,詳細的子產品情報可以在你的系統中找到:

  • /etc/pam.d:詳細的 PAM 說明檔案。

例如鳥哥使用未 update 過的 CentOS 5.2 ,pam_nologin 說明檔案檔在: /usr/share/doc/pam-0.99.6.2/txts/README.pam_nologin。你可以自行查閱一下該子產品的功能。 鳥哥這裡僅簡單介紹幾個較常使用的子產品,詳細的資訊還得要您努力查閱參考書呢! ^_^

  • pam_securetty.so:

    限制系統管理者 (root) 隻能夠從安全的 (secure) 終端機登陸;那什麼是終端機?例如 tty1, tty2 等就是傳統的終端機裝置名稱。那麼安全的終端機配置呢? 就寫在 /etc/securetty 這個檔案中。你可以查閱一下該檔案, 就知道為什麼 root 可以從 tty1~tty7 登陸,但卻無法透過 telnet 登陸 Linux 主機了!

  • pam_nologin.so:

    這個子產品可以限制一般使用者是否能夠登陸主機之用。當 /etc/nologin 這個檔案存在時,則所有一般使用者均無法再登陸系統了!若 /etc/nologin 存在,則一般使用者在登陸時, 在他們的終端機上會将該檔案的内容顯示出來!是以,正常的情況下,這個檔案應該是不能存在系統中的。 但這個子產品對 root 以及已經登陸系統中的一般賬号并沒有影響。

  • pam_selinux.so:

    SELinux 是個針對程式來進行細部管理權限的功能,SELinux 這玩意兒我們會在第十七章的時候再來詳細談論。由于 SELinux 會影響到使用者運作程式的權限,是以我們利用 PAM 子產品,将 SELinux 暫時關閉,等到驗證通過後, 再予以啟動!

  • pam_console.so:

    當系統出現某些問題,或者是某些時刻你需要使用特殊的終端接口 (例如 RS232 之類的終端聯機裝置) 登陸主機時, 這個子產品可以幫助處理一些檔案權限的問題,讓使用者可以透過特殊終端接口 (console) 順利的登陸系統。

  • pam_loginuid.so:

    我們知道系統賬号與一般賬号的 UID 是不同的!一般賬号 UID 均大于 500 才合理。 是以,為了驗證使用者的 UID 真的是我們所需要的數值,可以使用這個子產品來進行規範!

  • pam_env.so:

    用來配置環境變量的一個子產品,如果你有需要額外的環境變量配置,可以參考 /etc/security/pam_env.conf 這個檔案的詳細說明。

  • pam_unix.so:

    這是個很複雜且重要的子產品,這個子產品可以用在驗證階段的認證功能,可以用在授權階段的賬号許可證管理, 可以用在會議階段的登入檔案記錄等,甚至也可以用在密碼更新階段的檢驗!非常豐富的功能! 這個子產品在早期使用得相當頻繁喔!

  • pam_cracklib.so:

    可以用來檢驗密碼的強度!包括密碼是否在字典中,密碼輸入幾次都失敗就斷掉此次聯機等功能,都是這子產品提供的! 這玩意兒很重要!

  • pam_limits.so:

    還記得我們在十一章談到的 ulimit 嗎? 其實那就是這個子產品提供的能力!還有更多細部的配置可以參考: /etc/security/limits.conf 内的說明。

了解了這些子產品的大緻功能後,言歸正傳,讨論一下 login 的 PAM 驗證機制流程是這樣的:

  1. 驗證階段 (auth):首先,(a)會先經過 pam_securetty.so 判斷,如果使用者是 root 時,則會參考 /etc/securetty 的配置; 接下來(b)經過 pam_env.so 配置額外的環境變量;再(c)透過 pam_unix.so 檢驗密碼,若通過則回報 login 程式;若不通過則(d)繼續往下以 pam_succeed_if.so 判斷 UID 是否大于 500 ,若小于 500則回報失敗,否則再往下 (e)以 pam_deny.so 拒絕聯機。
  2. 授權階段 (account):(a)先以 pam_nologin.so 判斷 /etc/nologin 是否存在,若存在則不許一般使用者登陸; (b)接下來以 pam_unix 進行賬号管理,再以 (c) pam_succeed_if.so 判斷 UID 是否小于 500 ,若小于 500 則不記錄登入資訊。(d)最後以 pam_permit.so 允許該賬号登陸。
  3. 密碼階段 (password):(a)先以 pam_cracklib.so 配置密碼僅能嘗試錯誤 3 次;(b)接下來以 pam_unix.so 透過 md5, shadow 等功能進行密碼檢驗,若通過則回報 login 程式,若不通過則 (c)以 pam_deny.so 拒絕登陸。
  4. 會議階段 (session):(a)先以 pam_selinux.so 暫時關閉 SELinux;(b)使用 pam_limits.so 配置好使用者能夠操作的系統資源; (c)登陸成功後開始記錄相關資訊在登入檔案中; (d)以 pam_loginuid.so 規範不同的 UID 權限;(e)開啟 pam_selinux.so 的功能。

總之,就是依據驗證類别 (type) 來看,然後先由 login 的配置值去查閱,如果出現『 include system-auth 』 就轉到 system-auth 檔案中的相同類别,去取得額外的驗證流程就是了。然後再到下一個驗證類别,最終将所有的驗證跑完! 就結束這次的 PAM 驗證啦!

經過這樣的驗證流程,現在你知道為啥 /etc/nologin 存在會有問題,也會知道為何你使用一些遠端聯機機制時, 老是無法使用 root 登陸的問題了吧?沒錯!這都是 PAM 子產品提供的功能啦!

例題: 為什麼 root 無法以 telnet 直接登陸系統,但是卻能夠使用 ssh 直接登陸? 答: 一般來說, telnet 會引用 login 的 PAM 子產品,而 login 的驗證階段會有 /etc/securetty 的限制! 由于遠端聯機屬于 pts/n (n 為數字) 的動态終端機接口裝置名稱,并沒有寫入到 /etc/securetty , 是以 root 無法以 telnet 登陸遠端主機。至于 ssh 使用的是 /etc/pam.d/sshd 這個子產品, 你可以查閱一下該子產品,由于該子產品的驗證階段并沒有加入 pam_securetty ,是以就沒有 /etc/securetty 的限制!故可以從遠端直接聯機到伺服器端。

另外,關于 telnet 與 ssh 的細部說明,請參考 鳥哥的 Linux 私房菜伺服器篇

第十四章、Linux 賬号管理與 ACL 權限配置

其他相關檔案

除了前一小節談到的 /etc/securetty 會影響到 root 可登陸的安全終端機, /etc/nologin 會影響到一般使用者是否能夠登陸的功能之外,我們也知道 PAM 相關的配置檔案在 /etc/pam.d , 說明檔案在 /usr/share/doc/pam-(版本) ,子產品實際在 /lib/security/ 。那麼還有沒有相關的 PAM 檔案呢? 是有的,主要都在 /etc/security 這個目錄内!我們底下介紹幾個可能會用到的配置檔案喔!

  • limits.conf

我們在第十一章談到的 ulimit 功能中, 除了修改使用者的 ~/.bashrc 配置檔案之外,其實系統管理者可以統一藉由 PAM 來管理的! 那就是 /etc/security/limits.conf 這個檔案的配置了。這個檔案的配置很簡單,你可以自行參考一下該檔案内容。 我們這裡僅作個簡單的介紹:

範例一:vbird1 這個使用者隻能建立 100MB 的檔案,且大于 90MB 會警告
[[email protected] ~]# vi /etc/security/limits.conf
vbird1	soft		fsize		 90000
vbird1	hard		fsize		100000
#賬号   限制依據	限制項目 	限制值
# 第一字段為賬号,或者是群組!若為群組則前面需要加上 @ ,例如 @projecta
# 第二字段為限制的依據,是嚴格(hard),還是僅為警告(soft);
# 第三字段為相關限制,此例中限制檔案容量,
# 第四字段為限制的值,在此例中機關為 KB。
# 若以 vbird1 登陸後,進行如下的操作則會有相關的限制出現!

[[email protected] ~]$ ulimit -a
....(前面省略)....
file size               (blocks, -f) 90000
....(後面省略)....

[[email protected] ~]$ dd if=/dev/zero of=test bs=1M count=110
File size limit exceeded
[[email protected] ~]$ ll -k test
-rw-rw-r-- 1 vbird1 vbird1 90000 Mar  4 11:30 test
# 果然有限制到了

範例二:限制 pro1 這個群組,每次僅能有一個使用者登陸系統 (maxlogins)
[[email protected] ~]# vi /etc/security/limits.conf
@pro1   hard   maxlogins   1
# 如果要使用群組功能的話,這個功能似乎對初始群組才有效喔!
# 而如果你嘗試多個 pro1 的登陸時,第二個以後就無法登陸了。
# 而且在 /var/log/secure 檔案中還會出現如下的資訊:
# pam_limits(login:session): Too many logins (max 1) for pro1
      

這個檔案挺有趣的,而且是配置完成就生效了,你不用重新啟動任何服務的! 但是 PAM 有個特殊的地方,由于他是在程式呼叫時才予以配置的,是以你修改完成的資料, 對于已登陸系統中的使用者是沒有效果的,要等他再次登陸時才會生效喔!另外, 上述的配置請在測試完成後立刻批注掉,否則下次這兩個使用者登陸就會發生些許問題啦! ^_^

  • /var/log/secure, /var/log/messages

如果發生任何無法登陸或者是産生一些你無法預期的錯誤時,由于 PAM 子產品都會将資料記載在 /var/log/secure 當中,是以發生了問題請務必到該檔案内去查詢一下問題點!舉例來說, 我們在 limits.conf 的介紹内的範例二,就有談到多重登陸的錯誤可以到 /var/log/secure 内查閱了! 這樣你也就知道為何第二個 pro1 無法登陸啦!^_^

第十四章、Linux 賬号管理與 ACL 權限配置

Linux 主機上的使用者資訊傳遞

談了這麼多的賬号問題,總是該要談一談,那麼如何針對系統上面的使用者進行查詢吧? 想幾個狀态,如果你在 Linux 上面操作時,剛好有其他的使用者也登陸主機,你想要跟他對談,該如何是好? 你想要知道某個賬号的相關資訊,該如何查閱?呼呼!底下我們就來聊一聊~

第十四章、Linux 賬号管理與 ACL 權限配置

查詢使用者: w, who, last, lastlog

如何查詢一個使用者的相關資料呢?這還不簡單,我們之前就提過了 id, finger 等指令了,都可以讓您了解到一個使用者的相關資訊啦!那麼想要知道使用者到底啥時候登陸呢? 最簡單可以使用 last 檢查啊!這個玩意兒我們也在 第十一章 bash 提過了, 您可以自行前往參考啊!簡單的很。

Tips:

早期的 Red Hat 系統的版本中, last 僅會列出當月的登陸者資訊,不過在我們的 CentOS 5.x 版以後, last 可以列出從系統建立之後到目前為止的所有登陸者資訊!這是因為登入檔輪替的配置不同所緻。 詳細的說明可以參考後續的第十九章登入檔簡介。

第十四章、Linux 賬号管理與 ACL 權限配置

那如果你想要知道目前已登陸在系統上面的使用者呢?可以透過 w 或 who 來查詢喔!如下範例所示:

[[email protected] ~]# w
 13:13:56 up 13:00,  1 user,  load average: 0.08, 0.02, 0.01
USER   TTY    FROM            LOGIN@   IDLE   JCPU   PCPU WHAT
root   pts/1  192.168.1.100   11:04    0.00s  0.36s  0.00s -bash
vbird1 pts/2  192.168.1.100   13:15    0.00s  0.06s  0.02s w
# 第一行顯示目前的時間、啟動 (up) 多久,幾個使用者在系統上平均負載等;
# 第二行隻是各個項目的說明,
# 第三行以後,每行代表一個使用者。如上所示,root 登陸并取得終端機名 pts/1 之意。

[[email protected] ~]# who
root     pts/1        2009-03-04 11:04 (192.168.1.100)
vbird1   pts/2        2009-03-04 13:15 (192.168.1.100)
      

另外,如果您想要知道每個賬号的最近登陸的時間,則可以使用 lastlog 這個指令喔! lastlog 會去讀取 /var/log/lastlog 檔案,結果将資料輸出如下表:

[[email protected] ~]# lastlog
Username    Port   From           Latest
root        pts/1  192.168.1.100  Wed Mar  4 11:04:22 +0800 2009
bin                                        **Never logged in**
....(中間省略)....
vbird1      pts/2  192.168.1.100  Wed Mar  4 13:15:56 +0800 2009
....(以下省略)....
      

這樣就能夠知道每個賬号的最近登陸的時間啰~ ^_^

第十四章、Linux 賬号管理與 ACL 權限配置

使用者對談: write, mesg, wall

那麼我是否可以跟系統上面的使用者談天說地呢?當然可以啦!利用 write 這個指令即可。 write 可以直接将資訊傳給接收者啰!舉例來說,我們的 Linux 目前有 vbird1 與 root 兩個人在線上, 我的 root 要跟 vbird1 講話,可以這樣做:

[[email protected] ~]# write 使用者賬号 [使用者所在終端接口]

[[email protected] ~]# who
root     pts/1    2009-03-04 11:04 (192.168.1.100)
vbird1   pts/2    2009-03-04 13:15 (192.168.1.100)  <==有看到 vbird1 在線上

[[email protected] ~]# write vbird1 pts/2
Hello, there:
Please don't do anything wrong...  <==這兩行是 root 寫的資訊!
# 結束時,請按下 [crtl]-d 來結束輸入。此時在 vbird1 的畫面中,會出現:

Message from [email protected] on pts/1 at 13:23 ...
Hello, there:
Please don't do anything wrong...
EOF
      

怪怪~立刻會有資訊響應給 vbird1 !不過......當時 vbird1 正在查資料,哇! 這些資訊會立刻打斷 vbird1 原本的工作喔!是以,如果 vbird1 這個人不想要接受任何資訊,直接下達這個動作:

[[email protected] ~]$ mesg n
[[email protected] ~]$ mesg
is n
      

不過,這個 mesg 的功能對 root 傳送來的資訊沒有抵擋的能力!是以如果是 root 傳送資訊, vbird1 還是得要收下。 但是如果 root 的 mesg 是 n 的,那麼 vbird1 寫給 root 的資訊會變這樣:

[[email protected] ~]$ write root
write: root has messages disabled
      

了解乎?如果想要解開的話,再次下達『 mesg y 』就好啦!想要知道目前的 mesg 狀态,直接下達『 mesg 』即可!瞭呼? 相對于 write 是僅針對一個使用者來傳『簡訊』,我們還可以『對所有系統上面的使用者傳送簡訊 (廣播)』哩~ 如何下達?用 wall 即可啊!他的文法也是很簡單的喔!

然後你就會發現所有的人都會收到這個簡訊呢!

第十四章、Linux 賬号管理與 ACL 權限配置

使用者郵件信箱: mail

使用 wall, write 畢竟要等到使用者在線上才能夠進行,有沒有其他方式來聯絡啊? 不是說每個 Linux 主機上面的使用者都具有一個 mailbox 嗎? 我們可否寄信給使用者啊!呵呵!當然可以啊!我們可以寄、收 mailbox 内的信件呢! 一般來說, mailbox 都會放置在 /var/spool/mail 裡面,一個賬号一個 mailbox (檔案)。 舉例來說,我的 vbird1 就具有 /var/spool/mail/vbird1 這個 mailbox 喔!

那麼我該如何寄出信件呢?就直接使用 mail 這個指令即可!這個指令的用法很簡單的,直接這樣下達:『 mail [email protected] -s "郵件标題" 』即可! 一般來說,如果是寄給本機上的使用者,基本上,連『 @localhost 』都不用寫啦! 舉例來說,我以 root 寄信給 vbird1 ,信件标題是『 nice to meet you 』,則:

[[email protected] ~]# mail vbird1 -s "nice to meet you"
Hello, D.M. Tsai
Nice to meet you in the network.
You are so nice.  byebye!
.    <==這裡很重要喔,結束時,最後一行輸入小數點 . 即可!
Cc:  <==這裡是所謂的『副本』,不需要寄給其他人,是以直接 [Enter]
[[email protected] ~]#  <==出現提示字元,表示輸入完畢了!
      

如此一來,你就已經寄出一封信給 vbird1 這位使用者啰,而且,該信件标題為: nice to meet you,信件内容就如同上面提到的。不過,你或許會覺得 mail 這個程式不好用~ 因為在信件編寫的過程中,如果寫錯字而按下 Enter 進入次行,前一行的資料很難删除ㄟ! 那怎麼辦?沒關系啦!我們使用資料流重導向啊!呵呵!利用那個小于的符号 ( < ) 就可以達到取代鍵盤輸入的要求了。也就是說,你可以先用 vi 将信件内容編好, 然後再以 mail vbird1 -s "nice to meet you" < filename 來将檔案内容傳輸即可。

例題: 請将你的家目錄下的環境變量檔案 (~/.bashrc) 寄給自己! 答: mail -s "bashrc file content" vbird < ~/.bashrc

剛剛上面提到的是關于『寄信』的問題,那麼如果是要收信呢?呵呵!同樣的使用 mail 啊! 假設我以 vbird1 的身份登陸主機,然後輸入 mail 後,會得到什麼?

[[email protected] ~]$ mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/spool/mail/vbird1": 1 message 1 new
>N  1 [email protected]   Wed Mar  4 13:36  18/663   "nice to meet you"
&  <==這裡可以輸入很多的指令,如果要查閱,輸入 ? 即可!
      

在 mail 當中的提示字元是 & 符号喔,别搞錯了~輸入 mail 之後,我可以看到我有一封信件, 這封信件的前面那個 > 代表目前處理的信件,而在大于符号的左邊那個 N 代表該封信件尚未讀過, 如果我想要知道這個 mail 内部的指令有哪些,可以在 & 之後輸入『 ? 』,就可以看到如下的畫面:

& ?
    Mail   Commands
t <message list>                type messages
n                               goto and type next message
e <message list>                edit messages
f <message list>                give head lines of messages
d <message list>                delete messages
s <message list> file           append messages to file
u <message list>                undelete messages
R <message list>                reply to message senders
r <message list>                reply to message senders and all recipients
pre <message list>              make messages go back to /usr/spool/mail
m <user list>                   mail to specific users
q                               quit, saving unresolved messages in mbox
x                               quit, do not remove system mailbox
h                               print out active message headers
!                               shell escape
cd [directory]                  chdir to directory or home if none given
      

<message list> 指的是每封郵件的左邊那個數字啦!而幾個比較常見的指令是:

指令 意義
h 列出信件标頭;如果要查閱 40 封信件左右的信件标頭,可以輸入『 h 40 』
d 删除後續接的信件号碼,删除單封是『 d10 』,删除 20~40 封則為『 d20-40 』。 不過,這個動作要生效的話,必須要配合 q 這個指令才行(參考底下說明)!
s 将信件儲存成檔案。例如我要将第 5 封信件的内容存成 ~/mail.file:『s 5 ~/mail.file』
x 或者輸入 exit 都可以。這個是『不作任何動作離開 mail 程式』的意思。 不論你剛剛删除了什麼信件,或者讀過什麼,使用 exit 都會直接離開 mail,是以剛剛進行的删除與閱讀工作都會無效。 如果您隻是查閱一下郵件而已的話,一般來說,建議使用這個離開啦!除非你真的要删除某些信件。
q 相對于 exit 是不動作離開, q 則會進行兩項動作: 1. 将剛剛删除的信件移出 mailbox 之外; 2. 将剛剛有閱讀過的信件存入 ~/mbox ,且移出 mailbox 之外。鳥哥通常不很喜歡使用 q 離開, 因為,很容易忘記讀過什麼咚咚~導緻信件給他移出 mailbox 說~

由于讀過的信件若使用『 q 』來離開 mail 時,會将該信件移動到 ~/mbox 中,是以你可以這樣想象: /var/spool/mail/vbird1 為 vbird1 的『新件匣』,而 /home/vbird1/mbox 則為『收件匣』的意思。 那如何讀取 /home/vbird1/mbox 呢?就使用『mail -f /home/vbird1/mbox』即可。

第十四章、Linux 賬号管理與 ACL 權限配置

手動新增使用者

一般來說,我們不很建議大家使用手動的方式來新增使用者,為什麼呢? 因為使用者的建立涉及到 GID/UID 等權限的關系,而且,與檔案/目錄的權限也有關系, 使用 useradd 可以幫我們自動配置好 UID/GID 家目錄以及家目錄相關的權限配置, 但是,手動來添加的時候,有可能會忘東忘西,結果導緻一些困擾的發生。

不過,要了解整個系統,最好還是手動來修改過比較好,至少我們的賬号問題可以完全依照自己的意思去修訂, 而不必遷就于系統的預設值啊!但是,還是要告誡一下朋友們,要手動配置賬号時, 您必須要真的很了解自己在作什麼,尤其是與權限有關的配置方面喔!好吧!底下就讓我們來玩一玩啰~ ^_^

第十四章、Linux 賬号管理與 ACL 權限配置

一些檢查工具

既然要手動修改賬号的相關配置檔案,那麼一些檢查群組、賬号相關的指令就不可不知道啊~ 尤其是那個密碼轉換的 pwconv 及 pwuconv 這兩個玩意~可重要的很呢!底下我們稍微介紹一下這些指令吧!

  • pwck

pwck 這個指令在檢查 /etc/passwd 這個賬号配置檔案内的資訊,與實際的家目錄是否存在等資訊, 還可以比對 /etc/passwd /etc/shadow 的資訊是否一緻,另外,如果 /etc/passwd 内的資料字段錯誤時,會提示使用者修訂。 一般來說,我隻是利用這個玩意兒來檢查我的輸入是否正确就是了。

[[email protected] ~]# pwck
user adm: directory /var/adm does not exist
user uucp: directory /var/spool/uucp does not exist
user gopher: directory /var/gopher does not exist
      

瞧!上面僅是告知我,這些賬号并沒有家目錄,由于那些賬号絕大部分都是系統賬号, 确實也不需要家目錄的,是以,那是『正常的錯誤!』呵呵!不理他。 ^_^。 相對應的群組檢查可以使用 grpck 這個指令的啦!

  • pwconv

這個指令主要的目的是在『将 /etc/passwd 内的賬号與密碼,移動到 /etc/shadow 當中!』 早期的 Unix 系統當中并沒有 /etc/shadow 呢,是以,使用者的登陸密碼早期是在 /etc/passwd 的第二欄,後來為了系統安全,才将密碼資料移動到 /etc/shadow 内的。使用 pwconv 後,可以:

  • 比對 /etc/passwd 及 /etc/shadow ,若 /etc/passwd 記憶體在的賬号并沒有對應的 /etc/shadow 密碼時,則 pwconv 會去 /etc/login.defs 取用相關的密碼資料,并建立該賬号的 /etc/shadow 資料;
  • 若 /etc/passwd 記憶體在加密後的密碼資料時,則 pwconv 會将該密碼欄移動到 /etc/shadow 内,并将原本的 /etc/passwd 内相對應的密碼欄變成 x !

一般來說,如果您正常使用 useradd 添加使用者時,使用 pwconv 并不會有任何的動作,因為 /etc/passwd 與 /etc/shadow 并不會有上述兩點問題啊! ^_^。不過,如果手動配置賬号,這個 pwconv 就很重要啰!

  • pwunconv

相對于 pwconv , pwunconv 則是『将 /etc/shadow 内的密碼欄資料寫回 /etc/passwd 當中, 并且删除 /etc/shadow 檔案。』這個指令說實在的,最好不要使用啦! 因為他會将你的 /etc/shadow 删除喔!如果你忘記備份,又不會使用 pwconv 的話,粉嚴重呢!

  • chpasswd

chpasswd 是個挺有趣的指令,他可以『讀入未加密前的密碼,并且經過加密後, 将加密後的密碼寫入 /etc/shadow 當中。』這個指令很常被使用在大量建置賬号的情況中喔! 他可以由 Standard input 讀入資料,每筆資料的格式是『 username:password 』。 舉例來說,我的系統當中有個使用者賬号為 dmtsai ,我想要更新他的密碼 (update) , 假如他的密碼是 abcdefg 的話,那麼我可以這樣做:

神奇吧!這樣就可以更新了呢!在預設的情況中, chpasswd 使用的是 DES 加密方法來加密, 我們可以使用 chpasswd -m 來使用 CentOS 5.x 預設的 MD5 加密方法。這個指令雖然已經很好用了,不過 CentOS 5.x 其實已經提供了『 passwd --stdin 』的選項,老實說,這個 chpasswd 可以不必使用了。但考慮其他版本不見得會提供 --stdin 給 passwd 這個指令,是以您還是得要了解一下這個指令用途!

第十四章、Linux 賬号管理與 ACL 權限配置

特殊賬号,如純數字賬号的手工建立

在我們了解了 UID/GID 與賬号的關系之後,基本上,您應該了解了,為啥我們不建議使用純數字的賬号了!因為很多時候,系統會搞不清楚那組數字是『賬号』還是『 UID 』,這不是很好啦~也是以,在早期某些版本底下,是沒有辦法使用數字來建立賬号的。例如在 Red Hat 9 的環境中, 使用『 useradd 1234 』他會顯示『 useradd: invalid user name '1234' 』了解了嗎?

Tips:

在較新的 distribution 當中,純數字的賬号已經可以被 useradd 建立了。不過鳥哥還是非常不建議使用純數字賬号。 例如在 setfacl 的配置值中,若使用『 setfacl -m u:501:rwx filename 』那個 501 代表的是 UID 還是賬号? 因為 setfacl 的配置是支援使用 UID 或賬号的,純數字賬号很容易造成系統的誤解!

第十四章、Linux 賬号管理與 ACL 權限配置

不過,有的時候,長官的指令難為啊 @_@ 有時還是得要建立這方面的賬号的,那該如何是好? 呵呵!當然可以手動來建立這樣的賬号啦!不過,為了系統安全起見,鳥哥還是不建議使用純數字的賬号的啦! 是以,底下的範例當中,我們使用手動的方式來建立一個名為 normaluser 的賬号, 而且這個賬号屬于 normalgroup 這個群組。OK!那麼整個步驟該如何是好呢? 由前面的說明來看,您應該了解了賬号與群組是與 /etc/group, /etc/shadow, /etc/passwd, /etc/gshadow 有關,是以,整個動作是這樣的:

  1. 先建立所需要的群組 ( vi /etc/group );
  2. 将 /etc/group 與 /etc/gshadow 同步化 ( grpconv );
  3. 建立賬号的各個屬性 ( vi /etc/passwd );
  4. 将 /etc/passwd 與 /etc/shadow 同步化 ( pwconv );
  5. 建立該賬号的密碼 ( passwd accountname );
  6. 建立使用者家目錄 ( cp -a /etc/skel /home/accountname );
  7. 更改使用者家目錄的屬性 ( chown -R accountname.group /home/accountname )。

夠簡單的咯吧!讓我們來玩一玩啰~

1. 建立群組 normalgroup ,假設 520 這個 GID 沒有被使用!并且同步化 gshadow
[[email protected] ~]# vi /etc/group
# 在最後一行加入底下這一行!
normalgroup:x:520:
[[email protected] ~]# grpconv
[[email protected] ~]# grep 'normalgroup' /etc/group /etc/gshadow
/etc/group:normalgroup:x:520:
/etc/gshadow:normalgroup:x::
# 最後确定 /etc/group, /etc/gshadow 都存在這個群組才行!搞定群組啰!

2. 建立 normaluser 這個賬号,假設 UID 700 沒被使用掉!
[[email protected] ~]# vi /etc/passwd
# 在最後一行加入底下這一行!
normaluser:x:700:520::/home/normaluser:/bin/bash

3. 同步化密碼,并且建立該使用者的密碼
[[email protected] ~]# pwconv
[[email protected] ~]# grep 'normaluser' /etc/passwd /etc/shadow
/etc/passwd:normaluser:x:700:520::/home/normaluser:/bin/bash
/etc/shadow:normaluser:x:14307:0:99999:7:::
# 确定 /etc/passwd, /etc/shadow 都含有 normaluser 的資訊了!但是密碼還不對~
[[email protected] ~]# passwd normaluser
Changing password for user normaluser.
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.

4. 建立使用者家目錄,并且修訂權限!
[[email protected] ~]# cp -a /etc/skel /home/normaluser
[[email protected] ~]# chown -R normaluser:normalgroup /home/normaluser
[[email protected] ~]# chmod 700 /home/normaluser
      

别懷疑!這樣就搞定了一個賬号的配置了! 從此以後,你可以建立任何名稱的賬号啰~不過,還是不建議您配置一些很怪很怪的賬号名稱啦!

第十四章、Linux 賬号管理與 ACL 權限配置

大量建置賬号範本(适用 passwd --stdin 選項)

由于 CentOS 5.x 的 passwd 已經提供了 --stdin 的功能,是以如果我們可以提供賬号密碼的話, 那麼就能夠很簡單的建置起我們的賬号密碼了。底下鳥哥制作一個簡單的 script 來運作新增使用者的功能喔!

[[email protected] ~]# vi account1.sh
#!/bin/bash
# 這支程式用來建立新增賬号,功能有:
# 1. 檢查 account1.txt 是否存在,并将該檔案内的賬号取出;
# 2. 建立上述檔案的賬号;
# 3. 将上述賬号的密碼修訂成為『強制第一次進入需要修改密碼』的格式。
# 2009/03/04    VBird
export PATH=/bin:/sbin:/usr/bin:/usr/sbin

# 檢查 account1.txt 是否存在
if [ ! -f account1.txt ]; then
        echo "所需要的賬号檔案不存在,請建立 account1.txt ,每行一個賬号名稱"
        exit 1
fi

usernames=$(cat account1.txt)

for username in $usernames
do
        useradd $username                         <==新增賬号
        echo $username | passwd --stdin $username <==與賬号相同的密碼
        chage -d 0 $username                      <==強制登陸修改密碼
done
      

接下來隻要建立 account1.txt 這個檔案即可!鳥哥建立這個檔案裡面共有十行,你可以自行建立該檔案! 内容每一行一個賬号。注意,最終的結果會是每個賬号具有與賬号相同的密碼,且初次登陸後, 必須要重新配置密碼後才能夠再次登陸使用系統資源!

[[email protected] ~]# vi account1.txt
std01
std02
std03
std04
std05
std06
std07
std08
std09
std10

[[email protected] ~]# sh account1.sh
Changing password for user std01.
passwd: all authentication tokens updated successfully.
....(後面省略)....
      

這支簡單的腳本你可以在按如下的連結下載下傳:

  • http://vbird.dic.ksu.edu.tw/linux_basic/0410accountmanager/account1.sh

另外,鳥哥的 script 是在 zh_TW.big5 的語系下建立的,如果你需要轉成萬國碼 (utf8) 的編碼格式, 請下載下傳上述檔案後,利用第十章談到的 iconv 來處理語系的問題!

第十四章、Linux 賬号管理與 ACL 權限配置

大量建置賬号的範例(适用于連續數字,如學号)

前一小節的内容已經可以滿足很多朋友的賬号建置方法了,不過,某些時候上述的 script 還是很麻煩! 因為需要手動編輯 account1.txt 嘛!如果是類似學校機關這種學号非常類似的賬号時,有沒有更快的方案? 此外,如果需要每個班級同屬于一個群組,不同班級的群組不同,又該如何建置?這是比較麻煩啦!

目前很多網站都有提供大量建立賬号的工具,例如台南縣網中心的卧龍大師:

  • http://news.ols3.net/techdoc/old/howtouse_cmpwd101.htm

提供的好用的 cmpwd 程式,但是小三大師的程式僅供學術機關使用,一般個人是無權使用的(參考上述連結的授權)。 不過,其實我們也可以利用簡單的 script 來幫我們達成喔!例如底下這支程式, 他的運作結果與小三大師提供的程式差不多啦~但是因為我是直接以 useradd 來新增的, 是以,即使不了解 UID ,也是可以适用的啦~整支程式的特色是:

  • 預設不允許使用純數字方式建立賬号;
  • 可加入年級來區分賬号;
  • 可配置賬号的起始号碼與賬号數量;
  • 有兩種密碼建立方式,可以與賬号相同或程式自行以随機數建立密碼檔案。

運作方法也簡單的要命~請自行參考的啦!不再多說~使用時請注意,不要在公家使用的主機上面進行測試,因為..... 這支程式會大量建立賬号嘛!^_^

#!/bin/bash
#
# 這支程式主要在幫您建立大量的賬号之用,更多的使用方法請參考:
# http://vbird.dic.ksu.edu.tw/linux_basic/0410accountmanager.php#manual_amount
#
# 本程式為鳥哥自行開發,在 CentOS 5.x 上使用沒有問題,
# 但不保證絕不會發生錯誤!使用時,請自行負擔風險~
#
# History:
# 2005/09/05    VBird   剛剛才寫完,使用看看先~
# 2009/03/04    VBird   加入一些語系的修改與說明,修改密碼産生方式 (用 openssl)
export LANG=zh_TW.big5
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
accountfile="user.passwd"

# 1. 進行賬号相關的輸入先!
echo ""
echo "例如我們昆山四技的學号為: 4960c001 到 4960c060 ,那麼:"
echo "賬号開頭代碼為         :4"
echo "賬号層級或年級為       :960c"
echo "号碼數字位數為(001~060):3"
echo "賬号開始号碼為         :1"
echo "賬号數量為             :60"
echo ""
read -p "賬号開頭代碼 ( Input title name, ex> std )======> " username_start
read -p "賬号層級或年級 ( Input degree, ex> 1 or enter )=> " username_degree
read -p "号碼部分的數字位數 ( Input \# of digital )======> " nu_nu
read -p "起始号碼 ( Input start number, ex> 520 )========> " nu_start
read -p "賬号數量 ( Input amount of users, ex> 100 )=====> " nu_amount
read -p "密碼标準 1) 與賬号相同 2)随機數自定義 ==============> " pwm
if [ "$username_start" == "" ]; then
        echo "沒有輸入開頭的代碼,不給你運作哩!" ; exit 1
fi
# 判斷數字系統
testing0=$(echo $nu_nu     | grep '[^0-9]' )
testing1=$(echo $nu_amount | grep '[^0-9]' )
testing2=$(echo $nu_start  | grep '[^0-9]' )
if [ "$testing0" != "" -o "$testing1" != "" -o "$testing2" != "" ]; then
        echo "輸入的号碼不對啦!有非為數字的内容!" ; exit 1
fi
if [ "$pwm" != "1" ]; then
        pwm="2"
fi

# 2. 開始輸出賬号與密碼檔案!
[ -f "$accountfile" ] && mv $accountfile "$accountfile"$(date +%Y%m%d)
nu_end=$(($nu_start+$nu_amount-1))
for (( i=$nu_start; i<=$nu_end; i++ ))
do
        nu_len=${#i}
        if [ $nu_nu -lt $nu_len ]; then
                echo "數值的位數($i->$nu_len)已經比你配置的位數($nu_nu)還大!"
                echo "程式無法繼續"
                exit 1
        fi
        nu_diff=$(( $nu_nu - $nu_len ))
        if [ "$nu_diff" != "0" ]; then
                nu_nn=0000000000
                nu_nn=${nu_nn:1:$nu_diff}
        fi
        account=${username_start}${username_degree}${nu_nn}${i}
        if [ "$pwm" == "1" ]; then
                password="$account"
        else
                password=$(openssl rand -base64 6)
        fi
        echo "$account":"$password" | tee -a "$accountfile"
done

# 3. 開始建立賬号與密碼!
cat "$accountfile" | cut -d':' -f1 | xargs -n 1 useradd -m
chpasswd < "$accountfile"
pwconv
echo "OK!建立完成!"
      

如果有需要建立同一班級具有同一群組的話,可以先使用 groupadd 建立群組後, 将該群組加入『 cat "$accountfile" | cut -d':' -f1 | xargs -n 1 useradd -m -g groupname 』那行!這支腳本可以在底下連結下載下傳:

  • http://vbird.dic.ksu.edu.tw/linux_basic/0410accountmanager/account2.sh

如果僅是測試而已,想要将剛剛建立的使用者整個删除,則可以使用如下的腳本來進行删除!

[[email protected] ~]# vi delaccount2.sh
#!/bin/bash
usernames=$(cat user.passwd | cut -d ':' -f 1)
for username in $usernames
do
	echo "userdel -r $username"
	userdel -r $username
done
[[email protected] ~]# sh delaccount2.sh
      

總之,賬号管理是很重要的!希望上面的說明能夠對大家有點幫助啦!

第十四章、Linux 賬号管理與 ACL 權限配置

重點回顧

  • Linux 作業系統上面,關于賬号與群組,其實記錄的是 UID/GID 的數字而已;
  • 使用者的賬号/群組與 UID/GID 的對應,參考 /etc/passwd 及 /etc/group 兩個檔案
  • /etc/passwd 檔案結構以冒号隔開,共分為七個字段,分别是『賬号名稱、密碼、UID、GID、全名、家目錄、shell』
  • UID 隻有 0 與非為 0 兩種,非為 0 則為一般賬号。一般賬号又分為系統賬号 (1~499) 即可登陸者賬号 (大于 500)
  • 賬号的密碼已經移動到 /etc/shadow 檔案中,該檔案權限為僅有 root 可以更動。該檔案分為九個字段,内容為『 賬号名稱、加密密碼、密碼更動日期、密碼最小可變動日期、密碼最大需變動日期、密碼過期前警告日數、密碼失效天數、 賬号失效日、保留未使用』
  • 使用者可以支援多個群組,其中在建立檔案時會影響新檔案群組者,為有效群組。而寫入 /etc/passwd 的第四個字段者, 稱為初始群組。
  • 與使用者建立、更改參數、删除有關的指令為:useradd, usermod, userdel等,密碼建立則為 passwd;
  • 與群組建立、修改、删除有關的指令為:groupadd, groupmod, groupdel 等;
  • 群組的觀察與有效群組的切換分别為:groups 及 newgrp 指令;
  • useradd 指令作用參考的檔案有: /etc/default/useradd, /etc/login.defs, /etc/skel/ 等等
  • 觀察使用者詳細的密碼參數,可以使用『 chage -l 賬号 』來處理;
  • 使用者自行修改參數的指令有: chsh, chfn 等,觀察指令則有: id, finger 等
  • ACL 可進行單一個人或群組的權限管理,但 ACL 的啟動需要有檔案系統的支援;
  • ACL 的配置可使用 setfacl ,查閱則使用 getfacl ;
  • 身份切換可使用 su ,亦可使用 sudo ,但使用 sudo 者,必須先以 visudo 配置可使用的指令;
  • PAM 子產品可進行某些程式的驗證程式!與 PAM 子產品有關的配置檔案位于 /etc/pam.d/* 及 /etc/security/*
  • 系統上面賬号登陸情況的查詢,可使用 w, who, last, lastlog 等;
  • 線上與使用者交談可使用 write, wall,脫機狀态下可使用 mail 傳送郵件!
第十四章、Linux 賬号管理與 ACL 權限配置

本章習題

  • 情境模拟題一:想将本伺服器的賬号分開管理,分為單純郵件使用,與可登陸系統賬号兩種。其中若為純郵件賬号時, 将該賬号加入 mail 為初始群組,且此賬号不可使用 bash 等 shell 登陸系統。若為可登陸賬号時, 将該賬号加入 youcan 這個次要群組。
    • 目标:了解 /sbin/nologin 的用途;
    • 前提:可自行觀察使用者是否已經建立等問題;
    • 需求:需已了解 useradd, groupadd 等指令的用法;
    解決方案如下:
    1. 預先察看一下兩個群組是否存在?
      [[email protected] ~]# grep mail /etc/group
      [[email protected] ~]# grep youcan /etc/group
      [[email protected] ~]# groupadd youcan
            
      可發現 youcan 尚未被建立,是以如上表所示,我們主動去建立這個群組啰。
    2. 開始建立三個郵件賬号,此賬号名稱為 pop1, pop2, pop3 ,且密碼與賬号相同。可使用如下的程式來處理:
      [[email protected] ~]# vim popuser.sh
      #!/bin/bash
      for username in pop1 pop2 pop3
      do
      	useradd -g mail -s /sbin/nologin -M $username
      	echo $username | passwd --stdin $username
      done
      [[email protected] ~]# sh popuser.sh
            
    3. 開始建立一般賬号,隻是這些一般賬号必須要能夠登陸,并且需要使用次要群組的支援!是以:
      [[email protected] ~]# vim loginuser.sh
      #!/bin/bash
      for username in youlog1 youlog2 youlog3
      do
      	useradd -G youcan -s /bin/bash -m $username
      	echo $username | passwd --stdin $username
      done
      [[email protected] ~]# sh loginuser.sh
            
    4. 這樣就将賬号分開管理了!非常簡單吧!

簡答題部分

  • root 的 UID 與 GID 是多少?而基于這個理由,我要讓 test 這個賬号具有 root 的權限,應該怎麼作? root 的 UID 與 GID 均為 0 ,是以要讓 test 變成 root 的權限,那麼就将 /etc/passwd 裡面, test 的 UID 與 GID 字段變成 0 即可!
  • 假設我是一個系統管理者,我有一個使用者最近不乖,是以我想暫時将他的賬号停掉, 讓他近期無法進行任何動作,等到未來他乖一點之後,我再将他的賬号激活,請問:我可以怎麼作比較好?? 由于這個賬号是暫時失效的,是以不能使用 userdel 來删除,否則很麻煩!那麼應該如何配置呢?再回去瞧一瞧 /etc/shadow 的架構,可以知道有這幾個可使用的方法:
    • 将 /etc/passwd 的 shell 字段寫成 /sbin/nologin ,即可讓該賬号暫時無法登陸主機;
    • 将 /etc/shadow 内的密碼字段,添加一個 * 号在最前面,這樣該賬号亦無法登陸!
    • 将 /etc/shadow 的第八個字段關于賬号取消日期的那個,配置小于目前日期的數字,那麼他就無法登陸系統了!
  • 我在使用 useradd 的時候,新增的賬号裡面的 UID, GID 還有其他相關的密碼控制,都是在哪幾個檔案裡面配置的? 在 /etc/login.defs 還有 /etc/default/useradd 裡面規定好的!
  • 我希望我在配置每個賬号的時候( 使用 useradd ),預設情況中,他們的家目錄就含有一個名稱為 www 的子目錄,我應該怎麼作比較好? 由于使用 useradd 的時候,會自動以 /etc/skel 做為預設的家目錄,是以,我可以在 /etc/skel 裡面新添加一個名稱為 www 的目錄即可!
  • 簡單說明系統賬号與一般使用者賬号的差别? 一般而言,為了讓系統能夠順利以較小的權限運作,系統會有很多賬号, 例如 mail, bin, adm 等等。而為了確定這些賬号能夠在系統上面具有獨一無二的權限, 一般來說 Linux 都會保留一些 UID 給系統使用。在 CentOS 5.x 上面,小于 500 以下的賬号 (UID) 即是所謂的 System account。
  • 簡單說明,為何 CentOS 5.x 建立使用者時,他會主動的幫使用者建立一個群組,而不是使用 /etc/default/useradd 的配置? 不同的 linux distributions 對于使用者 group 的建立機制并不相同。主要的機制分為:
    • Public group schemes: 使用者将會直接給予一個系統指定的群組,一般來說即是 users , 可以 SuSE Server 9 為代表;
    • Private group schemes: 系統會建立一個與賬号一樣的組名!以 CentOS 5.x 為例!
  • 如何建立一個使用者名稱 alex, 他所屬群組為 alexgroup, 預計使用 csh, 他的全名為 "Alex Tsai", 且他還得要加入 users 群組當中! groupadd alexgroup

    useradd -c "Alex Tsai" -g alexgroup -G users -m alex

    務必先建立群組,才能夠建立使用者喔!

  • 由于種種因素,導緻你的使用者家目錄以後都需要被放置到 /account 這個目錄下。 請問,我該如何作,可以讓使用 useradd 時,預設的家目錄就指向 /account ? 最簡單的方法,編輯 /etc/default/useradd ,将裡頭的 HOME=/home 改成 HOME=/account 即可。
  • 我想要讓 dmtsai 這個使用者,加入 vbird1, vbird2, vbird3 這三個群組,且不影響 dmtsai 原本已經支援的次要群組時,該如何動作? usermod -a -G vbird1,vbird2,vbird3 dmtsai
第十四章、Linux 賬号管理與 ACL 權限配置

參考資料與延伸閱讀

  • 注1:最完整與詳細的密碼檔案說明,可參考各 distribution 内部的 man page。 本文中以 CentOS 5.x 的『 man 5 passwd 』及『 man 5 shadow 』的内容說明;
  • 注2:MD5與DES均為加密的機制,詳細的解釋可參考維基百科的說明:

    MD5:http://zh.wikipedia.org/wiki/MD5

    DES:http://en.wikipedia.org/wiki/Data_Encryption_Standard

    在早期的 Linux 版本中,主要使用 DES 加密算法,近期則使用 MD5 作為預設算法。

  • 注3:telnet 與 ssh 都是可以由遠端使用者主機聯機到 Linux 伺服器的一種機制!詳細資料可查詢鳥站文章: 遠端聯機伺服器:http://vbird.dic.ksu.edu.tw/linux_server/0310telnetssh.php
  • 注4:詳細的說明請參考 man sudo ,然後以 5 作為關鍵詞搜尋看看即可了解。
  • 注5:詳細的 PAM 說明可以參考如下連結:

    維基百科:http://en.wikipedia.org/wiki/Pluggable_Authentication_Modules

    Linux-PAM網頁: http://www.kernel.org/pub/linux/libs/pam/