Linux 的權限概念相當的重要!這裡先簡略的了解一下。權限與帳號相關性很高喔!所以,也要玩一下帳號管理!
從前幾節課的練習中發現,使用 student 這種一般身份帳號在進行一些任務時,總是發現無法順利的複製或者是進行其他的檔案管理任務, 這是因為『權限不足』所致。本堂課要來介紹 Linux 基礎檔案系統,藉以了解為何 student 的任務會成功或失敗。 此外,為了管理權限,有時也需要管理使用者帳號,因此基礎帳號管理也在本堂課簡單介紹。
Linux 權限的目的是在『保護某些人的檔案資料』,因此,讀者在認識『權限』的角度上,應該要思考的是『這個檔案的權限設定後, 會造成哪個個人?或某群人的讀寫開放或保護』。所以,這些權限最終都是『應用在某個/某群帳號』上面!而且,權限都是『設定在檔案/目錄』上, 不是設定在帳號上面的,這也要先釐清。
Linux 的檔案權限在設定上,主要依據三種身份來決定,包括:
底下以一個小案例來說明這三種身份的用法。
假設讀者還在學校當老師,你有一本書要讓班上同學借閱,但你又不想管,此時你會如何決定『這本書 (檔案)』的命運? 通常的作法是:
由上面這個簡單的小案例,讀者應該能夠知道,Linux 上面的檔案『都是針對帳號』來進行管理的, 只是為了方便管理上的設定 (班級同學與非本班其他同學) ,因此又將非本人的所有帳號分為兩類,一類是加入使用者所設定的群組, 一個則是沒有加入群組的其他人。
單純的檔案權限觀察,可以使用 ls -l 或 ll 來查閱,底下為查詢系統 /var/spool/mail 這個目錄的權限方式:
[student@localhost ~]$ ls -ld /var/spool/mail
drwxrwxr-x. 2 root mail 21 Feb 16 11:51 /var/spool/mail
[ A ][B][C ] [D ] [E ] [ F ] [ G ]
簡單的分析,上述的資料共有七個欄位,每個欄位的意義為:
讀者首先可以分析一下這個『檔案』的『類型』。之前讀者應該看過第一個字元為 - 以及 d 的表示方式,事實上還有很多常見的檔案類型, 底下僅為常見的類型介紹:
所以讀者可以知道 /var/spool/mail 為一個目錄檔案 (d 開頭,為 directory 的縮寫)。確定了檔案類型後,接下來的 9 個字元都是 rwx 與減號而已, 從這 9 個字元判斷,讀者大概可以猜出 rwx 的意義為:
只不過 rwx 該如何與 root, mail 這個使用者與群組套上關係?我們可以使用下圖來查閱第 1, 3, 4 個欄位的相關性:
如上圖所示,第一組為檔案擁有者的權限,第二組為檔案擁有群組的權限,第三組為不是擁有者也沒有加入該群組的其他人權限。 所以上述的檔案權限為:
[-][rwx][r-x][r--] 0 123 456 789
0 為:代表這個檔名為目錄或檔案,本例中為檔案(-); 123為:擁有者的權限,本例中為可讀、可寫、可執行(rwx); 456為:同群組使用者權限,本例中為可讀可執行(rx); 789為:其他使用者權限,本例中為可讀(r),就是唯讀之意
帳號名稱 加入的群組 test1 test1, testgroup test2 test2, testgroup test3 test3, testgroup test4 test4
-rw-r--r-- 1 root root 238 Jun 18 17:22 test.txt -rwxr-xr-- 1 test1 testgroup 5238 Jun 19 10:25 ping_tsai
上面這個練習還挺重要的!因為,檔案權限判斷的重點,都是:『哪個用戶可以對這個檔案進行讀、寫、執行』這樣的概念,而帳號是否加入這個檔案所屬群組, 就是個需要考慮的重點!
如上面例題,讀者可以知道 test1 屬於 test1 及 testgroup 群組,所以可以理解帳號與權限的相關性。不過在實際的系統操作中, 若想知道帳號所屬的群組,可以使用 id 這個指令來觀察即可理解。
[student@localhost ~]$ id uid=1000(student) gid=1000(student) groups=1000(student) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 [student@localhost ~]$ id student uid=1000(student) gid=1000(student) groups=1000(student) # 可以加上帳號在 id 後面喔!若是自己本身,則會列出 selinux 相關的資料!
而除了 id 可以觀察帳號與權限的相關性,在檔案類型部份,可以使用前一堂課談到的 file 來查詢。
[student@localhost ~]$ ll -d /etc/rc.local /etc/rc.d /etc/passwd /dev/vda /dev/zero brw-rw----. 1 root disk 252, 0 Feb 22 2023 /dev/vda crw-rw-rw-. 1 root root 1, 5 Feb 22 2023 /dev/zero -rw-r--r--. 1 root root 2098 Feb 16 11:51 /etc/passwd drwxr-xr-x. 3 root root 36 Feb 20 14:21 /etc/rc.d lrwxrwxrwx. 1 root root 13 Jan 24 04:06 /etc/rc.local -> rc.d/rc.local根據前面第一個字元判斷, /dev/vda 為區塊裝置檔案、 /dev/zero 為週邊裝置檔案、/etc/passwd 為一般檔案、 /etc/rc.d 為目錄檔案、/etc/rc.local 為連結檔。。
[student@localhost ~]$ file /etc/rc.local /etc/rc.d /etc/passwd /dev/vda /dev/zero
/etc/rc.local: symbolic link to rc.d/rc.local
/etc/rc.d: directory
/etc/passwd: ASCII text
/dev/vda: block special (252/0)
/dev/zero: character special (1/5)
可以顯示出更多的結果喔!使用 ls -l 可以很快速的看到檔案屬性、權限的概觀,不過,其實讀者也能使用 getfacl 這個指令來了解檔案的相關屬性與權限。 如下所示,同樣使用 /var/spool/mail 作為範本:
[student@localhost ~]$ getfacl /var/spool/mail getfacl: Removing leading '/' from absolute path names # file: var/spool/mail <==檔名 # owner: root <==檔案擁有者 # group: mail <==檔案群組 user::rwx <==使用者的權限 group::rwx <==同群組帳號的權限 other::r-x <==其他人的權限
透過 getfacl 可以更清楚的查詢到檔案的擁有者與相關的權限設定,只不過就沒有檔案的類型、修改的時間等參數。
檔案的權限與屬性的修改,若以 ls -l 的輸出來說,則每個部份可以修改的指令參照大致如下:
[student@localhost ~]$ cd /dev/shm/ [student@localhost shm]$ touch checking [student@localhost shm]$ ls -l checking -rw-r--r--. 1 student student 0 Feb 21 22:54 checking [ chmod ] [chown] [chgrp] [ touch ] [ mv ]
由於一般帳號僅能修改自己檔案的檔名、時間與權限,無法隨意切換使用者與群組的設定。因此底下的例題中, 讀者應該使用 root 的身份來進行處理,方可順利進行。首先,切換身份成為 root ,並且將工作目錄切換到 /dev/shm。
[student@localhost shm]$ su - password: [root@localhost ~]# cd /dev/shm [root@localhost shm]# ll checking -rw-r--r--. 1 student student 0 Feb 21 22:54 checking # 多人多工的 Linux,所以 student 建立,root 也是看得到的!
查詢系統中是否有名為 daemon 的帳號,如果存在該帳號,請將 checking 的使用者改為 daemon 所擁有,而非 student 所擁有。
[root@localhost shm]# id daemon uid=2(daemon) gid=2(daemon) groups=2(daemon) [root@localhost shm]# chown daemon checking [root@localhost shm]# ll checking -rw-r--r--. 1 daemon student 0 Feb 21 22:54 checking
其實 chown 的功能非常多,chown 也可以用來進行群組的修改,也能同時修改檔案擁有者與群組。建議讀者們應該 man chown 查詢相關語法。
系統的群組都紀錄在 /etc/group 檔案內,若想要了解系統是否存在某個群組,可以使用 grep 這個關鍵字擷取指令來查詢。 舉例來說,當系統內有 bin 這個群組時,就將 checking 的群組改為 bin 所有,否則就不予修改。
[root@localhost shm]# grep myname /etc/group # 不會出現任何資訊,因為沒有這個群組存在的意思。 [root@localhost shm]# grep bin /etc/group bin:x:1: <==代表確實有這個群組存在! [root@localhost shm]# chgrp bin checking [root@localhost shm]# ll checking -rw-r--r--. 1 daemon bin 0 Feb 21 22:54 checking
由於檔案紀錄了三種身份,每種身份都擁有 rwx 的最大權限與 --- 沒權限的情況。為了搭配性的方便,於是使用 2 位元的方法來記憶! 亦即是 2 進位的情況:
於是每種身份最低為 0 分,最高則為 r+w+x --> 4+2+1 --> 7 分!而因為有 3 種身份,因此使用者,群組,其他人的身份, 最多為 777 最少為 000 。以上述 checking (-rw-rw-r--)的分數來說,使用者為 rw=6, 群組為 rw=6,其他人為 r=4,亦即該檔案權限為 664。
[root@localhost shm]# chmod 740 checking [root@localhost shm]# ll checking -rwxr-----. 1 daemon bin 0 Feb 21 22:54 checking
另外,讀者也能夠透過直觀的方式來進行權限的設定,亦即使用 u,g,o 代表使用者、群組與其他人, 然後使用 +, -, = 來加入/減少/直接設定權限,使用表列方式說明如下:
chmod | u(user) g(group) o(other) a(all) |
+(加入) -(減去) =(設定) |
r w x | 檔案或目錄 |
舉例來說,讓 daemon 可讀可寫可執行 checking 檔案,bin 群組的用戶們為可讀可寫,其他人則為可讀,使用符號法的處理方式:
[root@localhost shm]# chmod u=rwx,g=rw,o=r checking [root@localhost shm]# ll checking -rwxrw-r--. 1 daemon bin 0 Feb 21 22:54 checking
假如讀者需要修改時間參數與檔名,就得要使用 touch 與 mv 這兩個指令了。舉例來說, 讓 checking 的修改日期改到 1 月 5 日的中午 12 點(年度不變),實驗的方式如下:
[root@localhost shm]# touch -t 01051200 checking [root@localhost shm]# ll checking -rwxrw-r--. 1 daemon bin 0 Jan 5 12:00 checking
至於檔名的修改則是前一堂課談到的 mv 這個指令。
帳號管理是系統管理員很重要的一個任務,例如學校的教學環境中,教師通常需要預先建置學生的帳號,以方便學期間上課使用。 公司行號一樣也需要讓管理員建置好員工的帳號密碼,才能讓員工順利的辦公。此外,『將帳號分組』也是很重要的一項工作。
讀者應該還記得,要登入系統的時候,需要輸入兩個資料,一個是點選帳號名稱,再來則是輸入該帳號的密碼。 因此,最簡單的帳號管理,即是建立帳號與給予密碼的任務。
請讀者嘗試建立一個名為 myuser1 的帳號,以及給予 MypassworD 的密碼,方式如下:(記得,帳號管理是系統管理員的任務, 所以,身份一定要是 root 才行!)
[root@localhost ~]# useradd myuser1 [root@localhost ~]# passwd myuser1 Changing password for user myuser1. New password: <==此處輸入密碼 BAD PASSWORD: The password fails the dictionary check - it is based on a dictionary word Retype new password: <==再輸入密碼一次 passwd: all authentication tokens updated successfully. [root@localhost ~]# id myuser1 uid=1001(myuser1) gid=1001(myuser1) groups=1001(myuser1)
給予密碼的 passwd 這個指令操作時,有幾個重點,需要特別注意:
而若帳號設定錯誤,可以使用 userdel 刪除帳號,例如:
[root@localhost ~]# userdel -r myuser1 # 有趣的是, myuser1 的出現也能用 [tab] 按鈕喔! userdel -r my[tab] 看看!
加上 -r 的目的是要該帳號連同家目錄與電子郵件新件夾通通刪除的意思。如果忘記加上 -r 的話,那就需要手動刪除用戶的家目錄與郵件檔案。 一般帳號自己能不能修改自己的密碼?以及如何修改?參考底下的例題看看:
上面的範例中,我們可以知道一般帳號也是能修改自己密碼的,只是,密碼的強度要夠,否則你的密碼將無法通過系統的強度驗證, 那就無法順利的修改一般用戶的密碼了!接下來,以 root 身份管理其他用戶的帳號與密碼吧!
若需要建立帳號時,給予帳號一個次要的群組支援,就需要先行建置群組。舉例而言,以學校專題製作為例,有三個帳號 prouser1, prouser2, prouser3 加入共有的群組 progroup 時,該如何建立?首先,應該要先建立群組,透過 groupadd 來處理,再來則是透過 useradd --help 找到次要群組支援的選項為 -G 的項目,即可建立好群組、帳號與密碼。同時,管理員可以透過 passwd --help 找到 --stdin 的選項來操作密碼的給予。整體流程如下:
[root@localhost ~]# groupadd progroup [root@localhost ~]# grep progroup /etc/group progroup:x:1001: <==確定有 progroup 在設定檔當中了 [root@localhost ~]# useradd -G progroup prouser1 [root@localhost ~]# useradd -G progroup prouser2 [root@localhost ~]# useradd -G progroup prouser3 [root@localhost ~]# id prouser1 uid=1001(prouser1) gid=1002(prouser1) groups=1002(prouser1),1001(progroup) [root@localhost ~]# echo mypassword mypassword <== echo 會將訊息從螢幕上輸出 [root@localhost ~]# echo mypassword | passwd --stdin prouser1 Changing password for user prouser1. passwd: all authentication tokens updated successfully. [root@localhost ~]# echo mypassword | passwd --stdin prouser2 [root@localhost ~]# echo mypassword | passwd --stdin prouser3
讀者可以發現到使用 passwd --stdin 的方式來給予密碼時,密碼會紀錄到螢幕與 history 的環境中,因此不見得適用於所有需要資安的系統中。 不過對於大量建置帳號時,會是一個很好用的工具。
另外,如果建立好帳號之後才想到要修改群組資源時,不需要刪除帳號再重建,此時可以透過 usermod 來進行修改。舉例來說,當 prouser1 還需要加入 student 群組時,可以使用 usermod -G 的方式來處理!不過需要留意到 -a 的選項才行。
使用者能使用系統上面的資源與權限有關,因此簡易的帳號管理之後,就需要與權限搭配設計。
一般用戶只能夠修改屬於自己的檔案的 rwx 權限,因此,若 root 要協助複製資料給一般用戶時,需要特別注意該資料的權限。 例如底下的範例中,管理員要將 /etc/chrony.keys 複製給 student 時,需要注意相關的事宜如下:
[root@localhost ~]# ls -l /etc/chrony.keys -rw-r-----. 1 root chrony 540 Dec 16 2021 /etc/chrony.keys # 如上所示,一般用戶根本沒權限 [root@localhost ~]# cp /etc/chrony.keys ~student [root@localhost ~]# ls -l ~student/chrony.keys -rw-r-----. 1 root root 540 Feb 22 10:20 /home/student/chrony.keys [root@localhost ~]# chown student.student ~student/chrony.keys [root@localhost ~]# ls -l ~student/chrony.keys -rw-r-----. 1 student student 540 Feb 22 10:20 /home/student/chrony.keys
原本 root 複製資料給 student 時,若沒有考量到權限,則 student 依舊無法讀取該檔案的內容,這在資料的複製行為上,需要特別注意才行。
另外,如果使用者想要自己複製指令,或者是進行額外的工作任務,可以將指令移動到自己的家目錄來處理, 例如 student 想要將 ls 複製成為 myls 並且直接執行 myls 來運作系統,可以這樣處理:
[student@localhost ~]$ cp /bin/ls myls [student@localhost ~]$ ls -l myls -rwxr-xr-x. 1 student student 142168 Feb 22 10:22 myls [student@localhost ~]$ chmod 700 myls [student@localhost ~]$ ls -l myls -rwx------. 1 student student 142168 Feb 22 10:22 myls # 未來這個檔案,就只有 student 自己能玩! [student@localhost ~]$ myls bash: myls: 找不到指令... [student@localhost ~]$ ./myls chrony.keys Desktop Documents Downloads group history.log Music myls Pictures Public Templates text1.txt Videos # 但是,要執行就得要這樣做!當然,也能自己寫入 PATH 變數內!如下: [student@localhost ~]$ mkdir bin [student@localhost ~]$ mv myls bin [student@localhost ~]$ myls bin chrony.keys Desktop Documents Downloads group history.log Music Pictures Public Templates text1.txt Videos
若僅想要讓自己執行,可以將權限改為 700 之類的模樣。而『在本目錄執行』則需要使用『 ./command 』的型態來執行, 若想要直接輸入指令即可,那需要放入使用者自己家目錄下的 bin 子目錄才行 (與 $PATH 變數有關)。因此本範例中,最終將 myls 移動到 /home/student/bin/ 目錄下。
某些情境下,群組可能需要共享某些檔案資料。舉例來說,在學校做專題時,同組專題成員可能需要個別的帳號,不過卻需要一個共享的目錄, 讓大家可以共同分享彼此的專題成果。舉例來說, progroup 成員 prouser1, prouser2, prouser3 (前小節建置的帳號資料),需要共用 /srv/project1/ 的目錄, 則該目錄的建置與共享可以使用如下的方式來達成:
[root@localhost ~]# mkdir /srv/project1 [root@localhost ~]# chgrp progroup /srv/project1 [root@localhost ~]# chmod 770 /srv/project1 [root@localhost ~]# ls -ld /srv/project1 drwxrwx---. 2 root progroup 6 Feb 22 10:26 /srv/project1/
此時 progroup 的成員即可在 project1 目錄內進行任何動作。但 770 並非最好的處理方式,下一堂課讀者們將會學習到 SGID 的功能, 屆時才會學到較為正確的權限設定。
除了共享目錄之外,在執行檔的可執行權限設計上,也能夠針對群組來給予可執行權,讓其他人不可隨意執行共用的指令。 例如讓 mycat 執行與 cat 相同的結果,但是僅有 progroup 的用戶能夠執行,可以這樣執行:
[root@localhost ~]# which cat /usr/bin/cat [root@localhost ~]# echo $PATH /root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin # 基本上,我們執行指令時,該指令名稱就會到 PATH 設定的目錄去找, # 找到的第一個同名的指令,就會被執行喔! [root@localhost ~]# cp /usr/bin/cat /usr/local/bin/mycat [root@localhost ~]# ll /usr/local/bin/mycat -rwxr-xr-x. 1 root root 37464 Feb 22 10:29 /usr/local/bin/mycat # 預設的情況下,還是系統上所有人都可以執行 mycat 的情境!接下來讓我們來改一改! [root@localhost ~]# chgrp progroup /usr/local/bin/mycat [root@localhost ~]# chmod 750 /usr/local/bin/mycat [root@localhost ~]# ll /usr/local/bin/mycat -rwxr-x---. 1 root progroup 37464 Feb 22 10:29 /usr/local/bin/mycat
接下來,請讀者分別以 student 與 prouser1 的身份執行一次『 mycat /etc/hosts 』,即可發現不同點了。
作業硬碟一般操作說明:
作業當中,某些部份可能為簡答題~若為簡答題時,請將答案寫入 /home/student/ans.txt 當中,並寫好正確題號,方便老師訂正答案。 請注意,檔名寫錯將無法上傳!
ps: 請使用 root 的身份進行如下實做的任務。直接在系統上面操作,操作成功即可,上傳結果的程式會主動找到你的實做結果。
作業結果傳輸:請以 root 的身分執行 vbird_book_check_unit 指令上傳作業結果。 正常執行完畢的結果應會出現【XXXXXX_aa:bb:cc:dd:ee:ff_unitNN】字樣。若需要查閱自己上傳資料的時間, 請在作業系統上面使用瀏覽器查詢: http://192.168.251.254 檢查相對應的課程檔案。 相關流程請參考: vbird_book_check_unit