在 Linux 系統下管理使用者的身份與帳號!
要登入 Linux 系統一定要有帳號與密碼才行,否則怎麼登入,您說是吧?不過, 不同的使用者應該要擁有不同的權限才行吧?我們還可以透過 user/group 的特殊權限設定, 來規範出不同的群組開發專案呢~在 Linux 的環境下,我們可以透過很多方式來限制使用者能夠使用的系統資源, 包括 第十章、bash 提到的 ulimit 限制、還有特殊權限限制,如 umask 等等。 透過這些舉動,我們可以規範出不同使用者的使用資源。另外,還記得系統管理員的帳號嗎?對! 就是 root 。請問一下,除了 root 之外,是否可以有其他的系統管理員帳號? 為什麼大家都要盡量避免使用數字型態的帳號?如何修改使用者相關的資訊呢?這些我們都得要瞭解瞭解的!
管理員的工作中,相當重要的一環就是『管理帳號』啦!因為整個系統都是你在管理的, 並且所有一般用戶的帳號申請,都必須要透過你的協助才行!所以你就必須要瞭解一下如何管理好一個伺服器主機的帳號啦! 在管理 Linux 主機的帳號時,我們必須先來瞭解一下 Linux 到底是如何辨別每一個使用者的!
雖然我們登入 Linux 主機的時候,輸入的是我們的帳號,但是其實 Linux 主機並不會直接認識你的『帳號名稱』的,他僅認識 ID 啊 (ID 就是一組號碼啦)。 由於電腦僅認識 0 與 1,所以主機對於數字比較有概念的;至於帳號只是為了讓人們容易記憶而已。 而你的 ID 與帳號的對應就在 /etc/passwd 當中哩。
那麼到底有幾種 ID 呢?還記得我們在第五章內有提到過, 每一個檔案都具有『擁有人與擁有群組』的屬性嗎?沒錯啦~每個登入的使用者至少都會取得兩個 ID ,一個是使用者 ID (User ID ,簡稱 UID)、一個是群組 ID (Group ID ,簡稱 GID)。
那麼檔案如何判別他的擁有者與群組呢?其實就是利用 UID 與 GID 啦!每一個檔案都會有所謂的擁有者 ID 與擁有群組 ID ,當我們有要顯示檔案屬性的需求時,系統會依據 /etc/passwd 與 /etc/group 的內容, 找到 UID / GID 對應的帳號與群組名稱再顯示出來!我們可以作個小實驗,你可以用 root 的身份 vim /etc/passwd ,然後將你的一般身份的使用者的 ID 隨便改一個號碼,然後再到你的一般身份的目錄下看看原先該帳號擁有的檔案,你會發現該檔案的擁有人變成了 『數字了』呵呵!這樣可以理解了嗎?來看看底下的例子:
# 1. 先察看一下,系統裡面有沒有一個名為 dmtsai 的用戶? [root@study ~]# id dmtsai uid=1000(dmtsai) gid=1000(dmtsai) groups=1000(dmtsai),10(wheel) <==確定有這個帳號喔! [root@study ~]# ll -d /home/dmtsai drwx------. 17 dmtsai dmtsai 4096 Jul 17 19:51 /home/dmtsai # 瞧一瞧,使用者的欄位正是 dmtsai 本身喔! # 2. 修改一下,將剛剛我們的 dmtsai 的 1000 UID 改為 2000 看看: [root@study ~]# vim /etc/passwd ....(前面省略).... dmtsai:x:2000:1000:dmtsai:/home/dmtsai:/bin/bash <==修改一下特殊字體部分,由 1000 改過來 [root@study ~]# ll -d /home/dmtsai drwx------. 17 1000 dmtsai 4096 Jul 17 19:51 /home/dmtsai # 很害怕吧!怎麼變成 1000 了?因為檔案只會記錄 UID 的數字而已! # 因為我們亂改,所以導致 1000 找不到對應的帳號,因此顯示數字! # 3. 記得將剛剛的 2000 改回來! [root@study ~]# vim /etc/passwd ....(前面省略).... dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash <==『務必一定要』改回來!
你一定要瞭解的是,上面的例子僅是在說明 UID 與帳號的對應性,在一部正常運作的 Linux 主機環境下,上面的動作不可隨便進行, 這是因為系統上已經有很多的資料被建立存在了,隨意修改系統上某些帳號的 UID 很可能會導致某些程序無法進行,這將導致系統無法順利運作的結果, 因為權限的問題啊!所以,瞭解了之後,請趕快回到 /etc/passwd 裡面,將數字改回來喔!
Linux 系統上面的使用者如果需要登入主機以取得 shell 的環境來工作時,他需要如何進行呢? 首先,他必須要在電腦前面利用 tty1~tty6 的終端機提供的 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 等等,這些帳號請不要隨意的殺掉他呢!這個檔案的內容有點像這樣:
[root@study ~]# 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~999 (系統帳號) | 保留給系統使用的 ID,其實除了 0 之外,其他的 UID 權限與特性並沒有不一樣。預設 1000
以下的數字讓給系統作為保留帳號只是一個習慣。 由於系統上面啟動的網路服務或背景服務希望使用較小的權限去運作,因此不希望使用 root 的身份去執行這些服務, 所以我們就得要提供這些運作中程式的擁有者帳號才行。這些系統帳號通常是不可登入的, 所以才會有我們在第十章提到的 /sbin/nologin 這個特殊的 shell 存在。 根據系統帳號的由來,通常這類帳號又約略被區分為兩種:
|
1000~60000 (可登入帳號) | 給一般使用者用的。事實上,目前的 linux 核心 (3.10.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@study ~]# head -n 4 /etc/shadow root:$6$wtbCCce/PxMeE5wm$KE2IfSJr.YLP7Rcai6oa/T7KFhO...:16559:0:99999:7::: <==底下說明用 bin:*:16372:0:99999:7::: daemon:*:16372:0:99999:7::: adm:*:16372:0:99999:7:::
基本上, shadow 同樣以『:』作為分隔符號,如果數一數,會發現共有九個欄位啊,這九個欄位的用途是這樣的:
[root@study ~]# echo $(($(date --date="2015/05/04" +%s)/86400+1))
16559
上述指令中,2015/05/04 為你想要計算的日期,86400 為每一天的秒數, %s 為 1970/01/01 以來的累積總秒數。
由於 bash 僅支援整數,因此最終需要加上 1 補齊 1970/01/01 當天。舉個例子來說好了,假如我的 dmtsai 這個使用者的密碼欄如下所示:
dmtsai:$6$M4IphgNP2TmlXaSS$B418YFroYxxmm....:16559:5:60:7:5:16679:
這表示什麼呢?先要注意的是 16559 是 2015/05/04 。所以 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:你必須要輸入一次舊密碼以及兩次新密碼後,才能夠開始使用系統的各項資源。如果你是在 2015/07/08 以後嘗試以 dmtsai 登入的話,那麼就會出現如下的錯誤訊息且無法登入,因為此時你的密碼就失效去啦!
Your account has expired; please contact your system administrator
透過這樣的說明,您應該會比較容易理解了吧?由於 shadow 有這樣的重要性,因此可不能隨意修改喔! 但在某些情況底下你得要使用各種方法來處理這個檔案的!舉例來說,常常聽到人家說:『我的密碼忘記了』, 或者是『我的密碼不曉得被誰改過,跟原先的不一樣了』,這個時候怎麼辦?
另外,由於 Linux 的新舊版本差異頗大,舊的版本 (CentOS 5.x 以前) 還活在很多伺服器內!因此,如果你想要知道 shadow 是使用哪種加密的機制時, 可以透過底下的方法去查詢喔!
[root@study ~]# authconfig --test | grep hashing password hashing algorithm is sha512 # 這就是目前的密碼加密機制!
認識了帳號相關的兩個檔案 /etc/passwd 與 /etc/shadow 之後,你或許還是會覺得奇怪, 那麼群組的設定檔在哪裡?還有,在 /etc/passwd 的第四欄不是所謂的 GID 嗎?那又是啥? 呵呵~此時就需要瞭解 /etc/group 與 /etc/gshadow 囉~
這個檔案就是在記錄 GID 與群組名稱的對應了~鳥哥測試機的 /etc/group 內容有點像這樣:
[root@study ~]# head -n 4 /etc/group root:x:0: bin:x:1: daemon:x:2: sys:x:3:
這個檔案每一行代表一個群組,也是以冒號『:』作為欄位的分隔符號,共分為四欄,每一欄位的意義是:
談完了 /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@study ~]# usermod -a -G users dmtsai <==先設定好次要群組 [root@study ~]# grep dmtsai /etc/passwd /etc/group /etc/gshadow /etc/passwd:dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash /etc/group:wheel:x:10:dmtsai <==次要群組的設定、安裝時指定的 /etc/group:users:x:100:dmtsai <==次要群組的設定 /etc/group:dmtsai:x:1000: <==因為是初始群組,所以第四欄位不需要填入帳號 /etc/gshadow:wheel:::dmtsai <==次要群組的設定 /etc/gshadow:users:::dmtsai <==次要群組的設定 /etc/gshadow:dmtsai:!!::
仔細看到上面這個表格,在 /etc/passwd 裡面,dmtsai 這個使用者所屬的群組為 GID=1000 ,搜尋一下 /etc/group 得到 1000 是那個名為 dmtsai 的群組啦!這就是 initial group。因為是初始群組, 使用者一登入就會主動取得,不需要在 /etc/group 的第四個欄位寫入該帳號的!
但是非 initial group 的其他群組可就不同了。舉上面這個例子來說,我將 dmtsai 加入 users 這個群組當中,由於 users 這個群組並非是 dmtsai 的初始群組,因此, 我必須要在 /etc/group 這個檔案中,找到 users 那一行,並且將 dmtsai 這個帳號加入第四欄, 這樣 dmtsai 才能夠加入 users 這個群組啊。
那麼在這個例子當中,因為我的 dmtsai 帳號同時支援 dmtsai, wheel 與 users 這三個群組, 因此,在讀取/寫入/執行檔案時,針對群組部分,只要是 users, wheel 與 dmtsai 這三個群組擁有的功能, 我 dmtsai 這個使用者都能夠擁有喔!這樣瞭呼?不過,這是針對已經存在的檔案而言, 如果今天我要建立一個新的檔案或者是新的目錄,請問一下,新檔案的群組是 dmtsai, wheel 還是 users ?呵呵!這就得要檢查一下當時的有效群組了 (effective group)。
如果我以 dmtsai 這個使用者的身份登入後,該如何知道我所有支援的群組呢? 很簡單啊,直接輸入 groups 就可以了!注意喔,是 groups 有加 s 呢!結果像這樣:
[dmtsai@study ~]$ groups
dmtsai wheel users
在這個輸出的訊息中,可知道 dmtsai 這個用戶同時屬於 dmtsai, wheel 及 users 這三個群組,而且, 第一個輸出的群組即為有效群組 (effective group) 了。 也就是說,我的有效群組為 dmtsai 啦~此時,如果我以 touch 去建立一個新檔,例如: 『 touch test 』,那麼這個檔案的擁有者為 dmtsai ,而且群組也是 dmtsai 的啦。
[dmtsai@study ~]$ touch test [dmtsai@study ~]$ ll test -rw-rw-r--. 1 dmtsai dmtsai 0 Jul 20 19:54 test
這樣是否可以瞭解什麼是有效群組了?通常有效群組的作用是在新建檔案啦!那麼有效群組是否能夠變換?
那麼如何變更有效群組呢?就使用 newgrp 啊!不過使用 newgrp 是有限制的,那就是你想要切換的群組必須是你已經有支援的群組。舉例來說, dmtsai 可以在 dmtsai/wheel/users 這三個群組間切換有效群組,但是 dmtsai 無法切換有效群組成為 sshd 啦!使用的方式如下:
[dmtsai@study ~]$ newgrp users [dmtsai@study ~]$ groups users wheel dmtsai [dmtsai@study ~]$ touch test2 [dmtsai@study ~]$ ll test* -rw-rw-r--. 1 dmtsai dmtsai 0 Jul 20 19:54 test -rw-r--r--. 1 dmtsai users 0 Jul 20 19:56 test2 [dmtsai@study ~]$ exit # 注意!記得離開 newgrp 的環境喔!
此時,dmtsai 的有效群組就成為 users 了。我們額外的來討論一下 newgrp 這個指令,這個指令可以變更目前使用者的有效群組, 而且是另外以一個 shell 來提供這個功能的喔,所以,以上面的例子來說, dmtsai 這個使用者目前是以另一個 shell 登入的,而且新的 shell 給予 dmtsai 有效 GID 為 users 就是了。如果以圖示來看就是如下所示:
雖然使用者的環境設定(例如環境變數等等其他資料)不會有影響,但是使用者的『群組權限』將會重新被計算。 但是需要注意,由於是新取得一個 shell ,因此如果你想要回到原本的環境中,請輸入 exit 回到原本的 shell 喔!
既然如此,也就是說,只要我的用戶有支援的群組就是能夠切換成為有效群組!好了, 那麼如何讓一個帳號加入不同的群組就是問題的所在囉。你要加入一個群組有兩個方式,一個是透過系統管理員 (root) 利用 usermod 幫你加入,如果 root 太忙了而且你的系統有設定群組管理員,那麼你可以透過群組管理員以 gpasswd 幫你加入他所管理的群組中!詳細的作法留待下一小節再來介紹囉!
剛剛講了很多關於『有效群組』的概念,另外,也提到 newgrp 這個指令的用法,但是,如果 /etc/gshadow 這個設定沒有搞懂得話,那麼 newgrp 是無法動作的呢! 鳥哥測試機的 /etc/gshadow 的內容有點像這樣:
[root@study ~]# head -n 4 /etc/gshadow root::: bin::: daemon::: sys:::
這個檔案內同樣還是使用冒號『:』來作為欄位的分隔字元,而且你會發現,這個檔案幾乎與 /etc/group 一模一樣啊!是這樣沒錯~不過,要注意的大概就是第二個欄位吧~第二個欄位是密碼欄, 如果密碼欄上面是『!』或空的時,表示該群組不具有群組管理員!至於第四個欄位也就是支援的帳號名稱囉~ 這四個欄位的意義為:
以系統管理員的角度來說,這個 gshadow 最大的功能就是建立群組管理員啦! 那麼什麼是群組管理員呢?由於系統上面的帳號可能會很多,但是我們 root 可能平時太忙碌,所以當有使用者想要加入某些群組時, root 或許會沒有空管理。此時如果能夠建立群組管理員的話,那麼該群組管理員就能夠將那個帳號加入自己管理的群組中! 可以免去 root 的忙碌啦!不過,由於目前有類似 sudo 之類的工具, 所以這個群組管理員的功能已經很少使用了。我們會在後續的 gpasswd 中介紹這個實作。
好啦!既然要管理帳號,當然是由新增與移除使用者開始的囉~底下我們就分別來談一談如何新增、 移除與更改使用者的相關資訊吧~
要如何在 Linux 的系統新增一個使用者啊?呵呵~真是太簡單了~我們登入系統時會輸入 (1)帳號與 (2)密碼, 所以建立一個可用的帳號同樣的也需要這兩個資料。那帳號可以使用 useradd 來新建使用者,密碼的給予則使用 passwd 這個指令!這兩個指令下達方法如下:
[root@study ~]# 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@study ~]# useradd vbird1 [root@study ~]# ll -d /home/vbird1 drwx------. 3 vbird1 vbird1 74 Jul 20 21:50 /home/vbird1 # 預設會建立使用者家目錄,且權限為 700 !這是重點! [root@study ~]# grep vbird1 /etc/passwd /etc/shadow /etc/group /etc/passwd:vbird1:x:1003:1004::/home/vbird1:/bin/bash /etc/shadow:vbird1:!!:16636:0:99999:7::: /etc/group:vbird1:x:1004: <==預設會建立一個與帳號一模一樣的群組名
其實系統已經幫我們規定好非常多的預設值了,所以我們可以簡單的使用『 useradd 帳號 』來建立使用者即可。 CentOS 這些預設值主要會幫我們處理幾個項目:
由於在 /etc/shadow 內僅會有密碼參數而不會有加密過的密碼資料,因此我們在建立使用者帳號時, 還需要使用『 passwd 帳號 』來給予密碼才算是完成了使用者建立的流程。如果由於特殊需求而需要改變使用者相關參數時, 就得要透過上述表格中的選項來進行建立了,參考底下的案例:
範例二:假設我已知道我的系統當中有個群組名稱為 users ,且 UID 1500 並不存在, 請用 users 為初始群組,以及 uid 為 1500 來建立一個名為 vbird2 的帳號 [root@study ~]# useradd -u 1500 -g users vbird2 [root@study ~]# ll -d /home/vbird2 drwx------. 3 vbird2 users 74 Jul 20 21:52 /home/vbird2 [root@study ~]# grep vbird2 /etc/passwd /etc/shadow /etc/group /etc/passwd:vbird2:x:1500:100::/home/vbird2:/bin/bash /etc/shadow:vbird2:!!:16636:0:99999:7::: # 看一下,UID 與 initial group 確實改變成我們需要的了!
在這個範例中,我們建立的是指定一個已經存在的群組作為使用者的初始群組,因為群組已經存在, 所以在 /etc/group 裡面就不會主動的建立與帳號同名的群組了! 此外,我們也指定了特殊的 UID 來作為使用者的專屬 UID 喔!瞭解了一般帳號後,我們來瞧瞧那啥是系統帳號 (system account) 吧!
範例三:建立一個系統帳號,名稱為 vbird3 [root@study ~]# useradd -r vbird3 [root@study ~]# ll -d /home/vbird3 ls: cannot access /home/vbird3: No such file or directorya <==不會主動建立家目錄 [root@study ~]# grep vbird3 /etc/passwd /etc/shadow /etc/group /etc/passwd:vbird3:x:699:699::/home/vbird3:/bin/bash /etc/shadow:vbird3:!!:16636:::::: /etc/group:vbird3:x:699:
我們在談到 UID 的時候曾經說過一般帳號應該是 1000 號以後,那使用者自己建立的系統帳號則一般是小於 1000 號以下的。 所以在這裡我們加上 -r 這個選項以後,系統就會主動將帳號與帳號同名群組的 UID/GID 都指定小於 1000 以下, 在本案例中則是使用 699(UID) 與 699(GID) 囉!此外,由於系統帳號主要是用來進行運作系統所需服務的權限設定, 所以系統帳號預設都不會主動建立家目錄的!
由這幾個範例我們也會知道,使用 useradd 建立使用者帳號時,其實會更改不少地方,至少我們就知道底下幾個檔案:
那請教一下,你有沒有想過,為何『 useradd vbird1 』會主動在 /home/vbird1 建立起使用者的家目錄?家目錄內有什麼資料且來自哪裡?為何預設使用的是 /bin/bash 這個 shell ?為何密碼欄位已經都規範好了 (0:99999:7 那一串)?呵呵!這就得要說明一下 useradd 所使用的參考檔案囉!
其實 useradd 的預設值可以使用底下的方法呼叫出來:
[root@study ~]# 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 去觀察該檔案的內容。搭配上頭剛剛談過的範例一的運作結果,上面這些設定項目所造成的行為分別是:
系統上面 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 使用私有群組機制,因此這個設定項目是不會生效的!不要太緊張啊!
使用者的家目錄通常是與帳號同名的目錄,這個目錄將會擺放在此設定值的目錄後。所以 vbird1 的家目錄就會在 /home/vbird1/ 了!很容易理解吧!
我們在 shadow 檔案結構當中談過,第七個欄位的設定值將會影響到密碼過期後, 在多久時間內還可使用舊密碼登入。這個項目就是在指定該日數啦!如果是 0 代表密碼過期立刻失效, 如果是 -1 則是代表密碼永遠不會失效,如果是數字,如 30 ,則代表過期 30 天後才失效。
就是 shadow 內的第八欄位,你可以直接設定帳號在哪個日期後就直接失效,而不理會密碼的問題。 通常不會設定此項目,但如果是付費的會員制系統,或許這個欄位可以設定喔!
系統預設的 shell 就寫在這裡。假如你的系統為 mail server ,你希望每個帳號都只能使用 email 的收發信件功能, 而不許使用者登入系統取得 shell ,那麼可以將這裡設定為 /sbin/nologin ,如此一來,新建的使用者預設就無法登入! 也免去後續使用 usermod 進行修改的手續!
這個咚咚就是指定使用者家目錄的參考基準目錄囉~舉我們的範例一為例, vbird1 家目錄 /home/vbird1 內的各項資料,都是由 /etc/skel 所複製過去的~所以呢,未來如果我想要讓新增使用者時,該使用者的環境變數 ~/.bashrc 就設定妥當的話,您可以到 /etc/skel/.bashrc 去編輯一下,也可以建立 /etc/skel/www 這個目錄,那麼未來新增使用者後,在他的家目錄下就會有 www 那個目錄了!這樣瞭呼?
你可以使用『 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 1000 <==使用者最小的 UID,意即小於 1000 的 UID 為系統保留 UID_MAX 60000 <==使用者能夠用的最大 UID SYS_UID_MIN 201 <==保留給使用者自行設定的系統帳號最小值 UID SYS_UID_MAX 999 <==保留給使用者自行設定的系統帳號最大值 UID GID_MIN 1000 <==使用者自訂群組的最小 GID,小於 1000 為系統保留 GID_MAX 60000 <==使用者自訂群組的最大 GID SYS_GID_MIN 201 <==保留給使用者自行設定的系統帳號最小值 GID SYS_GID_MAX 999 <==保留給使用者自行設定的系統帳號最大值 GID CREATE_HOME yes <==在不加 -M 及 -m 時,是否主動建立使用者家目錄? UMASK 077 <==使用者家目錄建立的 umask ,因此權限會是 700 USERGROUPS_ENAB yes <==使用 userdel 刪除時,是否會刪除初始群組 ENCRYPT_METHOD SHA512 <==密碼加密的機制使用的是 sha512 這一個機制!
這個檔案規範的資料則是如下所示:
現在你知道啦,使用 useradd 這支程式在建立 Linux 上的帳號時,至少會參考:
這些檔案,不過,最重要的其實是建立 /etc/passwd, /etc/shadow, /etc/group, /etc/gshadow 還有使用者家目錄就是了~所以,如果你瞭解整個系統運作的狀態,也是可以手動直接修改這幾個檔案就是了。 OK!帳號建立了,接下來處理一下使用者的密碼吧!
剛剛我們講到了,使用 useradd 建立了帳號之後,在預設的情況下,該帳號是暫時被封鎖的, 也就是說,該帳號是無法登入的,你可以去瞧一瞧 /etc/shadow 內的第二個欄位就曉得囉~ 那該如何是好?怕什麼?直接給他設定新密碼就好了嘛!對吧~設定密碼就使用 passwd 囉!
[root@study ~]# passwd [--stdin] [帳號名稱] <==所有人均可使用來改自己的密碼 [root@study ~]# 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@study ~]# passwd vbird2 Changing password for user vbird2. New UNIX password: <==這裡直接輸入新的密碼,螢幕不會有任何反應 BAD PASSWORD: The password is shorter than 8 characters <==密碼太簡單或過短的錯誤! Retype new UNIX password: <==再輸入一次同樣的密碼 passwd: all authentication tokens updated successfully. <==竟然還是成功修改了!
root 果然是最偉大的人物!當我們要給予使用者密碼時,透過 root 來設定即可。 root 可以設定各式各樣的密碼,系統幾乎一定會接受!所以您瞧瞧,如同上面的範例一,明明鳥哥輸入的密碼太短了, 但是系統依舊可接受 vbird2 這樣的密碼設定。這個是 root 幫忙設定的結果,那如果是使用者自己要改密碼呢? 包括 root 也是這樣修改的喔!
範例二:用 vbird2 登入後,修改 vbird2 自己的密碼 [vbird2@study ~]$ passwd <==後面沒有加帳號,就是改自己的密碼! Changing password for user vbird2. Changing password for vbird2 (current) UNIX password: <==這裡輸入『原有的舊密碼』 New UNIX password: <==這裡輸入新密碼 BAD PASSWORD: The password is shorter than 8 characters <==密碼太短!不可以設定!重新想 New password: <==這裡輸入新想的密碼 BAD PASSWORD: The password fails the dictionary check - 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 』這個關鍵字時才是修改密碼成功喔!
為何使用者要設訂自己的密碼會這麼麻煩啊?這是因為密碼的安全性啦!如果密碼設定太簡單, 一些有心人士就能夠很簡單的猜到你的密碼,如此一來人家就可能使用你的一般帳號登入你的主機或使用其他主機資源, 對主機的維護會造成困擾的!所以新的 distributions 是使用較嚴格的 PAM 模組來管理密碼,這個管理的機制寫在 /etc/pam.d/passwd 當中。而該檔案與密碼有關的測試模組就是使用:pam_cracklib.so,這個模組會檢驗密碼相關的資訊, 並且取代 /etc/login.defs 內的 PASS_MIN_LEN 的設定啦!關於 PAM 我們在本章後面繼續介紹,這裡先談一下, 理論上,你的密碼最好符合如下要求:
為了方便系統管理,新版的 passwd 還加入了很多創意選項喔!鳥哥個人認為最好用的大概就是這個『 --stdin 』了! 舉例來說,你想要幫 vbird2 變更密碼成為 abc543CC ,可以這樣下達指令呢!
範例三:使用 standard input 建立用戶的密碼 [root@study ~]# 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@study ~]# passwd -S vbird2 vbird2 PS 2015-07-20 0 99999 7 -1 (Password set, SHA512 crypt.) # 上面說明密碼建立時間 (2015-07-20)、0 最小天數、99999 變更天數、7 警告日數與密碼不會失效 (-1) [root@study ~]# passwd -x 60 -i 10 vbird2 [root@study ~]# passwd -S vbird2 vbird2 PS 2015-07-20 0 60 7 10 (Password set, SHA512 crypt.)
那如果我想要讓某個帳號暫時無法使用密碼登入主機呢?舉例來說, vbird2 這傢伙最近老是胡亂在主機亂來, 所以我想要暫時讓她無法登入的話,最簡單的方法就是讓她的密碼變成不合法 (shadow 第 2 欄位長度變掉)! 處理的方法就更簡單的!
範例五:讓 vbird2 的帳號失效,觀察完畢後再讓她失效 [root@study ~]# passwd -l vbird2 [root@study ~]# passwd -S vbird2 vbird2 LK 2015-07-20 0 60 7 10 (Password locked.) # 嘿嘿!狀態變成『 LK, Lock 』了啦!無法登入喔! [root@study ~]# grep vbird2 /etc/shadow vbird2:!!$6$iWWO6T46$uYStdkB7QjcUpJaCLB.OOp...:16636:0:60:7:10:: # 其實只是在這裡加上 !! 而已! [root@study ~]# passwd -u vbird2 [root@study ~]# grep vbird2 /etc/shadow vbird2:$6$iWWO6T46$uYStdkB7QjcUpJaCLB.OOp...:16636:0:60:7:10:: # 密碼欄位恢復正常!
是否很有趣啊!您可以自行管理一下你的帳號的密碼相關參數喔!接下來讓我們用更簡單的方法來查閱密碼參數喔!
除了使用 passwd -S 之外,有沒有更詳細的密碼參數顯示功能呢?有的!那就是 chage 了!他的用法如下:
[root@study ~]# chage [-ldEImMW] 帳號名 選項與參數: -l :列出該帳號的詳細密碼參數; -d :後面接日期,修改 shadow 第三欄位(最近一次更改密碼的日期),格式 YYYY-MM-DD -E :後面接日期,修改 shadow 第八欄位(帳號失效日),格式 YYYY-MM-DD -I :後面接天數,修改 shadow 第七欄位(密碼失效日期) -m :後面接天數,修改 shadow 第四欄位(密碼最短保留天數) -M :後面接天數,修改 shadow 第五欄位(密碼多久需要進行變更) -W :後面接天數,修改 shadow 第六欄位(密碼過期前警告日期) 範例一:列出 vbird2 的詳細密碼參數 [root@study ~]# chage -l vbird2 Last password change : Jul 20, 2015 Password expires : Sep 18, 2015 Password inactive : Sep 28, 2015 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@study ~]# useradd agetest [root@study ~]# echo "agetest" | passwd --stdin agetest [root@study ~]# chage -d 0 agetest [root@study ~]# chage -l agetest | head -n 3 Last password change : password must be changed Password expires : password must be changed Password inactive : password must be changed # 此時此帳號的密碼建立時間會被改為 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@study ~]# 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@study ~]# usermod -c "VBird's test" vbird2 [root@study ~]# grep vbird2 /etc/passwd vbird2:x:1500:100:VBird's test:/home/vbird2:/bin/bash 範例二:使用者 vbird2 這個帳號在 2015/12/31 失效。 [root@study ~]# usermod -e "2015-12-31" vbird2 [root@study ~]# chage -l vbird2 | grep 'Account expires' Account expires : Dec 31, 2015 範例三:我們建立 vbird3 這個系統帳號時並沒有給予家目錄,請建立他的家目錄 [root@study ~]# ll -d ~vbird3 ls: cannot access /home/vbird3: No such file or directory <==確認一下,確實沒有家目錄的存在! [root@study ~]# cp -a /etc/skel /home/vbird3 [root@study ~]# chown -R vbird3:vbird3 /home/vbird3 [root@study ~]# chmod 700 /home/vbird3 [root@study ~]# ll -a ~vbird3 drwx------. 3 vbird3 vbird3 74 May 4 17:51 . <==使用者家目錄權限 drwxr-xr-x. 10 root root 4096 Jul 20 22:51 .. -rw-r--r--. 1 vbird3 vbird3 18 Mar 6 06:06 .bash_logout -rw-r--r--. 1 vbird3 vbird3 193 Mar 6 06:06 .bash_profile -rw-r--r--. 1 vbird3 vbird3 231 Mar 6 06:06 .bashrc drwxr-xr-x. 4 vbird3 vbird3 37 May 4 17:51 .mozilla # 使用 chown -R 是為了連同家目錄底下的使用者/群組屬性都一起變更的意思; # 使用 chmod 沒有 -R ,是因為我們僅要修改目錄的權限而非內部檔案的權限!
這個功能就太簡單了,目的在刪除使用者的相關資料,而使用者的資料有:
整個指令的語法非常簡單:
[root@study ~]# userdel [-r] username 選項與參數: -r :連同使用者的家目錄也一起刪除 範例一:刪除 vbird2 ,連同家目錄一起刪除 [root@study ~]# userdel -r vbird2
這個指令下達的時候要小心了!通常我們要移除一個帳號的時候,你可以手動的將 /etc/passwd 與 /etc/shadow 裡頭的該帳號取消即可!一般而言,如果該帳號只是『暫時不啟用』的話,那麼將 /etc/shadow 裡頭帳號失效日期 (第八欄位) 設定為 0 就可以讓該帳號無法使用,但是所有跟該帳號相關的資料都會留下來! 使用 userdel 的時機通常是『你真的確定不要讓該用戶在主機上面使用任何資料了!』
另外,其實使用者如果在系統上面操作過一陣子了,那麼該使用者其實在系統內可能會含有其他檔案的。 舉例來說,他的郵件信箱 (mailbox) 或者是例行性工作排程 (crontab, 十五章) 之類的檔案。 所以,如果想要完整的將某個帳號完整的移除,最好可以在下達 userdel -r username 之前, 先以『 find / -user username 』查出整個系統內屬於 username 的檔案,然後再加以刪除吧!
不論是 useradd/usermod/userdel ,那都是系統管理員所能夠使用的指令, 如果我是一般身份使用者,那麼我是否除了密碼之外,就無法更改其他的資料呢? 當然不是啦!這裡我們介紹幾個一般身份使用者常用的帳號資料變更與查詢指令囉!
id 這個指令則可以查詢某人或自己的相關 UID/GID 等等的資訊,他的參數也不少,不過,都不需要記~反正使用 id 就全部都列出囉! 另外,也回想一下,我們在前一章談到的迴圈時,就有用過這個指令喔! ^_^
[root@study ~]# id [username] 範例一:查閱 root 自己的相關 ID 資訊! [root@study ~]# id uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t: s0-s0:c0.c1023 # 上面資訊其實是同一行的資料!包括會顯示 UID/GID 以及支援的所有群組! # 至於後面那個 context=... 則是 SELinux 的內容,先不要理會他! 範例二:查閱一下 vbird1 吧~ [root@study ~]# id vbird1 uid=1003(vbird1) gid=1004(vbird1) groups=1004(vbird1) [root@study ~]# id vbird100 id: vbird100: No such user <== id 這個指令也可以用來判斷系統上面有無某帳號!
finger 的中文字面意義是:『手指』或者是『指紋』的意思。這個 finger 可以查閱很多使用者相關的資訊喔! 大部分都是在 /etc/passwd 這個檔案裡面的資訊啦!不過,這個指令有點危險,所以新的版本中已經預設不安裝這個軟體! 好啦!現在繼續來安裝軟體先~記得第九章 dos2unix 的安裝方式! 假設你已經將光碟機或光碟映像檔掛載在 /mnt 底下了,所以:
[root@study ~]# df -hT /mnt Filesystem Type Size Used Avail Use% Mounted on /dev/sr0 iso9660 7.1G 7.1G 0 100% /mnt # 先確定是有掛載光碟的啦! [root@study ~]# rpm -ivh /mnt/Packages/finger-[0-9]*
我們就先來檢查檢查使用者資訊吧!
[root@study ~]# finger [-s] username 選項與參數: -s :僅列出使用者的帳號、全名、終端機代號與登入時間等等; -m :列出與後面接的帳號相同者,而不是利用部分比對 (包括全名部分) 範例一:觀察 vbird1 的使用者相關帳號屬性 [root@study ~]# finger vbird1 Login: vbird1 Name: 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@study ~]$ echo "I will study Linux during this year." > ~/.plan [vbird1@study ~]$ finger vbird1 Login: vbird1 Name: Directory: /home/vbird1 Shell: /bin/bash Last login Mon Jul 20 23:06 (CST) on pts/0 No mail. Plan: I will study Linux during this year. 範例三:找出目前在系統上面登入的使用者與登入時間 [vbird1@study ~]$ finger Login Name Tty Idle Login Time Office Office Phone Host dmtsai dmtsai tty2 11d Jul 7 23:07 dmtsai dmtsai pts/0 Jul 20 17:59
在範例三當中,我們發現輸出的資訊還會有 Office, Office Phone 等資訊,那這些資訊要如何記錄呢? 底下我們會介紹 chfn 這個指令!來看看如何修改使用者的 finger 資料吧!
chfn 有點像是: change finger 的意思!這玩意的使用方法如下:
[root@study ~]# chfn [-foph] [帳號名] 選項與參數: -f :後面接完整的大名; -o :您辦公室的房間號碼; -p :辦公室的電話號碼; -h :家裡的電話號碼! 範例一:vbird1 自己更改一下自己的相關資訊! [vbird1@study ~]$ chfn Changing finger information for vbird1. Name []: VBird Tsai test <==輸入你想要呈現的全名 Office []: DIC in KSU <==辦公室號碼 Office Phone []: 06-2727175#356 <==辦公室電話 Home Phone []: 06-1234567 <==家裡電話號碼 Password: <==確認身份,所以輸入自己的密碼 Finger information changed. [vbird1@study ~]$ grep vbird1 /etc/passwd vbird1:x:1003:1004:VBird Tsai test,DIC in KSU,06-2727175#356,06-1234567:/home/vbird1:/bin/bash # 其實就是改到第五個欄位,該欄位裡面用多個『 , 』分隔就是了! [vbird1@study ~]$ finger vbird1 Login: vbird1 Name: VBird Tsai test Directory: /home/vbird1 Shell: /bin/bash Office: DIC in KSU, 06-2727175#356 Home Phone: 06-1234567 Last login Mon Jul 20 23:12 (CST) on pts/0 No mail. Plan: I will study Linux during this year. # 就是上面特殊字體呈現的那些地方是由 chfn 所修改出來的!
這個指令說實在的,除非是你的主機有很多的用戶,否則倒真是用不著這個程式!這就有點像是 bbs 裡頭更改你『個人屬性』的那一個資料啦!不過還是可以自己玩一玩!尤其是用來提醒自己相關資料啦! ^_^
這就是 change shell 的簡寫!使用方法就更簡單了!
[vbird1@study ~]$ chsh [-ls] 選項與參數: -l :列出目前系統上面可用的 shell ,其實就是 /etc/shells 的內容! -s :設定修改自己的 Shell 囉 範例一:用 vbird1 的身份列出系統上所有合法的 shell,並且指定 csh 為自己的 shell [vbird1@study ~]$ chsh -l /bin/sh /bin/bash /sbin/nologin <==所謂:合法不可登入的 Shell 就是這玩意! /usr/bin/sh /usr/bin/bash /usr/sbin/nologin /bin/tcsh /bin/csh <==這就是 C shell 啦! # 其實上面的資訊就是我們在 bash 中談到的 /etc/shells 啦! [vbird1@study ~]$ chsh -s /bin/csh; grep vbird1 /etc/passwd Changing shell for vbird1. Password: <==確認身份,請輸入 vbird1 的密碼 Shell changed. vbird1:x:1003:1004:VBird Tsai test,DIC in KSU,06-2727175#356,06-1234567:/home/vbird1:/bin/csh [vbird1@study ~]$ chsh -s /bin/bash # 測試完畢後,立刻改回來! [vbird1@study ~]$ ll $(which chsh) -rws--x--x. 1 root root 23856 Mar 6 13:59 /bin/chsh
不論是 chfn 與 chsh ,都是能夠讓一般使用者修改 /etc/passwd 這個系統檔的!所以你猜猜,這兩個檔案的權限是什麼? 一定是 SUID 的功能啦!看到這裡,想到前面! 這就是 Linux 的學習方法~ ^_^
OK!瞭解了帳號的新增、刪除、更動與查詢後,再來我們可以聊一聊群組的相關內容了。 基本上,群組的內容都與這兩個檔案有關:/etc/group, /etc/gshadow。 群組的內容其實很簡單,都是上面兩個檔案的新增、修改與移除而已, 不過,如果再加上有效群組的概念,那麼 newgrp 與 gpasswd 則不可不知呢!
[root@study ~]# groupadd [-g gid] [-r] 群組名稱 選項與參數: -g :後面接某個特定的 GID ,用來直接給予某個 GID ~ -r :建立系統群組啦!與 /etc/login.defs 內的 GID_MIN 有關。 範例一:新建一個群組,名稱為 group1 [root@study ~]# groupadd group1 [root@study ~]# grep group1 /etc/group /etc/gshadow /etc/group:group1:x:1503: /etc/gshadow:group1:!:: # 群組的 GID 也是會由 1000 以上最大 GID+1 來決定!
曾經有某些版本的教育訓練手冊談到,為了讓使用者的 UID/GID 成對,她們建議新建的與使用者私有群組無關的其他群組時,使用小於 1000 以下的 GID 為宜。 也就是說,如果要建立群組的話,最好能夠使用『 groupadd -r 群組名』的方式來建立啦! 不過,這見仁見智啦!看你自己的抉擇囉!
跟 usermod 類似的,這個指令僅是在進行 group 相關參數的修改而已。
[root@study ~]# groupmod [-g gid] [-n group_name] 群組名 選項與參數: -g :修改既有的 GID 數字; -n :修改既有的群組名稱 範例一:將剛剛上個指令建立的 group1 名稱改為 mygroup , GID 為 201 [root@study ~]# groupmod -g 201 -n mygroup group1 [root@study ~]# grep mygroup /etc/group /etc/gshadow /etc/group:mygroup:x:201: /etc/gshadow:mygroup:!::
不過,還是那句老話,不要隨意的更動 GID ,容易造成系統資源的錯亂喔!
呼呼! groupdel 自然就是在刪除群組的囉~用法很簡單:
[root@study ~]# groupdel [groupname] 範例一:將剛剛的 mygroup 刪除! [root@study ~]# groupdel mygroup 範例二:若要刪除 vbird1 這個群組的話? [root@study ~]# groupdel vbird1 groupdel: cannot remove the primary group of user 'vbird1'
為什麼 mygroup 可以刪除,但是 vbird1 就不能刪除呢?原因很簡單,『有某個帳號 (/etc/passwd) 的 initial group 使用該群組!』 如果查閱一下,你會發現在 /etc/passwd 內的 vbird1 第四欄的 GID 就是 /etc/group 內的 vbird1 那個群組的 GID ,所以囉,當然無法刪除~否則 vbird1 這個使用者登入系統後, 就會找不到 GID ,那可是會造成很大的困擾的!那麼如果硬要刪除 vbird1 這個群組呢? 你『必須要確認 /etc/passwd 內的帳號沒有任何人使用該群組作為 initial group 』才行喔!所以,你可以:
如果系統管理員太忙碌了,導致某些帳號想要加入某個專案時找不到人幫忙!這個時候可以建立『群組管理員』喔! 什麼是群組管理員呢?就是讓某個群組具有一個管理員,這個群組管理員可以管理哪些帳號可以加入/移出該群組! 那要如何『建立一個群組管理員』呢?就得要透過 gpasswd 囉!
# 關於系統管理員(root)做的動作: [root@study ~]# gpasswd groupname [root@study ~]# gpasswd [-A user1,...] [-M user3,...] groupname [root@study ~]# gpasswd [-rR] groupname 選項與參數: :若沒有任何參數時,表示給予 groupname 一個密碼(/etc/gshadow) -A :將 groupname 的主控權交由後面的使用者管理(該群組的管理員) -M :將某些帳號加入這個群組當中! -r :將 groupname 的密碼移除 -R :讓 groupname 的密碼欄失效 # 關於群組管理員(Group administrator)做的動作: [someone@study ~]$ gpasswd [-ad] user groupname 選項與參數: -a :將某位使用者加入到 groupname 這個群組當中! -d :將某位使用者移除出 groupname 這個群組當中。 範例一:建立一個新群組,名稱為 testgroup 且群組交由 vbird1 管理: [root@study ~]# groupadd testgroup <==先建立群組 [root@study ~]# gpasswd testgroup <==給這個群組一個密碼吧! Changing the password for group testgroup New Password: Re-enter new password: # 輸入兩次密碼就對了! [root@study ~]# gpasswd -A vbird1 testgroup <==加入群組管理員為 vbird1 [root@study ~]# grep testgroup /etc/group /etc/gshadow /etc/group:testgroup:x:1503: /etc/gshadow:testgroup:$6$MnmChP3D$mrUn.Vo.buDjObMm8F2emTkvGSeuWikhRzaKHxpJ...:vbird1: # 很有趣吧!此時 vbird1 則擁有 testgroup 的主控權喔!身份有點像板主啦! 範例二:以 vbird1 登入系統,並且讓他加入 vbird1, vbird3 成為 testgroup 成員 [vbird1@study ~]$ id uid=1003(vbird1) gid=1004(vbird1) groups=1004(vbird1) ... # 看得出來,vbird1 尚未加入 testgroup 群組喔! [vbird1@study ~]$ gpasswd -a vbird1 testgroup [vbird1@study ~]$ gpasswd -a vbird3 testgroup [vbird1@study ~]$ grep testgroup /etc/group testgroup:x:1503:vbird1,vbird3
很有趣的一個小實驗吧!我們可以讓 testgroup 成為一個可以公開的群組,然後建立起群組管理員, 群組管理員可以有多個。在這個案例中,我將 vbird1 設定為 testgroup 的群組管理員,所以 vbird1 就可以自行增加群組成員囉~呼呼!然後,該群組成員就能夠使用 newgrp 囉~
帳號管理不是隨意建置幾個帳號就算了!有時候我們需要考量到一部主機上面可能有多個帳號在協同工作! 舉例來說,在大學任教時,我們學校的專題生是需要分組的,這些同一組的同學間必須要能夠互相修改對方的資料檔案, 但是同時這些同學又需要保留自己的私密資料,因此直接公開家目錄是不適宜的。那該如何是好? 為此,我們底下提供幾個例子來讓大家思考看看囉:
任務一:單純的完成上頭交代的任務,假設我們需要的帳號資料如下,你該如何實作?
帳號名稱 | 帳號全名 | 支援次要群組 | 是否可登入主機 | 密碼 |
myuser1 | 1st user | mygroup1 | 可以 | password |
myuser2 | 2nd user | mygroup1 | 可以 | password |
myuser3 | 3rd user | 無額外支援 | 不可以 | password |
處理的方法如下所示:
# 先處理帳號相關屬性的資料: [root@study ~]# groupadd mygroup1 [root@study ~]# useradd -G mygroup1 -c "1st user" myuser1 [root@study ~]# useradd -G mygroup1 -c "2nd user" myuser2 [root@study ~]# useradd -c "3rd user" -s /sbin/nologin myuser3 # 再處理帳號的密碼相關屬性的資料: [root@study ~]# echo "password" | passwd --stdin myuser1 [root@study ~]# echo "password" | passwd --stdin myuser2 [root@study ~]# echo "password" | passwd --stdin myuser3
要注意的地方主要有:myuser1 與 myuser2 都有支援次要群組,但該群組不見得會存在,因此需要先手動建立他! 然後 myuser3 是『不可登入系統』的帳號,因此需要使用 /sbin/nologin 這個 shell 來給予,這樣該帳號就無法登入囉! 這樣是否理解啊!接下來再來討論比較難一些的環境!如果是專題環境該如何製作?
任務二:我的使用者 pro1, pro2, pro3 是同一個專案計畫的開發人員,我想要讓這三個用戶在同一個目錄底下工作, 但這三個用戶還是擁有自己的家目錄與基本的私有群組。假設我要讓這個專案計畫在 /srv/projecta 目錄下開發, 可以如何進行?
# 1. 假設這三個帳號都尚未建立,可先建立一個名為 projecta 的群組, # 再讓這三個用戶加入其次要群組的支援即可: [root@study ~]# groupadd projecta [root@study ~]# useradd -G projecta -c "projecta user" pro1 [root@study ~]# useradd -G projecta -c "projecta user" pro2 [root@study ~]# useradd -G projecta -c "projecta user" pro3 [root@study ~]# echo "password" | passwd --stdin pro1 [root@study ~]# echo "password" | passwd --stdin pro2 [root@study ~]# echo "password" | passwd --stdin pro3 # 2. 開始建立此專案的開發目錄: [root@study ~]# mkdir /srv/projecta [root@study ~]# chgrp projecta /srv/projecta [root@study ~]# chmod 2770 /srv/projecta [root@study ~]# ll -d /srv/projecta drwxrws---. 2 root projecta 6 Jul 20 23:32 /srv/projecta
由於此專案計畫只能夠給 pro1, pro2, pro3 三個人使用,所以 /srv/projecta 的權限設定一定要正確才行! 所以該目錄群組一定是 projecta ,但是權限怎麼會是 2770 呢還記得第六章談到的 SGID 吧?為了讓三個使用者能夠互相修改對方的檔案, 這個 SGID 是必須要存在的喔!如果連這裡都能夠理解,嘿嘿!您的帳號管理已經有一定程度的概念囉! ^_^
但接下來有個困擾的問題發生了!假如任務一的 myuser1 是 projecta 這個專案的助理,他需要這個專案的內容, 但是他『不可以修改』專案目錄內的任何資料!那該如何是好?你或許可以這樣做:
真要命!傳統的 Linux 權限無法針對某個個人設定專屬的權限嗎?其實是可以啦!接下來我們就來談談這個功能吧!
在談 ACL 之前,我們再來談一個概念性的操作~因為我們目前沒有伺服器可供練習....
有時候,除了本機的帳號之外,我們可能還會使用到其他外部的身份驗證伺服器所提供的驗證身份的功能!舉例來說, windows 底下有個很有名的身份驗證系統,稱為 Active Directory (AD)的東西,還有 Linux 為了提供不同主機使用同一組帳號密碼, 也會使用到 LDAP, NIS 等伺服器提供的身份驗證等等!
如果你的 Linux 主機要使用到上面提到的這些外部身份驗證系統時,可能就得要額外的設定一些資料了! 為了簡化使用者的操作流程,所以 CentOS 提供一隻名為 authconfig-tui 的指令給我們參考,這個指令的執行結果如下:
你可以在該畫面中使用 [tab] 按鈕在各個項目中間切換。因為我們尚未談到伺服器的章節,所以什麼 NIS 啦、LDAP 啦都還沒有提供! 反正,未來在"伺服器篇"談到外部身份驗證的設定時,你知道有個 authconfig-tui 就好了! 上圖中最多可供操作的,大概僅有支援 MD5 這個早期的密碼格式就是了!此外,不要隨便將已經啟用的項目 (上頭有星號 * 的項目) 取消喔! 可能某些帳號會失效...
從第五章開始,我們就一直強調 Linux 的權限概念是非常重要的! 但是傳統的權限僅有三種身份 (owner, group, others) 搭配三種權限 (r,w,x) 而已,並沒有辦法單純的針對某一個使用者或某一個群組來設定特定的權限需求,例如前一小節最後的那個任務! 此時就得要使用 ACL 這個機制啦!這玩意挺有趣的,底下我們就來談一談:
ACL 是 Access Control List 的縮寫,主要的目的是在提供傳統的 owner,group,others 的 read,write,execute 權限之外的細部權限設定。ACL 可以針對單一使用者,單一檔案或目錄來進行 r,w,x 的權限規範,對於需要特殊權限的使用狀況非常有幫助。
那 ACL 主要可以針對哪些方面來控制權限呢?他主要可以針對幾個項目:
也就是說,如果你有一個目錄,需要給一堆人使用,每個人或每個群組所需要的權限並不相同時,在過去,傳統的 Linux 三種身份的三種權限是無法達到的, 因為基本上,傳統的 Linux 權限只能針對一個用戶、一個群組及非此群組的其他人設定權限而已,無法針對單一用戶或個人來設計權限。 而 ACL 就是為了要改變這個問題啊!好了,稍微了解之後,再來看看如何讓你的檔案系統可以支援 ACL 吧!
事實上,原本 ACL 是 unix-like 作業系統的額外支援項目,但因為近年以來 Linux 系統對權限細部設定的熱切需求, 因此目前 ACL 幾乎已經預設加入在所有常見的 Linux 檔案系統的掛載參數中 (ext2/ext3/ext4/xfs等等)!所以你無須進行任何動作, ACL 就可以被你使用囉!不過,如果你不放心系統是否真的有支援 ACL 的話,那麼就來檢查一下核心掛載時顯示的資訊吧!
[root@study ~]# dmesg | grep -i acl [ 0.330377] systemd[1]: systemd 208 running in system mode. (+PAM +LIBWRAP +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ) [ 0.878265] SGI XFS with ACLs, security attributes, large block/inode numbers, no debug enabled
瞧!至少 xfs 已經支援這個 ACL 的功能囉!
好了,既然知道我們的 filesystem 有支援 ACL 之後,接下來該如何設定與觀察 ACL 呢? 很簡單,利用這兩個指令就可以了:
先讓我們來瞧一瞧 setfacl 如何使用吧!
[root@study ~]# 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@study ~]# touch acl_test1 [root@study ~]# ll acl_test1 -rw-r--r--. 1 root root 0 Jul 21 17:33 acl_test1 [root@study ~]# setfacl -m u:vbird1:rx acl_test1 [root@study ~]# ll acl_test1 -rw-r-xr--+ 1 root root 0 Jul 21 17:33 acl_test1 # 權限部分多了個 + ,且與原本的權限 (644) 看起來差異很大!但要如何查閱呢? [root@study ~]# setfacl -m u::rwx acl_test1 [root@study ~]# ll acl_test1 -rwxr-xr--+ 1 root root 0 Jul 21 17:33 acl_test1 # 設定值中的 u 後面無使用者列表,代表設定該檔案擁有者,所以上面顯示 root 的權限成為 rwx 了!
上述動作為最簡單的 ACL 設定,利用『 u:使用者:權限 』的方式來設定的啦!設定前請加上 -m 這個選項。 如果一個檔案設定了 ACL 參數後,他的權限部分就會多出一個 + 號了!但是此時你看到的權限與實際權限可能就會有點誤差! 那要如何觀察呢?就透過 getfacl 吧!
[root@study ~]# getfacl filename 選項與參數: getfacl 的選項幾乎與 setfacl 相同!所以鳥哥這裡就免去了選項的說明啊! # 請列出剛剛我們設定的 acl_test1 的權限內容: [root@study ~]# getfacl acl_test1 # file: acl_test1 <==說明檔名而已! # owner: root <==說明此檔案的擁有者,亦即 ls -l 看到的第三使用者欄位 # group: root <==此檔案的所屬群組,亦即 ls -l 看到的第四群組欄位 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@study ~]# setfacl -m g:mygroup1:rx acl_test1 [root@study ~]# 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@study ~]# setfacl -m m:r acl_test1 [root@study ~]# getfacl acl_test1 # file: acl_test1 # owner: root # group: root user::rwx user:vbird1:r-x #effective:r-- <==vbird1+mask均存在者,僅有 r 而已,x 不會生效 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 是獨立的使用者與群組,因此無法使用傳統的 Linux 權限設定。此時使用 ACL 的設定如下:
# 1. 先測試看看,使用 myuser1 能否進入該目錄? [myuser1@study ~]$ cd /srv/projecta -bash: cd: /srv/projecta: Permission denied <==確實不可進入! # 2. 開始用 root 的身份來設定一下該目錄的權限吧! [root@study ~]# setfacl -m u:myuser1:rx /srv/projecta [root@study ~]# getfacl /srv/projecta # file: srv/projecta # owner: root # group: projecta # flags: -s- user::rwx user:myuser1:r-x <==還是要看看有沒有設定成功喔! group::rwx mask::rwx other::--- # 3. 還是得要使用 myuser1 去測試看看結果! [myuser1@study ~]$ cd /srv/projecta [myuser1@study projecta]$ ll -a drwxrws---+ 2 root projecta 4096 Feb 27 11:29 . <==確實可以查詢檔名 drwxr-xr-x 4 root root 4096 Feb 27 11:29 .. [myuser1@study projecta]$ touch testing touch: cannot touch `testing': Permission denied <==確實不可以寫入!請注意,上述的 1, 3 步驟使用 myuser1 的身份,2步驟才是使用 root 去設定的! |
上面的設定我們就完成了之前任務二的後續需求喔!這麼簡單呢!接下來讓我們來測試一下,如果我用 root 或者是 pro1 的身份去 /srv/projecta 增加檔案或目錄時,該檔案或目錄是否能夠具有 ACL 的設定? 意思就是說,ACL 的權限設定是否能夠被次目錄所『繼承?』先試看看:
[root@study ~]# cd /srv/projecta [root@study ~]# touch abc1 [root@study ~]# mkdir abc2 [root@study ~]# ll -d abc* -rw-r--r--. 1 root projecta 0 Jul 21 17:49 abc1 drwxr-sr-x. 2 root projecta 6 Jul 21 17:49 abc2
你可以明顯的發現,權限後面都沒有 + ,代表這個 acl 屬性並沒有繼承喔!如果你想要讓 acl 在目錄底下的資料都有繼承的功能,那就得如下這樣做了!
# 4. 針對預設權限的設定方式: # 設定規範:『 d:[ug]:使用者列表:[rwx] 』 # 讓 myuser1 在 /srv/projecta 底下一直具有 rx 的預設權限! [root@study ~]# setfacl -m d:u:myuser1:rx /srv/projecta [root@study ~]# getfacl /srv/projecta # file: srv/projecta # owner: root # group: projecta # flags: -s- 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@study ~]# cd /srv/projecta [root@study projecta]# touch zzz1 [root@study projecta]# mkdir zzz2 [root@study projecta]# ll -d zzz* -rw-rw----+ 1 root projecta 0 Jul 21 17:50 zzz1 drwxrws---+ 2 root projecta 6 Jul 21 17:51 zzz2 # 看吧!確實有繼承喔!然後我們使用 getfacl 再次確認看看! [root@study projecta]# getfacl zzz2 # file: zzz2 # owner: root # group: projecta # flags: -s- 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 檔名 』即可啦! 太簡單了!鳥哥就不另外介紹了!請自行測試測試吧!
問:
針對剛剛的 /srv/projecta 目錄的權限設定中,我需要 1)取消 myuser1 的設定(連同預設值),以及 2)我不能讓 pro3 這個用戶使用該目錄,亦即 pro3 在該目錄下無任何權限,
該如何設定?
答:
取消全部的 ACL 設定可以使用 -b 來處理,但單一設定值的取消,就得要透過 -x 才行了!所以你應該這樣作:
# 1.1 找到針對 myuser1 的設定值 [root@study ~]# getfacl /srv/projecta | grep myuser1 user:myuser1:r-x default:user:myuser1:r-x # 1.2 針對每個設定值來處理,注意,取消某個帳號的 ACL 時,不需要加上權限項目! [root@study ~]# setfacl -x u:myuser1 /srv/projecta [root@study ~]# setfacl -x d:u:myuser1 /srv/projecta # 2.1 開始讓 pro3 這個用戶無法使用該目錄囉! [root@study ~]# setfacl -m u:pro3:- /srv/projecta只需要留意,當設定一個用戶/群組沒有任何權限的 ACL 語法中,在權限的欄位不可留白,而是應該加上一個減號 (-) 才是正確的作法! |
什麼?在 Linux 系統當中還要作身份的變換?這是為啥?可能有底下幾個原因啦!
事實上,為了安全的緣故,一些老人家都會建議你,盡量以一般身份使用者來操作 Linux 的日常作業!等到需要設定系統環境時, 才變換身份成為 root 來進行系統管理,相對比較安全啦!避免作錯一些嚴重的指令,例如恐怖的『 rm -rf / 』(千萬作不得!)
相對於系統安全,有的時候,我們必須要以某些系統帳號來進行程序的執行。 舉例來說, Linux 主機上面的一套軟體,名稱為 apache ,我們可以額外建立一個名為 apache 的使用者來啟動 apache 軟體啊,如此一來,如果這個程序被攻破,至少系統還不至於就損毀了~
在遠古時代的 telnet 程式中,該程式預設是不許使用 root 的身份登入的,telnet 會判斷登入者的 UID, 若 UID 為 0 的話,那就直接拒絕登入了。所以,你只能使用一般使用者來登入 Linux 伺服器。 此外, ssh (註3) 也可以設定拒絕 root 登入喔!那如果你有系統設定需求該如何是好啊?就變換身份啊!
由於上述考量,所以我們都是使用一般帳號登入系統的,等有需要進行系統維護或軟體更新時才轉為 root 的身份來動作。 那如何讓一般使用者轉變身份成為 root 呢?主要有兩種方式喔:
底下我們就來說一說 su 跟 sudo 的用法啦!
su 是最簡單的身份切換指令了,他可以進行任何身份的切換唷!方法如下:
[root@study ~]# su [-lm] [-c 指令] [username] 選項與參數: - :單純使用 - 如『 su - 』代表使用 login-shell 的變數檔案讀取方式來登入系統; 若使用者名稱沒有加上去,則代表切換為 root 的身份。 -l :與 - 類似,但後面需要加欲切換的使用者帳號!也是 login-shell 的方式。 -m :-m 與 -p 是一樣的,表示『使用目前的環境設定,而不讀取新使用者的設定檔』 -c :僅進行一次指令,所以 -c 後面可以加上指令喔!
上表的解釋當中有出現之前第十章談過的 login-shell 設定檔讀取方式,如果你忘記那是啥東西, 請先回去第十章瞧瞧再回來吧!這個 su 的用法當中,有沒有加上那個減號『 - 』差很多喔! 因為涉及 login-shell 與 non-login shell 的變數讀取方法。這裡讓我們以一個小例子來說明吧!
範例一:假設你原本是 dmtsai 的身份,想要使用 non-login shell 的方式變成 root [dmtsai@study ~]$ su <==注意提示字元,是 dmtsai 的身份喔! Password: <==這裡輸入 root 的密碼喔! [root@study dmtsai]# id <==提示字元的目錄是 dmtsai 喔! uid=0(root) gid=0(root) groups=0(root) context=unconf.... <==確實是 root 的身份! [root@study dmtsai]# env | grep 'dmtsai' USER=dmtsai <==竟然還是 dmtsai 這傢伙! PATH=...:/home/dmtsai/.local/bin:/home/dmtsai/bin <==這個影響最大! MAIL=/var/spool/mail/dmtsai <==收到的 mailbox 是 vbird1 PWD=/home/dmtsai <==並非 root 的家目錄 LOGNAME=dmtsai # 雖然你的 UID 已經是具有 root 的身份,但是看到上面的輸出訊息嗎? # 還是有一堆變數為原本 dmtsai 的身份,所以很多資料還是無法直接利用。 [root@study dmtsai]# exit <==這樣可以離開 su 的環境!
單純使用『 su 』切換成為 root 的身份,讀取的變數設定方式為 non-login shell 的方式,這種方式很多原本的變數不會被改變, 尤其是我們之前談過很多次的 PATH 這個變數,由於沒有改變成為 root 的環境, 因此很多 root 慣用的指令就只能使用絕對路徑來執行咯。其他的還有 MAIL 這個變數,你輸入 mail 時, 收到的郵件竟然還是 dmtsai 的,而不是 root 本身的郵件!是否覺得很奇怪啊!所以切換身份時,請務必使用如下的範例二:
範例二:使用 login shell 的方式切換為 root 的身份並觀察變數 [dmtsai@study ~]$ su - Password: <==這裡輸入 root 的密碼喔! [root@study ~]# 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@study ~]# exit <==這樣可以離開 su 的環境!
上述的作法是讓使用者的身份變成 root 並開始操作系統,如果想要離開 root 的身份則得要利用 exit 離開才行。 那我如果只是想要執行『一個只有 root 才能進行的指令,且執行完畢就恢復原本的身份』呢?那就可以加上 -c 這個選項囉! 請參考底下範例三!
範例三:dmtsai 想要執行『 head -n 3 /etc/shadow 』一次,且已知 root 密碼 [dmtsai@study ~]$ head -n 3 /etc/shadow head: cannot open `/etc/shadow' for reading: Permission denied [dmtsai@study ~]$ su - -c "head -n 3 /etc/shadow" Password: <==這裡輸入 root 的密碼喔! root:$6$wtbCCce/PxMeE5wm$KE2IfSJr.YLP7Rcai6oa/T7KFhOYO62vDnqfLw85...:16559:0:99999:7::: bin:*:16372:0:99999:7::: daemon:*:16372:0:99999:7::: [dmtsai@study ~]$ <==注意看,身份還是 dmtsai 喔!繼續使用舊的身份進行系統操作!
由於 /etc/shadow 權限的關係,該檔案僅有 root 可以查閱。為了查閱該檔案,所以我們必須要使用 root 的身份工作。 但我只想要進行一次該指令而已,此時就使用類似上面的語法吧!好,那接下來,如果我是 root 或者是其他人, 想要變更成為某些特殊帳號,可以使用如下的方法來切換喔!
範例四:原本是 dmtsai 這個使用者,想要變換身份成為 vbird1 時? [dmtsai@study ~]$ su -l vbird1 Password: <==這裡輸入 vbird1 的密碼喔! [vbird1@study ~]$ su - Password: <==這裡輸入 root 的密碼喔! [root@study ~]# id sshd uid=74(sshd) gid=74(sshd) groups=74(sshd) ... <==確實有存在此人 [root@study ~]# su -l sshd This account is currently not available. <==竟然說此人無法切換? [root@study ~]# finger sshd Login: sshd Name: Privilege-separated SSH Directory: /var/empty/sshd Shell: /sbin/nologin [root@study ~]# exit <==離開第二次的 su [vbird1@study ~]$ exit <==離開第一次的 su [dmtsai@study ~]$ 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@study ~]# sudo [-b] [-u 新使用者帳號] 選項與參數: -b :將後續的指令放到背景中讓系統自行執行,而不與目前的 shell 產生影響 -u :後面可以接欲切換的使用者,若無此項則代表切換身份為 root 。 範例一:你想要以 sshd 的身份在 /tmp 底下建立一個名為 mysshd 的檔案 [root@study ~]# sudo -u sshd touch /tmp/mysshd [root@study ~]# ll /tmp/mysshd -rw-r--r--. 1 sshd sshd 0 Jul 21 23:37 /tmp/mysshd # 特別留意,這個檔案的權限是由 sshd 所建立的情況喔! 範例二:你想要以 vbird1 的身份建立 ~vbird1/www 並於其中建立 index.html 檔案 [root@study ~]# sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \ > echo 'This is index.html file' > index.html" [root@study ~]# ll -a ~vbird1/www drwxr-xr-x. 2 vbird1 vbird1 23 Jul 21 23:38 . drwx------. 6 vbird1 vbird1 4096 Jul 21 23:38 .. -rw-r--r--. 1 vbird1 vbird1 24 Jul 21 23:38 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 的設定方式有幾種簡單的方法喔,底下我們以幾個簡單的例子來分別說明:
假如我們要讓 vbird1 這個帳號可以使用 root 的任何指令,基本上有兩種作法,第一種是直接透過修改 /etc/sudoers ,方法如下:
[root@study ~]# visudo ....(前面省略).... root ALL=(ALL) ALL <==找到這一行,大約在 98 行左右 vbird1 ALL=(ALL) ALL <==這一行是你要新增的! ....(底下省略)....
有趣吧!其實 visudo 只是利用 vi 將 /etc/sudoers 檔案呼叫出來進行修改而已,所以這個檔案就是 /etc/sudoers 啦! 這個檔案的設定其實很簡單,如上面所示,如果你找到 98 行 (有 root 設定的那行) 左右,看到的資料就是:
使用者帳號 可下達指令的主機名稱=(可切換的身份) 可下達的指令
root ALL=(ALL) ALL <==這是預設值
上面這一行的四個元件意義是:
那個 ALL 是特殊的關鍵字,代表任何身份、主機或指令的意思。所以,我想讓 vbird1 可以進行任何身份的任何指令, 就如同上表特殊字體寫的那樣,其實就是複製上述預設值那一行,再將 root 改成 vbird1 即可啊! 此時『vbird1 不論來自哪部主機登入,他可以變換身份成為任何人,且可以進行系統上面的任何指令』之意。 修改完請儲存後離開 vi,並以 vbird1 登入系統後,進行如下的測試看看:
[vbird1@study ~]$ tail -n 1 /etc/shadow <==注意!身份是 vbird1 tail: cannot open `/etc/shadow' for reading: Permission denied # 因為不是 root 嘛!所以當然不能查詢 /etc/shadow [vbird1@study ~]$ 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. [sudo] password for vbird1: <==注意啊!這裡輸入的是『 vbird1 自己的密碼 』 pro3:$6$DMilzaKr$OeHeTDQPHzDOz/u5Cyhq1Q1dy...:16636:0:99999:7::: # 看!vbird1 竟然可以查詢 shadow !
注意到了吧!vbird1 輸入自己的密碼就能夠執行 root 的指令!所以,系統管理員當然要瞭解 vbird1 這個用戶的『操守』才行!否則隨便設定一個使用者,他惡搞系統怎辦?另外,一個一個設定太麻煩了, 能不能使用群組的方式來設定呢?參考底下的第二種方式吧。
我們在本章前面曾經建立過 pro1, pro2, pro3 ,這三個用戶能否透過群組的功能讓這三個人可以管理系統? 可以的,而且很簡單!同樣我們使用實際案例來說明:
[root@study ~]# visudo <==同樣的,請使用 root 先設定 ....(前面省略).... %wheel ALL=(ALL) ALL <==大約在 106 行左右,請將這行的 # 拿掉! # 在最左邊加上 % ,代表後面接的是一個『群組』之意!改完請儲存後離開 [root@study ~]# usermod -a -G wheel pro1 <==將 pro1 加入 wheel 的支援
上面的設定值會造成『任何加入 wheel 這個群組的使用者,就能夠使用 sudo 切換任何身份來操作任何指令』的意思。 你當然可以將 wheel 換成你自己想要的群組名。接下來,請分別切換身份成為 pro1 及 pro2 試看看 sudo 的運作。
[pro1@study ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro1 ....(前面省略).... [sudo] password for pro1: <==輸入 pro1 的密碼喔! pro3:$6$DMilzaKr$OeHeTDQPHzDOz/u5Cyhq1Q1dy...:16636:0:99999:7::: [pro2@study ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro2 [sudo] password for pro2: <==輸入 pro2 的密碼喔! pro2 is not in the sudoers file. This incident will be reported. # 仔細看錯誤訊息他是說這個 pro2 不在 /etc/sudoers 的設定中!
這樣理解群組了吧?如果你想要讓 pro3 也支援這個 sudo 的話,不需要重新使用 visudo ,只要利用 usermod 去修改 pro3 的群組支援,讓 pro3 用戶加入 wheel 群組當中,那他就能夠進行 sudo 囉! 好了!那麼現在你知道為啥在安裝時建立的用戶,就是那個 dmstai 預設可以使用 sudo 了嗎?請使用『 id dmtsai 』看看, 這個用戶是否有加入 wheel 群組呢?嘿嘿!瞭解乎?
簡單吧!不過,既然我們都信任這些 sudo 的用戶了,能否提供『不需要密碼即可使用 sudo 』呢? 就透過如下的方式:
[root@study ~]# visudo <==同樣的,請使用 root 先設定 ....(前面省略).... %wheel ALL=(ALL) NOPASSWD: ALL <==大約在 109 行左右,請將 # 拿掉! # 在最左邊加上 % ,代表後面接的是一個『群組』之意!改完請儲存後離開
重點是那個 NOPASSWD 啦!該關鍵字是免除密碼輸入的意思喔!
上面兩點都會讓使用者能夠利用 root 的身份進行任何事情!這樣總是不太好~如果我想要讓使用者僅能夠進行部分系統任務, 比方說,系統上面的 myuser1 僅能夠幫 root 修改其他使用者的密碼時,亦即『當使用者僅能使用 passwd 這個指令幫忙 root 修改其他用戶的密碼』時,你該如何撰寫呢?可以這樣做:
[root@study ~]# visudo <==注意是 root 身份 myuser1 ALL=(root) /usr/bin/passwd <==最後指令務必用絕對路徑
上面的設定值指的是『myuser1 可以切換成為 root 使用 passwd 這個指令』的意思。其中要注意的是: 指令欄位必須要填寫絕對路徑才行!否則 visudo 會出現語法錯誤的狀況發生! 此外,上面的設定是有問題的!我們使用底下的指令操作來讓您瞭解:
[myuser1@study ~]$ sudo passwd myuser3 <==注意,身份是 myuser1 [sudo] password for myuser1: <==輸入 myuser1 的密碼 Changing password for user myuser3. <==底下改的是 myuser3 的密碼喔!這樣是正確的 New password: Retype new password: passwd: all authentication tokens updated successfully. [myuser1@study ~]$ sudo passwd Changing password for user root. <==見鬼!怎麼會去改 root 的密碼?
恐怖啊!我們竟然讓 root 的密碼被 myuser1 給改變了!下次 root 回來竟無法登入系統...欲哭無淚~怎辦? 所以我們必須要限制使用者的指令參數!修改的方法為將上述的那行改一改先:
[root@study ~]# 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 的密碼!很有用處的!
如上述第三點,如果我有 15 個用戶需要加入剛剛的管理員行列,那麼我是否要將上述那長長的設定寫入 15 行啊? 而且如果想要修改命令或者是新增命令時,那我每行都需要重新設定,很麻煩ㄟ!有沒有更簡單的方式? 是有的!透過別名即可!我們 visudo 的別名可以是『指令別名、帳號別名、主機別名』等。不過這裡我們僅介紹帳號別名, 其他的設定值有興趣的話,可以自行玩玩!
假設我的 pro1, pro2, pro3 與 myuser1, myuser2 要加入上述的密碼管理員的 sudo 列表中, 那我可以創立一個帳號別名稱為 ADMPW 的名稱,然後將這個名稱處理一下即可。處理的方式如下:
[root@study ~]# 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 這兩行即可!設定方面會比較簡單有彈性喔!
或許您已經發現了,那就是,如果我使用同一個帳號在短時間內重複操作 sudo 來運作指令的話, 在第二次執行 sudo 時,並不需要輸入自己的密碼!sudo 還是會正確的運作喔!為什麼呢? 第一次執行 sudo 需要輸入密碼,是擔心由於使用者暫時離開座位,但有人跑來你的座位使用你的帳號操作系統之故。 所以需要你輸入一次密碼重新確認一次身份。
兩次執行 sudo 的間隔在五分鐘內,那麼再次執行 sudo 時就不需要再次輸入密碼了, 這是因為系統相信你在五分鐘內不會離開你的作業,所以執行 sudo 的是同一個人!呼呼!真是很人性化的設計啊~ ^_^。不過如果兩次 sudo 操作的間隔超過 5 分鐘,那就得要重新輸入一次你的密碼了 (註4)
很多時候我們需要大量執行很多 root 的工作,所以一直使用 sudo 覺得很煩ㄟ!那有沒有辦法使用 sudo 搭配 su , 一口氣將身份轉為 root ,而且還用使用者自己的密碼來變成 root 呢?是有的!而且方法簡單的會讓你想笑! 我們建立一個 ADMINS 帳號別名,然後這樣做:
[root@study ~]# visudo User_Alias ADMINS = pro1, pro2, pro3, myuser1 ADMINS ALL=(root) /bin/su -
接下來,上述的 pro1, pro2, pro3, myuser1 這四個人,只要輸入『 sudo su - 』並且輸入『自己的密碼』後, 立刻變成 root 的身份!不但 root 密碼不會外流,使用者的管理也變的非常方便! 這也是實務上面多人共管一部主機時常常使用的技巧呢!這樣管理確實方便,不過還是要強調一下大前提, 那就是『這些你加入的使用者,全部都是你能夠信任的用戶』!
我們前面一直談到的大多是一般身份使用者與系統管理員 (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 這個帳號在管理, 他們都可以進行系統程序的工作,但是『就是無法登入主機取得互動的 shell』而已啦!^_^
換個角度來想,如果我的 Linux 主機提供的是郵件服務,所以說,在這部 Linux 主機上面的帳號, 其實大部分都是用來收受主機的信件而已,並不需要登入主機的呢! 這個時候,我們就可以考慮讓單純使用 mail 的帳號以 /sbin/nologin 做為他們的 shell , 這樣,最起碼當我的主機被嘗試想要登入系統以取得 shell 環境時,可以拒絕該帳號呢!
另外,如果我想要讓某個具有 /sbin/nologin 的使用者知道,他們不能登入主機時, 其實我可以建立『 /etc/nologin.txt 』這個檔案, 並且在這個檔案內說明不能登入的原因,那麼下次當這個使用者想要登入系統時, 螢幕上出現的就會是 /etc/nologin.txt 這個檔案的內容,而不是預設的內容了!
例題:
當使用者嘗試利用純 mail 帳號 (例如 myuser3) 時,利用 /etc/nologin.txt
告知使用者不要利用該帳號登入系統。
答:
直接以 vim 編輯該檔案,內容可以是這樣:
[root@study ~]# vim /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) 來測試看看!
[root@study ~]# su - myuser3
This account is system account or mail account.
Please DO NOT use this account to login my Linux server.
結果會發現與原本的預設訊息不一樣喔! ^_^
|
在過去,我們想要對一個使用者進行認證 (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 藉由一個與程式相同檔名的設定檔來進行一連串的認證分析需求。我們同樣以 passwd 這個指令的呼叫 PAM 來說明好了。 當你執行 passwd 後,這支程式呼叫 PAM 的流程是:
從上頭的說明,我們會知道重點其實是 /etc/pam.d/ 裡面的設定檔,以及設定檔所呼叫的 PAM 模組進行的驗證工作! 既然一直談到 passwd 這個密碼修改指令,那我們就來看看 /etc/pam.d/passwd 這個設定檔的內容是怎樣吧!
[root@study ~]# cat /etc/pam.d/passwd #%PAM-1.0 <==PAM版本的說明而已! auth include system-auth <==每一行都是一個驗證的過程 account include system-auth password substack system-auth -password optional pam_gnome_keyring.so use_authtok password substack postlogin 驗證類別 控制標準 PAM 模組與該模組的參數
在這個設定檔當中,除了第一行宣告 PAM 版本之外,其他任何『 # 』開頭的都是註解,而每一行都是一個獨立的驗證流程, 每一行可以區分為三個欄位,分別是驗證類別(type)、控制標準(flag)、PAM的模組與該模組的參數。 底下我們先來談談驗證類別與控制標準這兩項資料吧!
驗證類別主要分為四種,分別說明如下:
這四個驗證的類型通常是有順序的,不過也有例外就是了。 會有順序的原因是,(1)我們總是得要先驗證身份 (auth) 後, (2)系統才能夠藉由使用者的身份給予適當的授權與權限設定 (account),而且(3)登入與登出期間的環境才需要設定, 也才需要記錄登入與登出的資訊 (session)。如果在運作期間需要密碼修訂時,(4)才給予 password 的類別。這樣說起來, 自然是需要有點順序吧!
那麼『驗證的控制旗標(control flag)』又是什麼?簡單的說,他就是『驗證通過的標準』啦! 這個欄位在管控該驗證的放行方式,主要也分為四種控制方式:
如果將這些控制旗標以圖示的方式配合成功與否的條件繪圖,會有點像底下這樣:
程式運作過程中遇到驗證時才會去呼叫 PAM ,而 PAM 驗證又分很多類型與控制,不同的控制旗標所回報的訊息並不相同。 如上圖所示, requisite 失敗就回報了並不會繼續,而 sufficient 則是成功就回報了也不會繼續。 至於驗證結束後所回報的資訊通常是『succes 或 failure 』而已,後續的流程還需要該程式的判斷來繼續執行才行。
談完了設定檔的語法後,現在讓我們來查閱一下 CentOS 7.x 提供的 PAM 預設檔案的內容是啥吧! 由於我們常常需要透過各種方式登入 (login) 系統,因此就來看看登入所需要的 PAM 流程為何:
[root@study ~]# cat /etc/pam.d/login #%PAM-1.0 auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so auth substack system-auth auth include postlogin 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 required pam_loginuid.so session optional pam_console.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open session required pam_namespace.so session optional pam_keyinit.so force revoke session include system-auth session include postlogin -session optional pam_ck_connector.so # 我們可以看到,其實 login 也呼叫多次的 system-auth ,所以底下列出該設定檔 [root@study ~]# 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_fprintd.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid >= 1000 quiet_success auth required pam_deny.so account required pam_unix.so account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 1000 quiet account required pam_permit.so password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so -session optional pam_systemd.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so
上面這個表格當中使用到非常多的 PAM 模組,每個模組的功能都不太相同,詳細的模組情報可以在你的系統中找到:
例如鳥哥使用未 update 過的 CentOS 7.1 ,pam_nologin 說明文件檔在: /usr/share/doc/pam-1.1.8/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-(版本) ,模組實際在 /lib64/security/ 。那麼還有沒有相關的 PAM 檔案呢? 是有的,主要都在 /etc/security 這個目錄內!我們底下介紹幾個可能會用到的設定檔喔!
我們在第十章談到的 ulimit 功能中, 除了修改使用者的 ~/.bashrc 設定檔之外,其實系統管理員可以統一藉由 PAM 來管理的! 那就是 /etc/security/limits.conf 這個檔案的設定了。這個檔案的設定很簡單,你可以自行參考一下該檔案內容。 我們這裡僅作個簡單的介紹:
範例一:vbird1 這個用戶只能建立 100MB 的檔案,且大於 90MB 會警告 [root@study ~]# vim /etc/security/limits.conf vbird1 soft fsize 90000 vbird1 hard fsize 100000 #帳號 限制依據 限制項目 限制值 # 第一欄位為帳號,或者是群組!若為群組則前面需要加上 @ ,例如 @projecta # 第二欄位為限制的依據,是嚴格(hard),還是僅為警告(soft); # 第三欄位為相關限制,此例中限制檔案容量, # 第四欄位為限制的值,在此例中單位為 KB。 # 若以 vbird1 登入後,進行如下的操作則會有相關的限制出現! [vbird1@study ~]$ ulimit -a ....(前面省略).... file size (blocks, -f) 90000 ....(後面省略).... [vbird1@study ~]$ dd if=/dev/zero of=test bs=1M count=110 File size limit exceeded [vbird1@study ~]$ ll --block-size=K test -rw-rw-r--. 1 vbird1 vbird1 90000K Jul 22 01:33 test # 果然有限制到了 範例二:限制 pro1 這個群組,每次僅能有一個使用者登入系統 (maxlogins) [root@study ~]# vim /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 提過了, 您可以自行前往參考啊!簡單的很。
那如果你想要知道目前已登入在系統上面的使用者呢?可以透過 w 或 who 來查詢喔!如下範例所示:
[root@study ~]# w 01:49:18 up 25 days, 3:34, 3 users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT dmtsai tty2 07Jul15 12days 0.03s 0.03s -bash dmtsai pts/0 172.16.200.254 00:18 6.00s 0.31s 0.11s sshd: dmtsai [priv] # 第一行顯示目前的時間、開機 (up) 多久,幾個使用者在系統上平均負載等; # 第二行只是各個項目的說明, # 第三行以後,每行代表一個使用者。如上所示,dmtsai 登入並取得終端機名 tty2 之意。 [root@study ~]# who dmtsai tty2 2015-07-07 23:07 dmtsai pts/0 2015-07-22 00:18 (192.168.1.100)
另外,如果您想要知道每個帳號的最近登入的時間,則可以使用 lastlog 這個指令喔! lastlog 會去讀取 /var/log/lastlog 檔案,結果將資料輸出如下表:
[root@study ~]# lastlog Username Port From Latest root pts/0 Wed Jul 22 00:26:08 +0800 2015 bin **Never logged in** ....(中間省略).... dmtsai pts/1 192.168.1.100 Wed Jul 22 01:08:07 +0800 2015 vbird1 pts/0 Wed Jul 22 01:32:17 +0800 2015 pro3 **Never logged in** ....(以下省略)....
這樣就能夠知道每個帳號的最近登入的時間囉~ ^_^
那麼我是否可以跟系統上面的使用者談天說地呢?當然可以啦!利用 write 這個指令即可。 write 可以直接將訊息傳給接收者囉!舉例來說,我們的 Linux 目前有 vbird1 與 root 兩個人在線上, 我的 root 要跟 vbird1 講話,可以這樣做:
[root@study ~]# write 使用者帳號 [使用者所在終端介面] [root@study ~]# who vbird1 tty3 2015-07-22 01:55 <==有看到 vbird1 在線上 root tty4 2015-07-22 01:56 [root@study ~]# write vbird1 pts/2 Hello, there: Please don't do anything wrong... <==這兩行是 root 寫的資訊! # 結束時,請按下 [ctrl]-d 來結束輸入。此時在 vbird1 的畫面中,會出現: Message from root@study.centos.vbird on tty4 at 01:57 ... Hello, there: Please don't do anything wrong... EOF
怪怪~立刻會有訊息回應給 vbird1 !不過......當時 vbird1 正在查資料,哇! 這些訊息會立刻打斷 vbird1 原本的工作喔!所以,如果 vbird1 這個人不想要接受任何訊息,直接下達這個動作:
[vbird1@study ~]$ mesg n [vbird1@study ~]$ mesg is n
不過,這個 mesg 的功能對 root 傳送來的訊息沒有抵擋的能力!所以如果是 root 傳送訊息, vbird1 還是得要收下。 但是如果 root 的 mesg 是 n 的,那麼 vbird1 寫給 root 的資訊會變這樣:
[vbird1@study ~]$ write root
write: root has messages disabled
瞭解乎?如果想要解開的話,再次下達『 mesg y 』就好啦!想要知道目前的 mesg 狀態,直接下達『 mesg 』即可!瞭呼? 相對於 write 是僅針對一個使用者來傳『簡訊』,我們還可以『對所有系統上面的使用者傳送簡訊 (廣播)』哩~ 如何下達?用 wall 即可啊!他的語法也是很簡單的喔!
[root@study ~]# 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 -s "郵件標題" username@localhost 』即可! 一般來說,如果是寄給本機上的使用者,基本上,連『 @localhost 』都不用寫啦! 舉例來說,我以 root 寄信給 vbird1 ,信件標題是『 nice to meet you 』,則:
[root@study ~]# mail -s "nice to meet you" vbird1 Hello, D.M. Tsai Nice to meet you in the network. You are so nice. byebye! . <==這裡很重要喔,結束時,最後一行輸入小數點 . 即可! EOT [root@study ~]# <==出現提示字元,表示輸入完畢了!
如此一來,你就已經寄出一封信給 vbird1 這位使用者囉,而且,該信件標題為: nice to meet you,信件內容就如同上面提到的。不過,你或許會覺得 mail 這個程式不好用~ 因為在信件編寫的過程中,如果寫錯字而按下 Enter 進入次行,前一行的資料很難刪除ㄟ! 那怎麼辦?沒關係啦!我們使用資料流重導向啊!呵呵!利用那個小於的符號 ( < ) 就可以達到取代鍵盤輸入的要求了。也就是說,你可以先用 vi 將信件內容編好, 然後再以 mail -s "nice to meet you" vbird1 < filename 來將檔案內容傳輸即可。
例題:
請將你的家目錄下的環境變數檔 (~/.bashrc) 寄給自己!
答:
mail -s "bashrc file content" dmtsai < ~/.bashrc
例題:
透過管線命令直接將 ls -al ~ 的內容傳給 root 自己!
答:
ls -al ~ | mail -s "myfile" root
|
剛剛上面提到的是關於『寄信』的問題,那麼如果是要收信呢?呵呵!同樣的使用 mail 啊! 假設我以 vbird1 的身份登入主機,然後輸入 mail 後,會得到什麼?
[vbird1@study ~]$ mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/vbird1": 1 message 1 new >N 1 root Wed Jul 22 02:09 20/671 "nice to meet you" & <==這裡可以輸入很多的指令,如果要查閱,輸入 ? 即可!
在 mail 當中的提示字元是 & 符號喔,別搞錯了~輸入 mail 之後,我可以看到我有一封信件, 這封信件的前面那個 > 代表目前處理的信件,而在大於符號的右邊那個 N 代表該封信件尚未讀過, 如果我想要知道這個 mail 內部的指令有哪些,可以在 & 之後輸入『 ? 』,就可以看到如下的畫面:
& ?
mail commands
type <message list> type messages
next goto and type next message
from <message list> give head lines of messages
headers print out active message headers
delete <message list> delete messages
undelete <message list> undelete messages
save <message list> folder append messages to folder and mark as saved
copy <message list> folder append messages to folder without marking them
write <message list> file append message texts to file, save attachments
preserve <message list> keep incoming messages in mailbox even if saved
Reply <message list> reply to message senders
reply <message list> reply to message senders and all recipients
mail addresses mail to specific recipients
file folder change to another folder
quit quit and apply changes to folder
xit quit and discard changes made to folder
! shell escape
cd <directory> chdir to directory or home if none given
list list names of all available commands
<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 則會實際進行你剛剛所執行的任何動作 (尤其是刪除!) |
舊版的 CentOS 在使用 mail 讀信後,透過 q 離開始,會將已讀信件移動到 ~/mbox 中,不過目前 CentOS 7 已經不這麼做了! 所以離開 mail 可以輕鬆愉快的使用 q 了呢!
系統上面如果有一堆帳號存在,你怎麼判斷某些帳號是否存在一些問題?這時需要哪些軟體的協助處理比較好? 另外,如果你跟鳥哥一樣,在開學之初或期末之後,經常有需要大量建立帳號、刪除帳號的需求時,那麼是否要使用 useradd 一行一行指令去建立? 此外,如果還有需要使用到下一章會介紹到的 quota (磁碟配額) 時,那是否還要額外使用其他機制來建立這些限制值?既然已經學過 shell script 了, 當然寫支腳本讓它將所有的動作做完最輕鬆吧!所以囉,底下我們就來聊一聊,如何檢查帳號以及建立這個腳本要怎麼進行比較好?
先來檢查看看使用者的家目錄、密碼等資料有沒有問題?這時會使用到的主要有 pwck 以及 pwconv / pwuconv 等,讓我們來瞭解一下先!
pwck 這個指令在檢查 /etc/passwd 這個帳號設定檔內的資訊,與實際的家目錄是否存在等資訊, 還可以比對 /etc/passwd /etc/shadow 的資訊是否一致,另外,如果 /etc/passwd 內的資料欄位錯誤時,會提示使用者修訂。 一般來說,我只是利用這個玩意兒來檢查我的輸入是否正確就是了。
[root@study ~]# pwck
user 'ftp': directory '/var/ftp' does not exist
user 'avahi-autoipd': directory '/var/lib/avahi-autoipd' does not exist
user 'pulse': directory '/var/run/pulse' does not exist
pwck: no changes
瞧!上面僅是告知我,這些帳號並沒有家目錄,由於那些帳號絕大部分都是系統帳號,確實也不需要家目錄的,所以,那是『正常的錯誤!』呵呵!不理他。 ^_^。 相對應的群組檢查可以使用 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 』。 舉例來說,我的系統當中有個使用者帳號為 vbird3 ,我想要更新他的密碼 (update) , 假如他的密碼是 abcdefg 的話,那麼我可以這樣做:
[root@study ~]# echo "vbird3:abcdefg" | chpasswd
神奇吧!這樣就可以更新了呢!在預設的情況中, chpasswd 會去讀取 /etc/login.defs 檔案內的加密機制,我們 CentOS 7.x 用的是 SHA512, 因此 chpasswd 就預設會使用 SHA512 來加密!如果你想要使用不同的加密機制,那就得要使用 -c 以及 -e 等方式來處理了! 不過從 CentOS 5.x 開始之後,passwd 已經預設加入了 --stdin 的選項,因此這個 chpasswd 就變得英雄無用武之地了! 不過,在其他非 Red Hat 衍生的 Linux 版本中,或許還是可以參考這個指令功能來大量建置帳號喔!
由於 CentOS 7.x 的 passwd 已經提供了 --stdin 的功能,因此如果我們可以提供帳號密碼的話, 那麼就能夠很簡單的建置起我們的帳號密碼了。底下鳥哥製作一個簡單的 script 來執行新增用戶的功能喔!
[root@study ~]# vim accountadd.sh #!/bin/bash # This shell script will create amount of linux login accounts for you. # 1. check the "accountadd.txt" file exist? you must create that file manually. # one account name one line in the "accountadd.txt" file. # 2. use openssl to create users password. # 3. User must change his password in his first login. # 4. more options check the following url: # http://linux.vbird.org/linux_basic/0410accountmanager.php#manual_amount # 2015/07/22 VBird export PATH=/bin:/sbin:/usr/bin:/usr/sbin # 0. userinput usergroup="" # if your account need secondary group, add here. pwmech="openssl" # "openssl" or "account" is needed. homeperm="no" # if "yes" then I will modify home dir permission to 711 # 1. check the accountadd.txt file action="${1}" # "create" is useradd and "delete" is userdel. if [ ! -f accountadd.txt ]; then echo "There is no accountadd.txt file, stop here." exit 1 fi [ "${usergroup}" != "" ] && groupadd -r ${usergroup} rm -f outputpw.txt usernames=$(cat accountadd.txt) for username in ${usernames} do case ${action} in "create") [ "${usergroup}" != "" ] && usegrp=" -G ${usergroup} " || usegrp="" useradd ${usegrp} ${username} # 新增帳號 [ "${pwmech}" == "openssl" ] && usepw=$(openssl rand -base64 6) || usepw=${username} echo ${usepw} | passwd --stdin ${username} # 建立密碼 chage -d 0 ${username} # 強制登入修改密碼 [ "${homeperm}" == "yes" ] && chmod 711 /home/${username} echo "username=${username}, password=${usepw}" >> outputpw.txt ;; "delete") echo "deleting ${username}" userdel -r ${username} ;; *) echo "Usage: $0 [create|delete]" ;; esac done
接下來只要建立 accountadd.txt 這個檔案即可!鳥哥建立這個檔案裡面共有 5 行,你可以自行建立該檔案!內容每一行一個帳號。 而是否需要修改密碼?是否與帳號相同的資訊等等,你可以自由選擇!若使用 openssl 自動猜密碼時,使用者的密碼請由 outputpw.txt 去撈~鳥哥最常作的方法,就是將該檔案列印出來,用裁紙機一個帳號一條,交給同學即可!
[root@study ~]# vim accountadd.txt std01 std02 std03 std04 std05 [root@study ~]# sh accountadd.sh create Changing password for user std01. passwd: all authentication tokens updated successfully. ....(後面省略)....
這支簡單的腳本你可以在按如下的連結下載:
[root@study ~]# grep mail /etc/group [root@study ~]# grep youcan /etc/group [root@study ~]# groupadd youcan可發現 youcan 尚未被建立,因此如上表所示,我們主動去建立這個群組囉。
[root@study ~]# 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@study ~]# sh popuser.sh
[root@study ~]# 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 [root@study ~]# sh loginuser.sh