要登入 Linux 系統一定要有帳號與密碼才行,否則怎麼登入,您說是吧?不過, 不同的使用者應該要擁有不同的權限才行吧?我們還可以透過 user/group 的特殊權限設定, 來規範出不同的群組開發專案呢∼在 Linux 的環境下,我們可以透過很多方式來限制使用者能夠使用的系統資源, 包括 十一章、bash 提到的 ulimit 限制、還有特殊權限限制,如 umask 等等。 透過這些舉動,我們可以規範出不同使用者的使用資源。另外,還記得系統管理員的帳號嗎?對! 就是 root 。請問一下,除了 root 之外,是否可以有其他的系統管理員帳號? 為什麼大家都要盡量避免使用數字型態的帳號?如何修改使用者相關的資訊呢?這些我們都得要瞭解瞭解的! |
管理員的工作中,相當重要的一環就是『管理帳號』啦!因為整個系統都是你在管理的,
並且所有一般用戶的帳號申請,都必須要透過你的協助才行!所以你就必須要瞭解一下如何管理好一個伺服器主機的帳號啦!
在管理 Linux 主機的帳號時,我們必須先來瞭解一下 Linux 到底是如何辨別每一個使用者的!
雖然我們登入 Linux 主機的時候,輸入的是我們的帳號,但是其實 Linux 主機並不會直接認識你的『帳號名稱』的,他僅認識 ID 啊 (ID 就是一組號碼啦)。 由於電腦僅認識 0 與 1,所以主機對於數字比較有概念的;至於帳號只是為了讓人們容易記憶而已。 而你的 ID 與帳號的對應就在 /etc/passwd 當中哩。
如果你曾經在網路上下載過 tarball 類型的檔案, 那麼應該不難發現,在解壓縮之後的檔案中,檔案擁有者的欄位竟然顯示『不明的數字』?奇怪吧?這沒什麼好奇怪的,因為 Linux 說實在話,他真的只認識代表你身份的號碼而已!那麼到底有幾種 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 的用戶? [root@www ~]# grep 'dmtsai' /etc/passwd dmtsai:x:503:504::/home/dmtsai:/bin/bash <==是有這個帳號喔! [root@www ~]# ll -d /home/dmtsai drwx------ 4 dmtsai dmtsai 4096 Feb 6 18:25 /home/dmtsai # 瞧一瞧,使用者的欄位正是 dmtsai 本身喔! # 2. 修改一下,將剛剛我們的 dmtsai 的 503 UID 改為 2000 看看: [root@www ~]# vi /etc/passwd ....(前面省略).... dmtsai:x:2000:504::/home/dmtsai:/bin/bash <==修改一下特殊字體部分,由 503 改過來 [root@www ~]# ll -d /home/dmtsai drwx------ 4 503 dmtsai 4096 Feb 6 18:25 /home/dmtsai # 很害怕吧!怎麼變成 503 了?因為檔案只會記錄數字而已! # 因為我們亂改,所以導致 503 找不到對應的帳號,因此顯示數字! # 3. 記得將剛剛的 2000 改回來! [root@www ~]# vi /etc/passwd ....(前面省略).... dmtsai:x:503:504::/home/dmtsai:/bin/bash <==趕緊改回來! |
你一定要瞭解的是,上面的例子僅是在說明 UID 與帳號的對應性,在一部正常運作的 Linux 主機環境下,上面的動作不可隨便進行, 這是因為系統上已經有很多的資料被建立存在了,隨意修改系統上某些帳號的 UID 很可能會導致某些程序無法進行,這將導致系統無法順利運作的結果。 因為權限的問題啊!所以,瞭解了之後,請趕快回到 /etc/passwd 裡面,將數字改回來喔!
舉例來說,如果上面的測試最後一個步驟沒有將 2000 改回原本的 UID,那麼當 dmtsai 下次登入時將沒有辦法進入自己的家目錄! 因為他的 UID 已經改為 2000 ,但是他的家目錄 (/home/dmtsai) 卻記錄的是 503 ,由於權限是 700 , 因此他將無法進入原本的家目錄!是否非常嚴重啊?Linux 系統上面的使用者如果需要登入主機以取得 shell 的環境來工作時,他需要如何進行呢? 首先,他必須要在電腦前面利用 tty1~tty7 的終端機提供的 login 介面,並輸入帳號與密碼後才能夠登入。 如果是透過網路的話,那至少使用者就得要學習 ssh 這個功能了 (伺服器篇再來談)。 那麼你輸入帳號密碼後,系統幫你處理了什麼呢?
大致上的情況就像這樣,所以當你要登入你的 Linux 主機的時候,那個 /etc/passwd 與 /etc/shadow 就必須要讓系統讀取啦 (這也是很多攻擊者會將特殊帳號寫到 /etc/passwd 裡頭去的緣故),所以呢,如果你要備份 Linux 的系統的帳號的話,那麼這兩個檔案就一定需要備份才行呦!
由上面的流程我們也知道,跟使用者帳號有關的有兩個非常重要的檔案,一個是管理使用者 UID/GID 重要參數的
/etc/passwd ,一個則是專門管理密碼相關資料的 /etc/shadow 囉!那這兩個檔案的內容就非常值得進行研究啦!
底下我們會簡單的介紹這兩個檔案,詳細的說明可以參考 man 5 passwd 及 man 5 shadow (註1)。
這個檔案的構造是這樣的:每一行都代表一個帳號,有幾行就代表有幾個帳號在你的系統中! 不過需要特別留意的是,裡頭很多帳號本來就是系統正常運作所必須要的,我們可以簡稱他為系統帳號, 例如 bin, daemon, adm, nobody 等等,這些帳號請不要隨意的殺掉他呢! 這個檔案的內容有點像這樣:
鳥哥在接觸 Linux 之前曾經碰過 Solaris 系統 (1999 年),當時鳥哥啥也不清楚!由於『聽說』Linux 上面的帳號越複雜會導致系統越危險!所以鳥哥就將 /etc/passwd 上面的帳號全部刪除到只剩下 root 與鳥哥自己用的一般帳號!結果你猜發生什麼事?那就是....呼叫昇陽的工程師來維護系統 @_@!糗到一個不行!大家不要學啊![root@www ~]# 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 這個系統管理員那一行好了, 你可以明顯的看出來,每一行使用『:』分隔開,共有七個咚咚,分別是:
id 範圍 | 該 ID 使用者特性 |
0 (系統管理員) | 當 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/GID 有關!因此各程式當然需要讀取 /etc/passwd 來瞭解不同帳號的權限。 因此 /etc/passwd 的權限需設定為 -rw-r--r-- 這樣的情況, 雖然早期的密碼也有加密過,但卻放置到 /etc/passwd 的第二個欄位上!這樣一來很容易被有心人士所竊取的, 加密過的密碼也能夠透過暴力破解法去 trial and error (試誤) 找出來!
因為這樣的關係,所以後來發展出將密碼移動到 /etc/shadow 這個檔案分隔開來的技術, 而且還加入很多的密碼限制參數在 /etc/shadow 裡頭呢!在這裡,我們先來瞭解一下這個檔案的構造吧! 鳥哥的 /etc/shadow 檔案有點像這樣:
[root@www ~]# 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 同樣以『:』作為分隔符號,如果數一數,會發現共有九個欄位啊,這九個欄位的用途是這樣的:
[root@www ~]# echo $(($(date --date="2008/09/04" +%s)/86400+1))
14126
|
舉個例子來說好了,假如我的 dmtsai 這個使用者的密碼欄如下所示:
dmtsai:$1$vyUuj.eX$omt6lKJvMcIZHx4H7RI1V.:14299:5:60:7:5:14419: |
這表示什麼呢?先要注意的是 14299 是 2009/02/24 。所以 dmtsai 這個使用者的密碼相關意義是:
You must wait longer to change your password passwd: Authentication token manipulation error |
Warning: your password will expire in 5 days |
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: |
Your account has expired; please contact your system administrator |
透過這樣的說明,您應該會比較容易理解了吧?由於 shadow 有這樣的重要性,因此可不能隨意修改喔! 但在某些情況底下你得要使用各種方法來處理這個檔案的!舉例來說,常常聽到人家說:『我的密碼忘記了』, 或者是『我的密碼不曉得被誰改過,跟原先的不一樣了』,這個時候怎麼辦?
認識了帳號相關的兩個檔案 /etc/passwd 與 /etc/shadow 之後,你或許還是會覺得奇怪,
那麼群組的設定檔在哪裡?還有,在 /etc/passwd 的第四欄不是所謂的 GID 嗎?那又是啥?
呵呵∼此時就需要瞭解 /etc/group 與 /etc/gshadow 囉∼
這個檔案就是在記錄 GID 與群組名稱的對應了∼鳥哥測試機的 /etc/group 內容有點像這樣:
[root@www ~]# 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 |
這個檔案每一行代表一個群組,也是以冒號『:』作為欄位的分隔符號,共分為四欄,每一欄位的意義是:
談完了 /etc/passwd, /etc/shadow, /etc/group 之後,我們可以使用一個簡單的圖示來瞭解一下 UID / GID 與密碼之間的關係, 圖示如下。其實重點是 /etc/passwd 啦,其他相關的資料都是根據這個檔案的欄位去找尋出來的。 下圖中, root 的 UID 是 0 ,而 GID 也是 0 ,去找 /etc/group 可以知道 GID 為 0 時的群組名稱就是 root 哩。 至於密碼的尋找中,會找到 /etc/shadow 與 /etc/passwd 內同帳號名稱的那一行,就是密碼相關資料囉。
至於在 /etc/group 比較重要的特色在於第四欄啦,因為每個使用者都可以擁有多個支援的群組,這就好比在學校唸書的時候,
我們可以加入多個社團一樣! ^_^。不過這裡你或許會覺得奇怪的,那就是:『假如我同時加入多個群組,那麼我在作業的時候,到底是以那個群組為準?』
底下我們就來談一談這個『有效群組』的概念。
還記得每個使用者在他的 /etc/passwd 裡面的第四欄有所謂的 GID 吧?那個 GID 就是所謂的『初始群組 (initial group) 』!也就是說,當使用者一登入系統,立刻就擁有這個群組的相關權限的意思。 舉例來說,我們上面提到 dmtsai 這個使用者的 /etc/passwd 與 /etc/group 還有 /etc/gshadow 相關的內容如下:
[root@www ~]# usermod -G users dmtsai <==先設定好次要群組 [root@www ~]# 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)。
如果我以 dmtsai 這個使用者的身份登入後,該如何知道我所有支援的群組呢? 很簡單啊,直接輸入 groups 就可以了!注意喔,是 groups 有加 s 呢!結果像這樣:
[dmtsai@www ~]$ groups
dmtsai users
|
在這個輸出的訊息中,可知道 dmtsai 這個用戶同時屬於 dmtsai 及 users 這個兩個群組,而且, 第一個輸出的群組即為有效群組 (effective group) 了。 也就是說,我的有效群組為 dmtsai 啦∼此時,如果我以 touch 去建立一個新檔,例如: 『 touch test 』,那麼這個檔案的擁有者為 dmtsai ,而且群組也是 dmtsai 的啦。
[dmtsai@www ~]$ touch test [dmtsai@www ~]$ ll -rw-rw-r-- 1 dmtsai dmtsai 0 Feb 24 17:26 test |
這樣是否可以瞭解什麼是有效群組了?通常有效群組的作用是在新建檔案啦!那麼有效群組是否能夠變換?
那麼如何變更有效群組呢?就使用 newgrp 啊!不過使用 newgrp 是有限制的,那就是你想要切換的群組必須是你已經有支援的群組。舉例來說, dmtsai 可以在 dmtsai/users 這兩個群組間切換有效群組,但是 dmtsai 無法切換有效群組成為 sshd 啦!使用的方式如下:
[dmtsai@www ~]$ newgrp users [dmtsai@www ~]$ groups users dmtsai [dmtsai@www ~]$ touch test2 [dmtsai@www ~]$ 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 就是了。如果以圖示來看就是如下所示:
雖然使用者的環境設定(例如環境變數等等其他資料)不會有影響,但是使用者的『群組權限』將會重新被計算。 但是需要注意,由於是新取得一個 shell ,因此如果你想要回到原本的環境中,請輸入 exit 回到原本的 shell 喔!
既然如此,也就是說,只要我的用戶有支援的群組就是能夠切換成為有效群組!好了,
那麼如何讓一個帳號加入不同的群組就是問題的所在囉。你要加入一個群組有兩個方式,一個是透過系統管理員 (root) 利用
usermod 幫你加入,如果 root 太忙了而且你的系統有設定群組管理員,那麼你可以透過群組管理員以
gpasswd 幫你加入他所管理的群組中!詳細的作法留待下一小節再來介紹囉!
剛剛講了很多關於『有效群組』的概念,另外,也提到 newgrp 這個指令的用法, 但是,如果 /etc/gshadow 這個設定沒有搞懂得話,那麼 newgrp 是無法動作的呢! 鳥哥測試機的 /etc/gshadow 的內容有點像這樣:
[root@www ~]# head -n 4 /etc/gshadow root:::root bin:::root,bin,daemon daemon:::root,bin,daemon sys:::root,bin,adm |
這個檔案內同樣還是使用冒號『:』來作為欄位的分隔字元,而且你會發現,這個檔案幾乎與 /etc/group 一模一樣啊!是這樣沒錯∼不過,要注意的大概就是第二個欄位吧∼第二個欄位是密碼欄, 如果密碼欄上面是『!』時,表示該群組不具有群組管理員!至於第四個欄位也就是支援的帳號名稱囉∼ 這四個欄位的意義為:
以系統管理員的角度來說,這個 gshadow 最大的功能就是建立群組管理員啦! 那麼什麼是群組管理員呢?由於系統上面的帳號可能會很多,但是我們 root 可能平時太忙碌,所以當有使用者想要加入某些群組時, root 或許會沒有空管理。此時如果能夠建立群組管理員的話,那麼該群組管理員就能夠將那個帳號加入自己管理的群組中! 可以免去 root 的忙碌啦!不過,由於目前有類似 sudo 之類的工具, 所以這個群組管理員的功能已經很少使用了。我們會在後續的 gpasswd 中介紹這個實作。
好啦!既然要管理帳號,當然是由新增與移除使用者開始的囉∼底下我們就分別來談一談如何新增、
移除與更改使用者的相關資訊吧∼
要如何在 Linux 的系統新增一個使用者啊?呵呵∼真是太簡單了∼我們登入系統時會輸入 (1)帳號與 (2)密碼,
所以建立一個可用的帳號同樣的也需要這兩個資料。那帳號可以使用 useradd 來新建使用者,密碼的給予則使用 passwd
這個指令!這兩個指令下達方法如下:
[root@www ~]# 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 [root@www ~]# useradd vbird1 [root@www ~]# ll -d /home/vbird1 drwx------ 4 vbird1 vbird1 4096 Feb 25 09:38 /home/vbird1 # 預設會建立使用者家目錄,且權限為 700 !這是重點! [root@www ~]# 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/shadow 內僅會有密碼參數而不會有加密過的密碼資料,因此我們在建立使用者帳號時, 還需要使用『 passwd 帳號 』來給予密碼才算是完成了使用者建立的流程。如果由於特殊需求而需要改變使用者相關參數時, 就得要透過上述表格中的選項來進行建立了,參考底下的案例:
範例二:假設我已知道我的系統當中有個群組名稱為 users ,且 UID 700 並不存在, 請用 users 為初始群組,以及 uid 為 700 來建立一個名為 vbird2 的帳號 [root@www ~]# useradd -u 700 -g users vbird2 [root@www ~]# ll -d /home/vbird2 drwx------ 4 vbird2 users 4096 Feb 25 09:59 /home/vbird2 [root@www ~]# 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 [root@www ~]# useradd -r vbird3 [root@www ~]# ll -d /home/vbird3 ls: /home/vbird3: No such file or directory <==不會主動建立家目錄 [root@www ~]# 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 建立使用者帳號時,其實會更改不少地方,至少我們就知道底下幾個檔案:
那請教一下,你有沒有想過,為何『 useradd vbird1 』會主動在 /home/vbird1
建立起使用者的家目錄?家目錄內有什麼資料且來自哪裡?為何預設使用的是 /bin/bash 這個 shell
?為何密碼欄位已經都規範好了 (0:99999:7 那一串)?呵呵!這就得要說明一下 useradd 所使用的參考檔案囉!
其實 useradd 的預設值可以使用底下的方法呼叫出來:
[root@www ~]# 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 去觀察該檔案的內容。搭配上頭剛剛談過的範例一的運作結果,上面這些設定項目所造成的行為分別是:
除了這些基本的帳號設定值之外, 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 的加密機制處理 |
這個檔案規範的資料則是如下所示:
現在你知道啦,使用 useradd 這支程式在建立 Linux 上的帳號時,至少會參考:
這些檔案,不過,最重要的其實是建立 /etc/passwd, /etc/shadow, /etc/group, /etc/gshadow
還有使用者家目錄就是了∼所以,如果你瞭解整個系統運作的狀態,也是可以手動直接修改這幾個檔案就是了。
OK!帳號建立了,接下來處理一下使用者的密碼吧!
剛剛我們講到了,使用 useradd 建立了帳號之後,在預設的情況下,該帳號是暫時被封鎖的, 也就是說,該帳號是無法登入的,你可以去瞧一瞧 /etc/shadow 內的第二個欄位就曉得囉∼ 那該如何是好?怕什麼?直接給他設定新密碼就好了嘛!對吧∼設定密碼就使用 passwd 囉!
[root@www ~]# passwd [--stdin] <==所有人均可使用來改自己的密碼 [root@www ~]# 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 密碼 [root@www ~]# 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 自己的密碼 [vbird2@www ~]$ 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 』這個關鍵字時才是修改密碼成功喔!
與一般使用者不同的是, root 並不需要知道舊密碼就能夠幫使用者或 root 自己建立新密碼! 但如此一來有困擾∼就是如果你的親密愛人老是告訴你『我的密碼真難記,幫我設定簡單一點的!』時, 千萬不要妥協啊!這是為了系統安全...為何使用者要設訂自己的密碼會這麼麻煩啊?這是因為密碼的安全性啦!如果密碼設定太簡單, 一些有心人士就能夠很簡單的猜到你的密碼,如此一來人家就可能使用你的一般帳號登入你的主機或使用其他主機資源, 對主機的維護會造成困擾的!所以新的 distributions 是使用較嚴格的 PAM 模組來管理密碼,這個管理的機制寫在 /etc/pam.d/passwd 當中。而該檔案與密碼有關的測試模組就是使用:pam_cracklib.so,這個模組會檢驗密碼相關的資訊, 並且取代 /etc/login.defs 內的 PASS_MIN_LEN 的設定啦!關於 PAM 我們在本章後面繼續介紹,這裡先談一下, 理論上,你的密碼最好符合如下要求:
為了方便系統管理,新版的 passwd 還加入了很多創意選項喔!鳥哥個人認為最好用的大概就是這個『 --stdin 』了! 舉例來說,你想要幫 vbird2 變更密碼成為 abc543CC ,可以這樣下達指令呢!
範例三:使用 standard input 建立用戶的密碼 [root@www ~]# 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 天後帳號失效的設定 [root@www ~]# passwd -S vbird2 vbird2 PS 2009-02-26 0 99999 7 -1 (Password set, MD5 crypt.) # 上面說明密碼建立時間 (2009-02-26)、0 最小天數、99999 變更天數、7 警告日數 # 與密碼不會失效 (-1) 。 [root@www ~]# passwd -x 60 -i 10 vbird2 [root@www ~]# passwd -S vbird2 vbird2 PS 2009-02-26 0 60 7 10 (Password set, MD5 crypt.) |
那如果我想要讓某個帳號暫時無法使用密碼登入主機呢?舉例來說, vbird2 這傢伙最近老是胡亂在主機亂來, 所以我想要暫時讓她無法登入的話,最簡單的方法就是讓她的密碼變成不合法 (shadow 第 2 欄位長度變掉)! 處理的方法就更簡單的!
範例五:讓 vbird2 的帳號失效,觀察完畢後再讓她失效 [root@www ~]# passwd -l vbird2 [root@www ~]# passwd -S vbird2 vbird2 LK 2009-02-26 0 60 7 10 (Password locked.) # 嘿嘿!狀態變成『 LK, Lock 』了啦!無法登入喔! [root@www ~]# grep vbird2 /etc/shadow vbird2:!!$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10:: # 其實只是在這裡加上 !! 而已! [root@www ~]# passwd -u vbird2 [root@www ~]# grep vbird2 /etc/shadow vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10:: # 密碼欄位恢復正常! |
是否很有趣啊!您可以自行管理一下你的帳號的密碼相關參數喔!接下來讓我們用更簡單的方法來查閱密碼參數喔!
除了使用 passwd -S 之外,有沒有更詳細的密碼參數顯示功能呢?有的!那就是 chage 了! 他的用法如下:
[root@www ~]# chage [-ldEImMW] 帳號名 選項與參數: -l :列出該帳號的詳細密碼參數; -d :後面接日期,修改 shadow 第三欄位(最近一次更改密碼的日期),格式 YYYY-MM-DD -E :後面接日期,修改 shadow 第八欄位(帳號失效日),格式 YYYY-MM-DD -I :後面接天數,修改 shadow 第七欄位(密碼失效日期) -m :後面接天數,修改 shadow 第四欄位(密碼最短保留天數) -M :後面接天數,修改 shadow 第五欄位(密碼多久需要進行變更) -W :後面接天數,修改 shadow 第六欄位(密碼過期前警告日期) 範例一:列出 vbird2 的詳細密碼參數 [root@www ~]# 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 環境 [root@www ~]# useradd agetest [root@www ~]# echo "agetest" | passwd --stdin agetest [root@www ~]# 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 這個帳號在第一次登入時可以使用與帳號同名的密碼登入,
但登入時就會被要求立刻更改密碼,更改密碼完成後就會被踢出系統。再次登入時就能夠使用新密碼登入了!
這個功能對學校老師非常有幫助!因為我們不想要知道學生的密碼,那麼在初次上課時就使用與學號相同的帳號/密碼給學生,
讓她們登入時自行設定她們的密碼,如此一來就能夠避免其他同學隨意使用別人的帳號,也能夠保證學生知道如何更改自己的密碼!
所謂這『人有失手,馬有亂蹄』,您說是吧?所以囉,當然有的時候會『不小心』在 useradd 的時候加入了錯誤的設定資料。或者是,在使用 useradd 後,發現某些地方還可以進行細部修改。 此時,當然我們可以直接到 /etc/passwd 或 /etc/shadow 去修改相對應欄位的資料, 不過,Linux 也有提供相關的指令讓大家來進行帳號相關資料的微調呢∼那就是 usermod 囉∼
[root@www ~]# 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』的說明。 [root@www ~]# usermod -c "VBird's test" vbird2 [root@www ~]# grep vbird2 /etc/passwd vbird2:x:700:100:VBird's test:/home/vbird2:/bin/bash 範例二:使用者 vbird2 這個帳號在 2009/12/31 失效。 [root@www ~]# usermod -e "2009-12-31" vbird2 [root@www ~]# grep vbird2 /etc/shadow vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10:14609: 範例三:我們建立 vbird3 這個系統帳號時並沒有給予家目錄,請建立他的家目錄 [root@www ~]# ll -d ~vbird3 ls: /home/vbird3: No such file or directory <==確認一下,確實沒有家目錄的存在! [root@www ~]# cp -a /etc/skel /home/vbird3 [root@www ~]# chown -R vbird3:vbird3 /home/vbird3 [root@www ~]# chmod 700 /home/vbird3 [root@www ~]# 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 ,是因為我們僅要修改目錄的權限而非內部檔案的權限! |
這個功能就太簡單了,目的在刪除使用者的相關資料,而使用者的資料有:
整個指令的語法非常簡單:
[root@www ~]# userdel [-r] username 選項與參數: -r :連同使用者的家目錄也一起刪除 範例一:刪除 vbird2 ,連同家目錄一起刪除 [root@www ~]# userdel -r vbird2 |
這個指令下達的時候要小心了!通常我們要移除一個帳號的時候,你可以手動的將 /etc/passwd 與 /etc/shadow 裡頭的該帳號取消即可!一般而言,如果該帳號只是『暫時不啟用』的話,那麼將 /etc/shadow 裡頭帳號失效日期 (第八欄位) 設定為 0 就可以讓該帳號無法使用,但是所有跟該帳號相關的資料都會留下來! 使用 userdel 的時機通常是『你真的確定不要讓該用戶在主機上面使用任何資料了!』
另外,其實使用者如果在系統上面操作過一陣子了,那麼該使用者其實在系統內可能會含有其他檔案的。 舉例來說,他的郵件信箱 (mailbox) 或者是例行性工作排程 (crontab, 十六章) 之類的檔案。 所以,如果想要完整的將某個帳號完整的移除,最好可以在下達 userdel -r username 之前, 先以『 find / -user username 』查出整個系統內屬於 username 的檔案,然後再加以刪除吧!
不論是 useradd/usermod/userdel ,那都是系統管理員所能夠使用的指令,
如果我是一般身份使用者,那麼我是否除了密碼之外,就無法更改其他的資料呢?
當然不是啦!這裡我們介紹幾個一般身份使用者常用的帳號資料變更與查詢指令囉!
finger 的中文字面意義是:『手指』或者是『指紋』的意思。這個 finger 可以查閱很多使用者相關的資訊喔! 大部分都是在 /etc/passwd 這個檔案裡面的資訊啦!我們就先來檢查檢查使用者資訊吧!
[root@www ~]# finger [-s] username 選項與參數: -s :僅列出使用者的帳號、全名、終端機代號與登入時間等等; -m :列出與後面接的帳號相同者,而不是利用部分比對 (包括全名部分) 範例一:觀察 vbird1 的使用者相關帳號屬性 [root@www ~]# finger vbird1 Login: vbird1 Name: (null) Directory: /home/vbird1 Shell: /bin/bash Never logged in. No mail. No Plan. |
由於 finger 類似指紋的功能,他會將使用者的相關屬性列出來!如上表所示,其實他列出來的幾乎都是 /etc/passwd 檔案裡面的東西。列出的資訊說明如下:
不過是否能夠查閱到 Mail 與 Plan 則與權限有關了!因為 Mail / Plan 都是與使用者自己的權限設定有關, root 當然可以查閱到使用者的這些資訊,但是 vbird1 就不見得能夠查到 vbird3 的資訊, 因為 /var/spool/mail/vbird3 與 /home/vbird3/ 的權限分別是 660, 700 ,那 vbird1 當然就無法查閱的到! 這樣解釋可以理解吧?此外,我們可以建立自己想要執行的預定計畫,當然,最多是給自己看的!可以這樣做:
範例二:利用 vbird1 建立自己的計畫檔 [vbird1@www ~]$ echo "I will study Linux during this year." > ~/.plan [vbird1@www ~]$ 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. 範例三:找出目前在系統上面登入的使用者與登入時間 [vbird1@www ~]$ 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 有點像是: change finger 的意思!這玩意的使用方法如下:
[root@www ~]# chfn [-foph] [帳號名] 選項與參數: -f :後面接完整的大名; -o :您辦公室的房間號碼; -p :辦公室的電話號碼; -h :家裡的電話號碼! 範例一:vbird1 自己更改一下自己的相關資訊! [vbird1@www ~]$ 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. [vbird1@www ~]$ grep vbird1 /etc/passwd vbird1:x:504:505:VBird Tsai test,Dic in Ksu. Tainan,06-2727175#356,06-1234567: /home/vbird1:/bin/bash # 其實就是改到第五個欄位,該欄位裡面用多個『 , 』分隔就是了! [vbird1@www ~]$ 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
裡頭更改你『個人屬性』的那一個資料啦!不過還是可以自己玩一玩!尤其是用來提醒自己相關資料啦! ^_^
這就是 change shell 的簡寫!使用方法就更簡單了!
[vbird1@www ~]$ chsh [-ls] 選項與參數: -l :列出目前系統上面可用的 shell ,其實就是 /etc/shells 的內容! -s :設定修改自己的 Shell 囉 範例一:用 vbird1 的身份列出系統上所有合法的 shell,並且指定 csh 為自己的 shell [vbird1@www ~]$ chsh -l /bin/sh /bin/bash /sbin/nologin <==所謂:合法不可登入的 Shell 就是這玩意! /bin/tcsh /bin/csh <==這就是 C shell 啦! /bin/ksh # 其實上面的資訊就是我們在 bash 中談到的 /etc/shells 啦! [vbird1@www ~]$ 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 [vbird1@www ~]$ chsh -s /bin/bash # 測試完畢後,立刻改回來! [vbird1@www ~]$ ll $(which chsh) -rws--x--x 1 root root 19128 May 25 2008 /usr/bin/chsh |
不論是 chfn 與 chsh ,都是能夠讓一般使用者修改 /etc/passwd 這個系統檔的!所以你猜猜,這兩個檔案的權限是什麼?
一定是 SUID 的功能啦!看到這裡,想到前面!
這就是 Linux 的學習方法∼ ^_^
id 這個指令則可以查詢某人或自己的相關 UID/GID 等等的資訊,他的參數也不少,不過, 都不需要記∼反正使用 id 就全部都列出囉∼ ^_^
[root@www ~]# id [username] 範例一:查閱 root 自己的相關 ID 資訊! [root@www ~]# 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 吧∼ [root@www ~]# id vbird1 uid=504(vbird1) gid=505(vbird1) groups=505(vbird1) context=root:system_r: unconfined_t:SystemLow-SystemHigh [root@www ~]# id vbird100 id: vbird100: No such user <== id 這個指令也可以用來判斷系統上面有無某帳號! |
OK!瞭解了帳號的新增、刪除、更動與查詢後,再來我們可以聊一聊群組的相關內容了。
基本上,群組的內容都與這兩個檔案有關:/etc/group, /etc/gshadow。
群組的內容其實很簡單,都是上面兩個檔案的新增、修改與移除而已,
不過,如果再加上有效群組的概念,那麼 newgrp 與 gpasswd 則不可不知呢!
[root@www ~]# groupadd [-g gid] [-r] 群組名稱 選項與參數: -g :後面接某個特定的 GID ,用來直接給予某個 GID ∼ -r :建立系統群組啦!與 /etc/login.defs 內的 GID_MIN 有關。 範例一:新建一個群組,名稱為 group1 [root@www ~]# groupadd group1 [root@www ~]# grep group1 /etc/group /etc/gshadow /etc/group:group1:x:702: /etc/gshadow:group1:!:: # 群組的 GID 也是會由 500 以上最大 GID+1 來決定! |
曾經有某些版本的教育訓練手冊談到,為了讓使用者的 UID/GID 成對,她們建議新建的與使用者私有群組無關的其他群組時,使用小於 500 以下的 GID 為宜。
也就是說,如果要建立群組的話,最好能夠使用『 groupadd -r 群組名』的方式來建立啦!
不過,這見仁見智啦!看你自己的抉擇囉!
跟 usermod 類似的,這個指令僅是在進行 group 相關參數的修改而已。
[root@www ~]# groupmod [-g gid] [-n group_name] 群組名 選項與參數: -g :修改既有的 GID 數字; -n :修改既有的群組名稱 範例一:將剛剛上個指令建立的 group1 名稱改為 mygroup , GID 為 201 [root@www ~]# groupmod -g 201 -n mygroup group1 [root@www ~]# grep mygroup /etc/group /etc/gshadow /etc/group:mygroup:x:201: /etc/gshadow:mygroup:!:: |
不過,還是那句老話,不要隨意的更動 GID ,容易造成系統資源的錯亂喔!
呼呼! groupdel 自然就是在刪除群組的囉∼用法很簡單:
[root@www ~]# groupdel [groupname] 範例一:將剛剛的 mygroup 刪除! [root@www ~]# groupdel mygroup 範例二:若要刪除 vbird1 這個群組的話? [root@www ~]# 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 』才行喔!所以,你可以:
如果系統管理員太忙碌了,導致某些帳號想要加入某個專案時找不到人幫忙!這個時候可以建立『群組管理員』喔! 什麼是群組管理員呢?就是讓某個群組具有一個管理員,這個群組管理員可以管理哪些帳號可以加入/移出該群組! 那要如何『建立一個群組管理員』呢?就得要透過 gpasswd 囉!
# 關於系統管理員(root)做的動作: [root@www ~]# gpasswd groupname [root@www ~]# gpasswd [-A user1,...] [-M user3,...] groupname [root@www ~]# gpasswd [-rR] groupname 選項與參數: :若沒有任何參數時,表示給予 groupname 一個密碼(/etc/gshadow) -A :將 groupname 的主控權交由後面的使用者管理(該群組的管理員) -M :將某些帳號加入這個群組當中! -r :將 groupname 的密碼移除 -R :讓 groupname 的密碼欄失效 # 關於群組管理員(Group administrator)做的動作: [someone@www ~]$ gpasswd [-ad] user groupname 選項與參數: -a :將某位使用者加入到 groupname 這個群組當中! -d :將某位使用者移除出 groupname 這個群組當中。 範例一:建立一個新群組,名稱為 testgroup 且群組交由 vbird1 管理: [root@www ~]# groupadd testgroup <==先建立群組 [root@www ~]# gpasswd testgroup <==給這個群組一個密碼吧! Changing the password for group testgroup New Password: Re-enter new password: # 輸入兩次密碼就對了! [root@www ~]# gpasswd -A vbird1 testgroup <==加入群組管理員為 vbird1 [root@www ~]# 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 成員 [vbird1@www ~]$ id uid=504(vbird1) gid=505(vbird1) groups=505(vbird1) .... # 看得出來,vbird1 尚未加入 testgroup 群組喔! [vbird1@www ~]$ gpasswd -a vbird1 testgroup [vbird1@www ~]$ gpasswd -a vbird3 testgroup [vbird1@www ~]$ grep testgroup /etc/group testgroup:x:702:vbird1,vbird3 |
很有趣的一個小實驗吧!我們可以讓 testgroup 成為一個可以公開的群組,然後建立起群組管理員, 群組管理員可以有多個。在這個案例中,我將 vbird1 設定為 testgroup 的群組管理員,所以 vbird1 就可以自行增加群組成員囉∼呼呼!然後,該群組成員就能夠使用 newgrp 囉∼
帳號管理不是隨意建置幾個帳號就算了!有時候我們需要考量到一部主機上面可能有多個帳號在協同工作! 舉例來說,在大學任教時,我們學校的專題生是需要分組的,這些同一組的同學間必須要能夠互相修改對方的資料檔案, 但是同時這些同學又需要保留自己的私密資料,因此直接公開家目錄是不適宜的。那該如何是好? 為此,我們底下提供幾個例子來讓大家思考看看囉:
任務一:單純的完成上頭交代的任務,假設我們需要的帳號資料如下,你該如何實作?
帳號名稱 | 帳號全名 | 支援次要群組 | 是否可登入主機 | 密碼 |
myuser1 | 1st user | mygroup1 | 可以 | password |
myuser2 | 2nd user | mygroup1 | 可以 | password |
myuser3 | 3rd user | 無額外支援 | 不可以 | password |
處理的方法如下所示:
# 先處理帳號相關屬性的資料: [root@www ~]# groupadd mygroup1 [root@www ~]# useradd -G mygroup1 -c "1st user" myuser1 [root@www ~]# useradd -G mygroup1 -c "2nd user" myuser2 [root@www ~]# useradd -c "3rd user" -s /sbin/nologin myuser3 # 再處理帳號的密碼相關屬性的資料: [root@www ~]# echo "password" | passwd --stdin myuser1 [root@www ~]# echo "password" | passwd --stdin myuser2 [root@www ~]# echo "password" | passwd --stdin myuser3 |
要注意的地方主要有:myuser1 與 myuser2 都有支援次要群組,但該群組不見得會存在,因此需要先手動建立他! 然後 myuser3 是『不可登入系統』的帳號,因此需要使用 /sbin/nologin 這個 shell 來給予,這樣該帳號就無法登入囉! 這樣是否理解啊!接下來再來討論比較難一些的環境!如果是專題環境該如何製作?
任務二:我的使用者 pro1, pro2, pro3 是同一個專案計畫的開發人員,我想要讓這三個用戶在同一個目錄底下工作, 但這三個用戶還是擁有自己的家目錄與基本的私有群組。假設我要讓這個專案計畫在 /srv/projecta 目錄下開發, 可以如何進行?
# 1. 假設這三個帳號都尚未建立,可先建立一個名為 projecta 的群組, # 再讓這三個用戶加入其次要群組的支援即可: [root@www ~]# groupadd projecta [root@www ~]# useradd -G projecta -c "projecta user" pro1 [root@www ~]# useradd -G projecta -c "projecta user" pro2 [root@www ~]# useradd -G projecta -c "projecta user" pro3 [root@www ~]# echo "password" | passwd --stdin pro1 [root@www ~]# echo "password" | passwd --stdin pro2 [root@www ~]# echo "password" | passwd --stdin pro3 # 2. 開始建立此專案的開發目錄: [root@www ~]# mkdir /srv/projecta [root@www ~]# chgrp projecta /srv/projecta [root@www ~]# chmod 2770 /srv/projecta [root@www ~]# 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 這個專案的助理,他需要這個專案的內容, 但是他『不可以修改』專案目錄內的任何資料!那該如何是好?你或許可以這樣做:
真要命!傳統的 Linux 權限無法針對某個個人設定專屬的權限嗎?其實是可以啦!接下來我們就來談談這個功能吧!
從第六章開始,我們就一直強調 Linux 的權限概念是非常重要的!
但是傳統的權限僅有三種身份 (owner, group, others) 搭配三種權限 (r,w,x)
而已,並沒有辦法單純的針對某一個使用者或某一個群組來設定特定的權限需求,例如前一小節最後的那個任務!
此時就得要使用 ACL 這個機制啦!這玩意挺有趣的,底下我們就來談一談:
ACL 是 Access Control List 的縮寫,主要的目的是在提供傳統的 owner,group,others 的 read,write,execute 權限之外的細部權限設定。ACL 可以針對單一使用者,單一檔案或目錄來進行 r,w,x 的權限規範,對於需要特殊權限的使用狀況非常有幫助。
那 ACL 主要可以針對哪些方面來控制權限呢?他主要可以針對幾個項目:
好了,再來看看如何讓你的檔案系統可以支援 ACL 吧!
由於 ACL 是傳統的 Unix-like 作業系統權限的額外支援項目,因此要使用 ACL 必須要有檔案系統的支援才行。目前絕大部分的檔案系統都有支援 ACL 的功能,包括 ReiserFS, EXT2/EXT3, JFS, XFS 等等。在我們的 CentOS 5.x 當中,預設使用 Ext3 是啟動 ACL 支援的!至於察看你的檔案系統是否支援 ACL 可以這樣看:
[root@www ~]# mount <==直接查閱掛載參數的功能 /dev/hda2 on / type ext3 (rw) /dev/hda3 on /home type ext3 (rw) # 其他項目鳥哥都將他省略了!假設我們只要看這兩個裝置。但沒有看到 acl 喔! [root@www ~]# dumpe2fs -h /dev/hda2 <==由 superblock 內容去查詢 ....(前面省略).... Default mount options: user_xattr acl ....(後面省略).... |
由 mount 單純去查閱不見得可以看到實際的項目,由於目前新的 distributions 常常會主動加入某些預設功能, 如上表所示,其實 CentOS 5.x 在預設的情況下 (Default mount options:) 就幫你加入 acl 的支援了! 那如果你的系統預設不會幫你加上 acl 的支援呢?那你可以這樣做:
[root@www ~]# mount -o remount,acl / [root@www ~]# mount /dev/hda2 on / type ext3 (rw,acl) # 這樣就加入了!但是如果想要每次開機都生效,那就這樣做: [root@www ~]# vi /etc/fstab LABEL=/1 / ext3 defaults,acl 1 1 |
如果你不確定或者是不會使用 dumpe2fs 觀察你的檔案系統,那麼建議直接將上述的 /etc/fstab 裡面的內容修改一下即可!
好了,讓你的 filesystem 啟動 ACL 支援後,接下來該如何設定與觀察 ACL 呢? 很簡單,利用這兩個指令就可以了:
先讓我們來瞧一瞧 setfacl 如何使用吧!
[root@www ~]# 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 : [root@www ~]# touch acl_test1 [root@www ~]# ll acl_test1 -rw-r--r-- 1 root root 0 Feb 27 13:28 acl_test1 [root@www ~]# setfacl -m u:vbird1:rx acl_test1 [root@www ~]# ll acl_test1 -rw-r-xr--+ 1 root root 0 Feb 27 13:28 acl_test1 # 權限部分多了個 + ,且與原本的權限 (644) 看起來差異很大!但要如何查閱呢? [root@www ~]# setfacl -m u::rwx acl_test1 [root@www ~]# ll acl_test1 -rwxr-xr--+ 1 root root 0 Feb 27 13:28 acl_test1 # 無使用者列表,代表設定該檔案擁有者,所以上面顯示 root 的權限成為 rwx 了! |
上述動作為最簡單的 ACL 設定,利用『 u:使用者:權限 』的方式來設定的啦!設定前請加上 -m 這個選項。
如果一個檔案設定了 ACL 參數後,他的權限部分就會多出一個 + 號了!但是此時你看到的權限與實際權限可能就會有點誤差!
那要如何觀察呢?就透過 getfacl 吧!
[root@www ~]# getfacl filename 選項與參數: getfacl 的選項幾乎與 setfacl 相同!所以鳥哥這裡就免去了選項的說明啊! # 請列出剛剛我們設定的 acl_test1 的權限內容: [root@www ~]# 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 : [root@www ~]# setfacl -m g:mygroup1:rx acl_test1 [root@www ~]# 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 : [root@www ~]# setfacl -m m:r acl_test1 [root@www ~]# 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 的功能。
透過如下的設定即可搞定:
|
上面的設定我們就完成了之前任務二的後續需求喔!這麼簡單呢!接下來讓我們來測試一下,如果我用 root 或者是 pro1 的身份去 /srv/projecta 增加檔案或目錄時,該檔案或目錄是否能夠具有 ACL 的設定? 意思就是說,ACL 的權限設定是否能夠被次目錄所『繼承?』先試看看:
[root@www ~]# cd /srv/projecta [root@www ~]# touch abc1 [root@www ~]# mkdir abc2 [root@www ~]# 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 的預設權限! [root@www ~]# setfacl -m d:u:myuser1:rx /srv/projecta [root@www ~]# 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::--- [root@www ~]# cd /srv/projecta [root@www projecta]# touch zzz1 [root@www projecta]# mkdir zzz2 [root@www 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 再次確認看看! [root@www 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 系統當中還要作身份的變換?這是為啥?可能有底下幾個原因啦!
由於上述考量,所以我們都是使用一般帳號登入系統的,等有需要進行系統維護或軟體更新時才轉為 root 的身份來動作。 那如何讓一般使用者轉變身份成為 root 呢?主要有兩種方式喔:
底下我們就來說一說 su 跟 sudo 的用法啦!
su 是最簡單的身份切換指令了,他可以進行任何身份的切換唷!方法如下:
[root@www ~]# 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 的密碼喔! [root@www vbird1]# id <==提示字元的目錄是 vbird1 喔! uid=0(root) gid=0(root) groups=0(root),1(bin),... <==確實是 root 的身份! [root@www 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 的身份,所以很多資料還是無法直接利用。 [root@www vbird1]# exit <==這樣可以離開 su 的環境! |
單純使用『 su 』切換成為 root 的身份,讀取的變數設定方式為 non-login shell 的方式,這種方式很多原本的變數不會被改變, 尤其是我們之前談過很多次的 PATH 這個變數,由於沒有改變成為 root 的環境 (一堆 /sbin, /usr/sbin 等目錄都沒有被包含進來), 因此很多 root 慣用的指令就只能使用絕對路徑來執行咯。其他的還有 MAIL 這個變數,你輸入 mail 時, 收到的郵件竟然還是 vbird1 的,而不是 root 本身的郵件!是否覺得很奇怪啊!所以切換身份時,請務必使用如下的範例二:
範例二:使用 login shell 的方式切換為 root 的身份並觀察變數 [vbird1@www ~]$ su - Password: <==這裡輸入 root 的密碼喔! [root@www ~]# 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 - 喔! [root@www ~]# exit <==這樣可以離開 su 的環境! |
上述的作法是讓使用者的身份變成 root 並開始操作系統,如果想要離開 root 的身份則得要利用 exit 離開才行。 那我如果只是想要執行『一個只有 root 才能進行的指令,且執行完畢就恢復原本的身份』呢?那就可以加上 -c 這個選項囉! 請參考底下範例三!
範例三:vbird1 想要執行『 head -n 3 /etc/shadow 』一次,且已知 root 密碼 [vbird1@www ~]$ head -n 3 /etc/shadow head: cannot open `/etc/shadow' for reading: Permission denied [vbird1@www ~]$ 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::: [vbird1@www ~]$ <==注意看,身份還是 vbird1 喔!繼續使用舊的身份進行系統操作! |
由於 /etc/shadow 權限的關係,該檔案僅有 root 可以查閱。為了查閱該檔案,所以我們必須要使用 root 的身份工作。 但我只想要進行一次該指令而已,此時就使用類似上面的語法吧!好,那接下來,如果我是 root 或者是其他人, 想要變更成為某些特殊帳號,可以使用如下的方法來切換喔!
範例四:原本是 vbird1 這個使用者,想要變換身份成為 dmtsai 時? [vbird1@www ~]$ su -l dmtsai Password: <==這裡輸入 dmtsai 的密碼喔! [dmtsai@www ~]$ su - Password: <==這裡輸入 root 的密碼喔! [root@www ~]# id sshd uid=74(sshd) gid=74(sshd) groups=74(sshd) ... <==確實有存在此人 [root@www ~]# su -l sshd This account is currently not available. <==竟然說此人無法切換? [root@www ~]# finger sshd Login: sshd Name: Privilege-separated SSH Directory: /var/empty/sshd Shell: /sbin/nologin [root@www ~]# exit <==離開第二次的 su [dmtsai@www ~]$ exit <==離開第一次的 su [vbird1@www ~]$ exit <==這才是最初的環境! |
su 就這樣簡單的介紹完畢,總結一下他的用法是這樣的:
雖然使用 su 很方便啦,不過缺點是,當我的主機是多人共管的環境時,如果大家都要使用 su 來切換成為 root 的身份,那麼不就每個人都得要知道 root 的密碼,這樣密碼太多人知道可能會流出去, 很不妥當呢!怎辦?透過 sudo 來處理即可!
相對於 su 需要瞭解新切換的使用者密碼 (常常是需要 root 的密碼), sudo 的執行則僅需要自己的密碼即可!
甚至可以設定不需要密碼即可執行 sudo 呢!由於 sudo 可以讓你以其他用戶的身份執行指令
(通常是使用 root 的身份來執行指令),因此並非所有人都能夠執行 sudo ,
而是僅有規範到 /etc/sudoers 內的用戶才能夠執行 sudo 這個指令喔!說的這麼神奇,底下就來瞧瞧那 sudo
如何使用?
由於一開始系統預設僅有 root 可以執行 sudo ,因此底下的範例我們先以 root 的身份來執行,等到談到 visudo 時,再以一般使用者來討論其他 sudo 的用法吧! sudo 的語法如下:
[root@www ~]# sudo [-b] [-u 新使用者帳號] 選項與參數: -b :將後續的指令放到背景中讓系統自行執行,而不與目前的 shell 產生影響 -u :後面可以接欲切換的使用者,若無此項則代表切換身份為 root 。 範例一:你想要以 sshd 的身份在 /tmp 底下建立一個名為 mysshd 的檔案 [root@www ~]# sudo -u sshd touch /tmp/mysshd [root@www ~]# ll /tmp/mysshd -rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd # 特別留意,這個檔案的權限是由 sshd 所建立的情況喔! 範例二:你想要以 vbird1 的身份建立 ~vbird1/www 並於其中建立 index.html 檔案 [root@www ~]# sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \ > echo 'This is index.html file' > index.html" [root@www ~]# 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 的執行是這樣的流程:
所以說,sudo 執行的重點是:『能否使用 sudo 必須要看 /etc/sudoers 的設定值,
而可使用 sudo 者是透過輸入使用者自己的密碼來執行後續的指令串』喔!由於能否使用與 /etc/sudoers 有關,
所以我們當然要去編輯 sudoers 檔案啦!不過,因為該檔案的內容是有一定的規範的,因此直接使用 vi 去編輯是不好的。
此時,我們得要透過 visudo 去修改這個檔案喔!
從上面的說明我們可以知道,除了 root 之外的其他帳號,若想要使用 sudo 執行屬於 root 的權限指令,則 root 需要先使用 visudo 去修改 /etc/sudoers ,讓該帳號能夠使用全部或部分的 root 指令功能。為什麼要使用 visudo 呢?這是因為 /etc/sudoers 是有設定語法的,如果設定錯誤那會造成無法使用 sudo 指令的不良後果。因此才會使用 visudo 去修改, 並在結束離開修改畫面時,系統會去檢驗 /etc/sudoers 的語法就是了。
一般來說,visudo 的設定方式有幾種簡單的方法喔,底下我們以幾個簡單的例子來分別說明:
[root@www ~]# visudo ....(前面省略).... root ALL=(ALL) ALL <==找到這一行,大約在 76 行左右 vbird1 ALL=(ALL) ALL <==這一行是你要新增的! ....(前面省略).... |
使用者帳號 登入者的來源主機名稱=(可切換的身份) 可下達的指令
root ALL=(ALL) ALL <==這是預設值
|
[vbird1@www ~]$ tail -n 1 /etc/shadow <==注意!身份是 vbird1 tail: cannot open `/etc/shadow' for reading: Permission denied # 因為不是 root 嘛!所以當然不能查詢 /etc/shadow [vbird1@www ~]$ 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 ! |
[root@www ~]# visudo <==同樣的,請使用 root 先設定 ....(前面省略).... %wheel ALL=(ALL) ALL <==大約在 84 行左右,請將這行的 # 拿掉! # 在最左邊加上 % ,代表後面接的是一個『群組』之意!改完請儲存後離開 [root@www ~]# usermod -a -G wheel pro1 <==將 pro1 加入 wheel 的支援 |
[pro1@www ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro1 ....(前面省略).... Password: <==輸入 pro1 的密碼喔! pro3:$1$GfinyJgZ$9J8IdrBXXMwZIauANg7tW0:14302:0:99999:7::: [pro2@www ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro2 Password: pro2 is not in the sudoers file. This incident will be reported. # 仔細看錯誤訊息他是說這個 pro2 不在 /etc/sudoers 的設定中! |
[root@www ~]# visudo <==同樣的,請使用 root 先設定 ....(前面省略).... %wheel ALL=(ALL) NOPASSWD: ALL <==大約在 87 行左右,請將 # 拿掉! # 在最左邊加上 % ,代表後面接的是一個『群組』之意!改完請儲存後離開 |
[root@www ~]# visudo <==注意是 root 身份 myuser1 ALL=(root) /usr/bin/passwd <==最後指令務必用絕對路徑 |
[myuser1@www ~]$ 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. [myuser1@www ~]$ sudo passwd Changing password for user root. <==見鬼!怎麼會去改 root 的密碼? |
[root@www ~]# visudo <==注意是 root 身份 myuser1 ALL=(root) !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \ !/usr/bin/passwd root |
[root@www ~]# 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 |
[root@www ~]# visudo User_Alias ADMINS = pro1, pro2, pro3, myuser1 ADMINS ALL=(root) /bin/su - |
我們前面一直談到的大多是一般身份使用者與系統管理員 (root) 的相關操作, 而且大多是討論關於可登入系統的帳號來說。那麼換個角度想,如果我今天想要建立的, 是一個『僅能使用 mail server 相關郵件服務的帳號,而該帳號並不能登入 Linux 主機』呢?如果不能給予該帳號一個密碼,那麼該帳號就無法使用系統的各項資源,當然也包括 mail 的資源, 而如果給予一個密碼,那麼該帳號就可能可以登入 Linux 主機啊!呵呵∼傷腦筋吧∼ 所以,底下讓我們來談一談這些有趣的話題囉!
另外,在本章之前談到過 /etc/login.defs 檔案中,關於密碼長度應該預設是
5 個字串長度,但是我們上面也談到,該設定值已經被 PAM 模組所取代了,那麼 PAM
是什麼?為什麼他可以影響我們使用者的登入呢?這裡也要來談談的!
在本章一開頭的 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 編輯該檔案,內容可以是這樣:
|
在過去,我們想要對一個使用者進行認證 (authentication),得要要求使用者輸入帳號密碼, 然後透過自行撰寫的程式來判斷該帳號密碼是否正確。也因為如此,我們常常得使用不同的機制來判斷帳號密碼, 所以搞的一部主機上面擁有多個各別的認證系統,也造成帳號密碼可能不同步的驗證問題! 為了解決這個問題因此有了 PAM (Pluggable Authentication Modules, 嵌入式模組) 的機制!
PAM 可以說是一套應用程式介面 (Application Programming Interface, API),他提供了一連串的驗證機制,只要使用者將驗證階段的需求告知 PAM 後, PAM 就能夠回報使用者驗證的結果 (成功或失敗)。由於 PAM 僅是一套驗證的機制,又可以提供給其他程式所呼叫引用,因此不論你使用什麼程式,都可以使用 PAM 來進行驗證,如此一來,就能夠讓帳號密碼或者是其他方式的驗證具有一致的結果!也讓程式設計師方便處理驗證的問題喔! (註5)
如上述的圖示, PAM 是一個獨立的 API 存在,只要任何程式有需求時,可以向 PAM 發出驗證要求的通知, PAM 經過一連串的驗證後,將驗證的結果回報給該程式,然後該程式就能夠利用驗證的結果來進行可登入或顯示其他無法使用的訊息。 這也就是說,你可以在寫程式的時候將 PAM 模組的功能加入,就能夠利用 PAM 的驗證功能囉。 因此目前很多程式都會利用 PAM 喔!所以我們才要來學習他啊!
PAM 用來進行驗證的資料稱為模組 (Modules),每個 PAM 模組的功能都不太相同。舉例來說, 還記得我們在本章使用 passwd 指令時,如果隨便輸入字典上面找的到的字串, passwd 就會回報錯誤資訊了!這是為什麼呢?這就是 PAM 的 pam_cracklib.so 模組的功能!他能夠判斷該密碼是否在字典裡面! 並回報給密碼修改程式,此時就能夠瞭解你的密碼強度了。
所以,當你有任何需要判斷是否在字典當中的密碼字串時,就可以使用 pam_cracklib.so 這個模組來驗證! 並根據驗證的回報結果來撰寫你的程式呢!這樣說,可以理解 PAM 的功能了吧?沒錯! PAM 的模組也是很重要的一環!
PAM 藉由一個與程式相同檔名的設定檔來進行一連串的認證分析需求。我們同樣以 passwd 這個指令的呼叫 PAM 來說明好了。 當你執行 passwd 後,這支程式呼叫 PAM 的流程是:
從上頭的說明,我們會知道重點其實是 /etc/pam.d/ 裡面的設定檔,以及設定檔所呼叫的 PAM 模組進行的驗證工作! 既然一直談到 passwd 這個密碼修改指令,那我們就來看看 /etc/pam.d/passwd 這個設定檔的內容是怎樣吧!
[root@www ~]# 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的模組與該模組的參數。 底下我們先來談談驗證類別與控制標準這兩項資料吧!
你會發現在我們上面的表格當中出現的是『 include (包括) 』這個關鍵字,他代表的是『請呼叫後面的檔案來作為這個類別的驗證』, 所以,上述的每一行都要重複呼叫 /etc/pam.d/system-auth 那個檔案來進行驗證的意思!驗證類別主要分為四種,分別說明如下:
這四個驗證的類型通常是有順序的,不過也有例外就是了。
會有順序的原因是,(1)我們總是得要先驗證身份 (auth) 後,
(2)系統才能夠藉由使用者的身份給予適當的授權與權限設定 (account),而且(3)登入與登出期間的環境才需要設定,
也才需要記錄登入與登出的資訊 (session)。如果在運作期間需要密碼修訂時,(4)才給予 password 的類別。這樣說起來,
自然是需要有點順序吧!
那麼『驗證的控制旗標(control flag)』又是什麼?簡單的說,他就是『驗證通過的標準』啦! 這個欄位在管控該驗證的放行方式,主要也分為四種控制方式:
如果將這些控制旗標以圖示的方式配合成功與否的條件繪圖,會有點像底下這樣:
程式運作過程中遇到驗證時才會去呼叫 PAM ,而 PAM 驗證又分很多類型與控制,不同的控制旗標所回報的訊息並不相同。 如上圖所示, requisite 失敗就回報了並不會繼續,而 sufficient 則是成功就回報了也不會繼續。 至於驗證結束後所回報的資訊通常是『succes 或 failure 』而已,後續的流程還需要該程式的判斷來繼續執行才行。
談完了設定檔的語法後,現在讓我們來查閱一下 CentOS 5.x 提供的 PAM 預設檔案的內容是啥吧! 由於我們常常需要透過各種方式登入 (login) 系統,因此就來看看登入所需要的 PAM 流程為何:
[root@www ~]# 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 ,所以底下列出該設定檔 [root@www ~]# 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 模組,每個模組的功能都不太相同,詳細的模組情報可以在你的系統中找到:
例如鳥哥使用未 update 過的 CentOS 5.2 ,pam_nologin 說明文件檔在: /usr/share/doc/pam-0.99.6.2/txts/README.pam_nologin。你可以自行查閱一下該模組的功能。 鳥哥這裡僅簡單介紹幾個較常使用的模組,詳細的資訊還得要您努力查閱參考書呢! ^_^
瞭解了這些模組的大致功能後,言歸正傳,討論一下 login 的 PAM 驗證機制流程是這樣的:
總之,就是依據驗證類別 (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 私房菜伺服器篇 |
除了前一小節談到的 /etc/securetty 會影響到 root 可登入的安全終端機, /etc/nologin
會影響到一般使用者是否能夠登入的功能之外,我們也知道 PAM 相關的設定檔在 /etc/pam.d ,
說明文件在 /usr/share/doc/pam-(版本) ,模組實際在 /lib/security/ 。那麼還有沒有相關的 PAM 檔案呢?
是有的,主要都在 /etc/security 這個目錄內!我們底下介紹幾個可能會用到的設定檔喔!
我們在第十一章談到的 ulimit 功能中, 除了修改使用者的 ~/.bashrc 設定檔之外,其實系統管理員可以統一藉由 PAM 來管理的! 那就是 /etc/security/limits.conf 這個檔案的設定了。這個檔案的設定很簡單,你可以自行參考一下該檔案內容。 我們這裡僅作個簡單的介紹:
範例一:vbird1 這個用戶只能建立 100MB 的檔案,且大於 90MB 會警告 [root@www ~]# vi /etc/security/limits.conf vbird1 soft fsize 90000 vbird1 hard fsize 100000 #帳號 限制依據 限制項目 限制值 # 第一欄位為帳號,或者是群組!若為群組則前面需要加上 @ ,例如 @projecta # 第二欄位為限制的依據,是嚴格(hard),還是僅為警告(soft); # 第三欄位為相關限制,此例中限制檔案容量, # 第四欄位為限制的值,在此例中單位為 KB。 # 若以 vbird1 登入後,進行如下的操作則會有相關的限制出現! [vbird1@www ~]$ ulimit -a ....(前面省略).... file size (blocks, -f) 90000 ....(後面省略).... [vbird1@www ~]$ dd if=/dev/zero of=test bs=1M count=110 File size limit exceeded [vbird1@www ~]$ ll -k test -rw-rw-r-- 1 vbird1 vbird1 90000 Mar 4 11:30 test # 果然有限制到了 範例二:限制 pro1 這個群組,每次僅能有一個使用者登入系統 (maxlogins) [root@www ~]# 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 有個特殊的地方,由於他是在程式呼叫時才予以設定的,因此你修改完成的資料,
對於已登入系統中的使用者是沒有效果的,要等他再次登入時才會生效喔!另外,
上述的設定請在測試完成後立刻註解掉,否則下次這兩個使用者登入就會發生些許問題啦! ^_^
如果發生任何無法登入或者是產生一些你無法預期的錯誤時,由於 PAM 模組都會將資料記載在 /var/log/secure 當中,所以發生了問題請務必到該檔案內去查詢一下問題點!舉例來說, 我們在 limits.conf 的介紹內的範例二,就有談到多重登入的錯誤可以到 /var/log/secure 內查閱了! 這樣你也就知道為何第二個 pro1 無法登入啦!^_^
談了這麼多的帳號問題,總是該要談一談,那麼如何針對系統上面的使用者進行查詢吧?
想幾個狀態,如果你在 Linux 上面操作時,剛好有其他的使用者也登入主機,你想要跟他對談,該如何是好?
你想要知道某個帳號的相關資訊,該如何查閱?呼呼!底下我們就來聊一聊∼
如何查詢一個使用者的相關資料呢?這還不簡單,我們之前就提過了 id, finger 等指令了,都可以讓您瞭解到一個使用者的相關資訊啦!那麼想要知道使用者到底啥時候登入呢? 最簡單可以使用 last 檢查啊!這個玩意兒我們也在 第十一章 bash 提過了, 您可以自行前往參考啊!簡單的很。
早期的 Red Hat 系統的版本中, last 僅會列出當月的登入者資訊,不過在我們的 CentOS 5.x 版以後, last 可以列出從系統建立之後到目前為止的所有登入者資訊!這是因為登錄檔輪替的設定不同所致。 詳細的說明可以參考後續的第十九章登錄檔簡介。那如果你想要知道目前已登入在系統上面的使用者呢?可以透過 w 或 who 來查詢喔!如下範例所示:
[root@www ~]# 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 之意。 [root@www ~]# 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 檔案,結果將資料輸出如下表:
[root@www ~]# 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 ....(以下省略).... |
這樣就能夠知道每個帳號的最近登入的時間囉∼ ^_^
那麼我是否可以跟系統上面的使用者談天說地呢?當然可以啦!利用 write 這個指令即可。 write 可以直接將訊息傳給接收者囉!舉例來說,我們的 Linux 目前有 vbird1 與 root 兩個人在線上, 我的 root 要跟 vbird1 講話,可以這樣做:
[root@www ~]# write 使用者帳號 [使用者所在終端介面] [root@www ~]# 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 在線上 [root@www ~]# write vbird1 pts/2 Hello, there: Please don't do anything wrong... <==這兩行是 root 寫的資訊! # 結束時,請按下 [crtl]-d 來結束輸入。此時在 vbird1 的畫面中,會出現: Message from root@www.vbird.tsai on pts/1 at 13:23 ... Hello, there: Please don't do anything wrong... EOF |
怪怪∼立刻會有訊息回應給 vbird1 !不過......當時 vbird1 正在查資料,哇! 這些訊息會立刻打斷 vbird1 原本的工作喔!所以,如果 vbird1 這個人不想要接受任何訊息,直接下達這個動作:
[vbird1@www ~]$ mesg n [vbird1@www ~]$ mesg is n |
不過,這個 mesg 的功能對 root 傳送來的訊息沒有抵擋的能力!所以如果是 root 傳送訊息, vbird1 還是得要收下。 但是如果 root 的 mesg 是 n 的,那麼 vbird1 寫給 root 的資訊會變這樣:
[vbird1@www ~]$ write root
write: root has messages disabled
|
瞭解乎?如果想要解開的話,再次下達『 mesg y 』就好啦!想要知道目前的 mesg 狀態,直接下達『 mesg 』即可!瞭呼? 相對於 write 是僅針對一個使用者來傳『簡訊』,我們還可以『對所有系統上面的使用者傳送簡訊 (廣播)』哩∼ 如何下達?用 wall 即可啊!他的語法也是很簡單的喔!
[root@www ~]# wall "I will shutdown my linux server..."
|
然後你就會發現所有的人都會收到這個簡訊呢!
使用 wall, write 畢竟要等到使用者在線上才能夠進行,有沒有其他方式來聯絡啊? 不是說每個 Linux 主機上面的使用者都具有一個 mailbox 嗎? 我們可否寄信給使用者啊!呵呵!當然可以啊!我們可以寄、收 mailbox 內的信件呢! 一般來說, mailbox 都會放置在 /var/spool/mail 裡面,一個帳號一個 mailbox (檔案)。 舉例來說,我的 vbird1 就具有 /var/spool/mail/vbird1 這個 mailbox 喔!
那麼我該如何寄出信件呢?就直接使用 mail 這個指令即可!這個指令的用法很簡單的,直接這樣下達:『 mail username@localhost -s "郵件標題" 』即可! 一般來說,如果是寄給本機上的使用者,基本上,連『 @localhost 』都不用寫啦! 舉例來說,我以 root 寄信給 vbird1 ,信件標題是『 nice to meet you 』,則:
[root@www ~]# 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] [root@www ~]# <==出現提示字元,表示輸入完畢了! |
如此一來,你就已經寄出一封信給 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 後,會得到什麼?
[vbird1@www ~]$ mail Mail version 8.1 6/6/93. Type ? for help. "/var/spool/mail/vbird1": 1 message 1 new >N 1 root@www.vbird.tsai 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』即可。
一般來說,我們不很建議大家使用手動的方式來新增使用者,為什麼呢? 因為使用者的建立涉及到 GID/UID 等權限的關係,而且,與檔案/目錄的權限也有關係, 使用 useradd 可以幫我們自動設定好 UID/GID 家目錄以及家目錄相關的權限設定, 但是,手動來增加的時候,有可能會忘東忘西,結果導致一些困擾的發生。
不過,要瞭解整個系統,最好還是手動來修改過比較好,至少我們的帳號問題可以完全依照自己的意思去修訂,
而不必遷就於系統的預設值啊!但是,還是要告誡一下朋友們,要手動設定帳號時,
您必須要真的很瞭解自己在作什麼,尤其是與權限有關的設定方面喔!好吧!底下就讓我們來玩一玩囉∼ ^_^
既然要手動修改帳號的相關設定檔,那麼一些檢查群組、帳號相關的指令就不可不知道啊∼
尤其是那個密碼轉換的 pwconv 及 pwuconv 這兩個玩意∼可重要的很呢!底下我們稍微介紹一下這些指令吧!
pwck 這個指令在檢查 /etc/passwd 這個帳號設定檔內的資訊,與實際的家目錄是否存在等資訊, 還可以比對 /etc/passwd /etc/shadow 的資訊是否一致,另外,如果 /etc/passwd 內的資料欄位錯誤時,會提示使用者修訂。 一般來說,我只是利用這個玩意兒來檢查我的輸入是否正確就是了。
[root@www ~]# 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 這個指令的啦!
這個指令主要的目的是在『將 /etc/passwd 內的帳號與密碼,移動到 /etc/shadow 當中!』 早期的 Unix 系統當中並沒有 /etc/shadow 呢,所以,使用者的登入密碼早期是在 /etc/passwd 的第二欄,後來為了系統安全,才將密碼資料移動到 /etc/shadow 內的。使用 pwconv 後,可以:
一般來說,如果您正常使用 useradd 增加使用者時,使用 pwconv 並不會有任何的動作,因為 /etc/passwd 與
/etc/shadow 並不會有上述兩點問題啊! ^_^。不過,如果手動設定帳號,這個 pwconv 就很重要囉!
相對於 pwconv , pwunconv 則是『將 /etc/shadow 內的密碼欄資料寫回 /etc/passwd 當中,
並且刪除 /etc/shadow 檔案。』這個指令說實在的,最好不要使用啦!
因為他會將你的 /etc/shadow 刪除喔!如果你忘記備份,又不會使用 pwconv 的話,粉嚴重呢!
chpasswd 是個挺有趣的指令,他可以『讀入未加密前的密碼,並且經過加密後, 將加密後的密碼寫入 /etc/shadow 當中。』這個指令很常被使用在大量建置帳號的情況中喔! 他可以由 Standard input 讀入資料,每筆資料的格式是『 username:password 』。 舉例來說,我的系統當中有個使用者帳號為 dmtsai ,我想要更新他的密碼 (update) , 假如他的密碼是 abcdefg 的話,那麼我可以這樣做:
[root@www ~]# echo "dmtsai:abcdefg" | chpasswd -m
|
神奇吧!這樣就可以更新了呢!在預設的情況中, chpasswd 使用的是 DES 加密方法來加密, 我們可以使用 chpasswd -m 來使用 CentOS 5.x 預設的 MD5 加密方法。這個指令雖然已經很好用了,不過 CentOS 5.x 其實已經提供了『 passwd --stdin 』的選項,老實說,這個 chpasswd 可以不必使用了。但考慮其他版本不見得會提供 --stdin 給 passwd 這個指令,所以您還是得要瞭解一下這個指令用途!
在我們瞭解了 UID/GID 與帳號的關係之後,基本上,您應該瞭解了,為啥我們不建議使用純數字的帳號了!因為很多時候,系統會搞不清楚那組數字是『帳號』還是『 UID 』,這不是很好啦∼也因此,在早期某些版本底下,是沒有辦法使用數字來建立帳號的。例如在 Red Hat 9 的環境中, 使用『 useradd 1234 』他會顯示『 useradd: invalid user name '1234' 』瞭解了嗎?
在較新的 distribution 當中,純數字的帳號已經可以被 useradd 建立了。不過鳥哥還是非常不建議使用純數字帳號。 例如在 setfacl 的設定值中,若使用『 setfacl -m u:501:rwx filename 』那個 501 代表的是 UID 還是帳號? 因為 setfacl 的設定是支援使用 UID 或帳號的,純數字帳號很容易造成系統的誤解!不過,有的時候,長官的命令難為啊 @_@ 有時還是得要建立這方面的帳號的,那該如何是好? 呵呵!當然可以手動來建立這樣的帳號啦!不過,為了系統安全起見,鳥哥還是不建議使用純數字的帳號的啦! 因此,底下的範例當中,我們使用手動的方式來建立一個名為 normaluser 的帳號, 而且這個帳號屬於 normalgroup 這個群組。OK!那麼整個步驟該如何是好呢? 由前面的說明來看,您應該瞭解了帳號與群組是與 /etc/group, /etc/shadow, /etc/passwd, /etc/gshadow 有關,因此,整個動作是這樣的:
1. 建立群組 normalgroup ,假設 520 這個 GID 沒有被使用!並且同步化 gshadow [root@www ~]# vi /etc/group # 在最後一行加入底下這一行! normalgroup:x:520: [root@www ~]# grpconv [root@www ~]# grep 'normalgroup' /etc/group /etc/gshadow /etc/group:normalgroup:x:520: /etc/gshadow:normalgroup:x:: # 最後確定 /etc/group, /etc/gshadow 都存在這個群組才行!搞定群組囉! 2. 建立 normaluser 這個帳號,假設 UID 700 沒被使用掉! [root@www ~]# vi /etc/passwd # 在最後一行加入底下這一行! normaluser:x:700:520::/home/normaluser:/bin/bash 3. 同步化密碼,並且建立該使用者的密碼 [root@www ~]# pwconv [root@www ~]# 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 的資訊了!但是密碼還不對∼ [root@www ~]# passwd normaluser Changing password for user normaluser. New UNIX password: Retype new UNIX password: passwd: all authentication tokens updated successfully. 4. 建立使用者家目錄,並且修訂權限! [root@www ~]# cp -a /etc/skel /home/normaluser [root@www ~]# chown -R normaluser:normalgroup /home/normaluser [root@www ~]# chmod 700 /home/normaluser |
別懷疑!這樣就搞定了一個帳號的設定了! 從此以後,你可以建立任何名稱的帳號囉∼不過,還是不建議您設定一些很怪很怪的帳號名稱啦!
由於 CentOS 5.x 的 passwd 已經提供了 --stdin 的功能,因此如果我們可以提供帳號密碼的話, 那麼就能夠很簡單的建置起我們的帳號密碼了。底下鳥哥製作一個簡單的 script 來執行新增用戶的功能喔!
[root@www ~]# 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 這個檔案即可!鳥哥建立這個檔案裡面共有十行,你可以自行建立該檔案! 內容每一行一個帳號。注意,最終的結果會是每個帳號具有與帳號相同的密碼,且初次登入後, 必須要重新設定密碼後才能夠再次登入使用系統資源!
[root@www ~]# vi account1.txt std01 std02 std03 std04 std05 std06 std07 std08 std09 std10 [root@www ~]# sh account1.sh Changing password for user std01. passwd: all authentication tokens updated successfully. ....(後面省略).... |
這支簡單的腳本你可以在按如下的連結下載:
另外,鳥哥的 script 是在 zh_TW.big5 的語系下建立的,如果你需要轉成萬國碼 (utf8) 的編碼格式, 請下載上述檔案後,利用第十章談到的 iconv 來處理語系的問題!
前一小節的內容已經可以滿足很多朋友的帳號建置方法了,不過,某些時候上述的 script 還是很麻煩! 因為需要手動編輯 account1.txt 嘛!如果是類似學校單位這種學號非常類似的帳號時,有沒有更快的方案? 此外,如果需要每個班級同屬於一個群組,不同班級的群組不同,又該如何建置?這是比較麻煩啦!
目前很多網站都有提供大量建立帳號的工具,例如台南縣網中心的臥龍大師:
提供的好用的 cmpwd 程式,但是小三大師的程式僅供學術單位使用,一般個人是無權使用的(參考上述連結的授權)。 不過,其實我們也可以利用簡單的 script 來幫我們達成喔!例如底下這支程式, 他的執行結果與小三大師提供的程式差不多啦∼但是因為我是直接以 useradd 來新增的, 所以,即使不瞭解 UID ,也是可以適用的啦∼整支程式的特色是:
執行方法也簡單的要命∼請自行參考的啦!不再多說∼使用時請注意,不要在公家使用的主機上面進行測試,因為..... 這支程式會大量建立帳號嘛!^_^
#!/bin/bash # # 這支程式主要在幫您建立大量的帳號之用,更多的使用方法請參考: # http://linux.vbird.org/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 』那行!這支腳本可以在底下連結下載:
如果僅是測試而已,想要將剛剛建立的使用者整個刪除,則可以使用如下的腳本來進行刪除!
[root@www ~]# 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 [root@www ~]# sh delaccount2.sh |
總之,帳號管理是很重要的!希望上面的說明能夠對大家有點幫助啦!
[root@www ~]# grep mail /etc/group [root@www ~]# grep youcan /etc/group [root@www ~]# groupadd youcan |
[root@www ~]# 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 [root@www ~]# sh popuser.sh |