在 Linux (一) - 基本概念與系統操作 中,我們有介紹到 Linux 其中一個很大的優勢就是可以讓多使用者多工進行操作,而使用者要使用系統的資源時,都需要先向系統管理員 (root) 申請帳號,再以這個帳號進入系統。
當然要做為 Linux 的系統管理員的話,也必須要很清楚如何管理帳號,所以這篇就是要來介紹如何管裡 Linux 系統的帳號。
對 Linux 系統來說,他並不認識你的帳號名稱,雖然登入的時候都是輸入帳號,但是那只是讓我們容易記住。Linux 系統只認得 ID
,而 ID
和帳號之間的對應就存在 etc/passwd
中。如果你對於 etc
這個目錄還不清楚的話可以參考 Linux (二) - 檔案系統架構 中有簡單的做介紹。
以下會介紹幾個檔案都需要 root
的權限,所以在存取時要先取得 root
的權限。
下面我們列出 /etc/passwd
來看一下 :
$ cat etc/passwd
root:x:0:0:root:/root:/bin/bash
...略...
tony:x:1000:1000::/home/tony:/bin/bash
simon:x:1001:1001::/home/simon:/bin/bash
上面的輸出可以看到每個帳號一行資料,每一行以 :
隔開每個欄位。欄位依序是 :
/etc/shadow
。UID
,0
是 root
,1~99
預留給系統的帳號。GID
會對應到 /etc/group
中的 group ID
。tony
和 simon
兩個帳號在這個欄位就是空的。/home
目錄下會以帳號名稱建立一個目錄即為該帳號的家目錄。前面提到了加密的密碼會儲存在 /etc/shadow
中,下面我們先列出 /etc/shadow
來看一下 :
$ cat /etc/shadow
root:locked::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
...略...
tony:!!:18535:0:99999:7:::
simon:!!:18543:0:99999:7:::
上面的輸出同樣以 :
隔開每個欄位,並且每一行是一個帳號的資訊。而欄位依序是 :
!
則代表密碼目前已經被鎖定無法登入。而如果是空的代表使用者不需密碼即可登入。以上的欄位如果為0或空,則代表停用此功能。
由於加密過後的密碼基本上是沒有辦法被轉回明碼的,但是仍有機會被破解。
一般的使用者
一般使用者忘記了密碼可以透過系統管理員以 root
的身分使用 passwd
指令就可以重新設定了。
root 忘記密碼
root 忘記密碼會較麻煩,因為已經無法使用 root 登入了,所以可以透過重新開機進入單人維護模式,系統會給予 root 的權限,此時可以再以 passwd
指令修改。或是以 LiveCD
開機後掛載根目錄去修改 /etc/shadow
,將 root 的密碼欄位清空。接著再重新開機即可不需要使用密碼,但是登入後要盡快去重設密碼。操作方式請參考以下幾篇 :
如果想要查看特定帳號的資訊,可以直接使用 id
指令。
id [username]
範例
下面這個範例可以看到指定了特定的帳號後會輸出這個帳號的 uid
、gid
、groups
。這裡可以和前面的 /etc/passwd
對照一下,可以看到帳號名稱是 tony
的 uid
都是 1000
。這裡也要注意不要任意去修改 etc/passwd
的內容,不然會造成系統對應異常導致系統運作不正常。
另外也可以用於查詢帳號是否存在,若不存在也會回應沒有這個使用者。
$ id tony
uid=1000(tony) gid=1000(tony) groups=1000(tony),0(root)
$ id frank
id: frank: no such user
前面有提到每個帳號會對應到一個群組,下面我們就來介紹群組的相關設定和操作。
群組的相關資訊就儲存在 /etc/group
。下面我們列出 /etc/group
來看一下 :
$ cat /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
...略...
tony:x:1000:
simon:x:1001:
輸出同樣是以 :
隔開每個欄位,且每一行是一個群組的資訊。而欄位依序是 :
x
來顯示,而加密過的密碼會在 /etc/gshadow
中。/etc/passwd
中的 GID 就是對應到此。範例
這個範例要將使用者直接透過 /etc/group
加入群組,首先使用 vi
編輯器打開 /etc/group
之後,將 root:x:0:
後面加上要加入的使用者,也就是上面介紹的群組內成員的欄位。如下 :
$ vi /etc/group
root:x:0:tony,simon
bin:x:1:
daemon:x:2:
...略...
tony:x:1000:
simon:x:1001:
加進 root
群組後可以用 id
這個指令列出帳號的資訊來看。可以看到 groups
的地方會發現 tony
和 simon
都多了 0(root)
,也就代表他們都已經被加進了 root
的群組。
$ id tony
uid=1000(tony) gid=1000(tony) groups=1000(tony),0(root)
$ id simon
uid=1001(simon) gid=1001(simon) groups=1001(simon),0(root)
以上這個範例盡量不要將使用者加入 root
群組,因為這樣會讓使用者可以直接存取 root
群組的檔案。如果要使用也要在練習完後將 root
群組的使用者移除。
上面的範例一直都有出現每個使用者對應到一個以使用者自己的名稱為名的群組,這個就是所謂的初始群組。而使用者一登入系統後就會馬上擁有初始群組的權限,所以可以在往回看到上一個範例,tony
和 simon
這兩個就是初始群組,並不需要在後面加上使用者自己的名稱。對應到 /etc/passwd
就是 GID
這個欄位。
在上一個範例中,我們將 tony
和 simon
加入了 root
的群組,因此 tony
和 simon
就有權限可以存取 root
群組的檔案。但是如果現在要建立一個檔案,這個檔案會屬於哪個群組呢 ? 當然就是有效群組。
可以透過 groups
指令來查看目前登入的帳號有哪些群組的權限,而第一個即為有效群組,剩下的稱為 支援群組
。
範例
simon@mycomputer$ groups
simon tony
以上面這個例子來說也就是 simon 的有效群組是 simon
,而支援群組是 tony
。所以如果現在建立一個檔案,則檔案就會屬於 simon
這個群組。如下 :
$ touch test.txt
$ ls -l test.txt
-rw-rw-r-- 1 simon simon 11 Oct 14 06:20 test.txt
如果想要切換有效群組,可以透過 newgrp
指令來切換。但前提是要切換的群組必須要是支援群組。
範例
首先先將 simon
的有效群組換成 tony
,接著使用 groups
指令就可以看到輸出的第一個群組是 tony
,也就代表有效群組被換成了 tony
。這時再次新增一個檔案並且查看檔案的詳細資訊可以看到檔案所屬的群組被換成了 tony
。
simon@mycomputer$ newgrp tony
simon@mycomputer$ groups
tony simon
simon@mycomputer$ touch test2.txt
simon@mycomputer$ ls -l test2.txt
-rw-r--r-- 1 simon tony 0 Oct 14 06:32 test2.txt
系統管理員可以新增、修改和刪除使用者的帳號。下面我們就來介紹如何管理使用者帳號。
加入新的使用者的帳號可以使用 useradd
指令,但是要注意的是 useradd
新增完帳號之後不是就可以馬上使用了,還需要再透過 passwd
設定密碼才可以使用。
useradd [option] [username]
option :
UserID
。初始群組
。UserID Info
。Home Directory
。/bin/bash
。也就是 /etc/passwd 第七欄的 Shell
。YYYY-MM-DD
,用來表示帳號失效的日期。也就是 /etc/shadow 第八欄的 Account Experiation Date
。Password Inactivity Period
。範例
下面這個範例新增一個帳號 biden
,並且針對這個帳號做一些設定。
$ useradd -u 7788 \
-g tony \
-c "biden is a dumb dumb." \
-d /home \
-s /bin/sh \
-e 2020-10-14 \
-f 180 \
biden
由下面的輸出可以看到新增完此帳號後,設定的內容都有寫進對應的欄位中。
$ cat /etc/passwd
...略...
biden:x:7788:1000:biden is a dumb dumb.:/home:/bin/sh
$ cat /etc/shadow
...略...
biden:!!:18549:0:99999:7:180:18549:
$ id biden
uid=7788(biden) gid=1000(tony) groups=1000(tony)
預設使用 useradd
建立帳號後,這個帳號會暫時先被鎖住不能登入。可以看到前一個範例的 cat /etc/shadow
的輸出,在第二個欄位顯示 !!
。在 /etc/shadow 中我們有說過如果這個欄位的第一個字是 !
代表被鎖定不能登入。所以這個時候就需要用 passwd
指令來設定密碼。
除了建立帳號時要使用 passwd
來設定密碼,平常如果忘記密碼也可以使用 passwd
來重設密碼。
passwd [option] [user name]
option :
!
。--stdin
: 透過前一個 pipline 的輸出作為密碼輸入,可用於 Shell Script
。以上這些指令除了 -f
以外其他都需要 root
的權限。
user name : 如果沒有指定帳號就是更改目前的帳號,所以這裡要注意如果在 root 的時候要記得加上要改的帳號,不然就會改到 root。
👁🗨 如果是要更改自己的密碼就可以直接下 passwd
就可以更改了,不過就只能改自己的,如果是忘記密碼了或是要更改他人的密碼都需要 root
才能更改。
範例
首先就先將剛剛建立的 biden
加上密碼,改完後可以看到 /etc/shadow
的第二個欄位已經不是 !!
,代表現在是有密碼可以登入的。
$ passwd biden
Changing password for user biden.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
$ cat /etc/shadow
...略...
biden:$6$5ksojzZi$a9228NCaylRTaecg1qgZAhk0.lXLA5aZfehUhIncb7pceRgrOl3eBgZqxF1CX9rOwj0H0wF111AfHWRxskdsf/:18549:0:99999:7:180:18549:
將 biden
的密碼刪除,刪除完成後可以看到第二個欄位密碼變成空的。這也是一個方法讓使用者忘記密碼時可以刪掉他的密碼讓他自己重新設定。
$ passwd -d biden
Removing password for user biden.
passwd: Success
$ cat /etc/shadow
...略...
biden::18549:0:99999:7:180:18549:
將 biden
的密碼鎖住,可以看到第二個欄位又變成了 !!
,也就代表不能登入了。
$ passwd -l biden
Locking password for user biden.
passwd: Success
$ cat /etc/shadow
...略...
biden:!!:18549:0:99999:7:180:18549:
將 biden
的密碼解鎖,讓他可以重新登入,不過這裡有一個很有趣的地方是上鎖再解鎖之後並不是回復成原來的密碼,而是變成沒有密碼可以直接登入。
$ passwd -u biden
Unlocking password for user biden.
passwd: Warning: unlocked password would be empty.
passwd: Unsafe operation (use -f to force)
$ passwd -uf biden
Unlocking password for user biden.
passwd: Success
$ cat /etc/shadow
biden::18549:0:99999:7:180:18549:
將 biden
設為密碼過期,下次登入一定要重設密碼,設定完成後可以看到 /etc/shadow
的第三個欄位變成 0。
$ passwd -e biden
Expiring password for user biden.
passwd: Success
$ cat /etc/shadow
...略...
biden::0:0:99999:7:180:18549:
將 biden
的帳號最長使用期限設為 10 天,可以看到在設定天數的這些 option 是將天數直接寫在 option 後面,下面其他 option 也是同樣的方式。設定完成後可以看到 /etc/shadow
的第五個欄位被改成了 10。
$ passwd -x 10 biden
Adjusting aging data for user biden.
passwd: Success
$ cat /etc/shadow
...略...
biden::0:0:10:7:180:18549:
將 biden
的帳號最短使用期限設為 3 天,這裡的最短是指要過多久才可以更改。設定完成後可以看到 /etc/shadow
的第四個欄位被改成了 3。
$ passwd -n 3 biden
Adjusting aging data for user biden.
passwd: Success
$ cat /etc/shadow
...略...
biden::0:3:10:7:180:18549:
將 biden
的帳號使用到期警告設為 5 天前,這裡的最短是指要過多久才可以更改。設定完成後可以看到 /etc/shadow
的第六個欄位被改成了 5。
$ passwd -w 5 biden
Adjusting aging data for user biden.
passwd: Success
$ cat /etc/shadow
...略...
biden::0:3:10:5:180:18549:
將 biden
的帳號使用到期後還可以登入修改密碼的期限設為 7 天。設定完成後可以看到 /etc/shadow
的第七個欄位被改成了 7。
$ passwd -i 7 biden
Adjusting aging data for user biden.
passwd: Success
$ cat /etc/shadow
...略...
biden::0:3:10:5:7:18549:
如果想簡單的看使用者的帳戶資訊,可以使用 -S
直接列出來,前面的範例是為了要清楚的知道到底是改到哪裡的設定。如下 :
$ passwd -S biden
biden NP 1970-01-01 3 10 5 7 (Empty password.)
接著我們練習一組用 root
建立好帳號之後再切到使用者下再次修改密碼,如下 :
root@mycomputer$ useradd gina
root@mycomputer$ passwd gina
Changing password for user gina.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
root@mycomputer$ su gina
gina@mycomputer$ passwd
Changing password for user gina.
Changing password for gina.
(current) UNIX password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
最後,我們用 --stdin
來直接一次完成設定密碼。前面的 echo
指令會印出要設定的密碼,而後面的 passwd
就會使用 echo
指令的輸出直接輸入作為密碼,如此就不需要再輸入密碼即可完成密碼設定。
$ echo "1q2w3e4r5t_" | passwd --stdin gina
Changing password for user gina.
passwd: all authentication tokens updated successfully.
上述這種做法通常都用於 Shell Script
,可以一次大量建立使用者的帳號。但是如果用 Shell Script
會有個缺點是密碼保留在指令中,駭客可以透過 /root/.bash_history
取得命令的歷史紀錄並獲得密碼。
除了使用 passwd
指令來修改密碼的設定外,還可以用 chage
指令來更改。chage
就是 change age
,可以用來修改密碼各種時間的設定。
chage [option] [user name]
option :
-l : 列出此帳號的詳細密碼時效資訊。
-d : 上一次變更密碼的日期,填入格式為 YYYY-MM-DD
,若填入 0 則下次登入強制必須更改密碼,會更改 /etc/shadow 的第三個欄位。
-m : 密碼最短使用期限,填入天數,會更改 /etc/shadow 的第四個欄位。
-M : 密碼最長使用期限,填入天數,會更改 /etc/shadow 的第五個欄位。
-W : 密碼過期前幾天會發出警告,填入天數,會更改 /etc/shadow 的第六個欄位。
-I : 密碼過期幾天內還可以登入修改密碼,填入天數,會更改 /etc/shadow 的第七個欄位。
-E : 帳號失效日期,時間到就不能再登入,填入格式為 YYYY-MM-DD
,會更改 /etc/shadow 的第八個欄位。
範例
我們先用 -l
將帳號的密碼時效設定列出來看一下,如下 :
$ chage -l biden
Last password change : password must be changed
Password expires : password must be changed
Password inactive : password must be changed
Account expires : Oct 14, 2020
Minimum number of days between password change : 3
Maximum number of days between password change : 10
Number of days of warning before password expires : 5
接著我們來對這些設定進行更改,但是我們更改的時候不加 option
。chage
預設如果不加 option
的話就會一個一個列出來讓你改,不想改的欄位就按 Enter
就可以跳過,如下 :
$ chage biden
Changing the aging information for biden
Enter the new value, or press ENTER for the default
Minimum Password Age [3]:
Maximum Password Age [10]: 15
Last Password Change (YYYY-MM-DD) [1970-01-01]: 2020-10-15
Password Expiration Warning [5]:
Password Inactive [7]:
Account Expiration Date (YYYY-MM-DD) [2020-10-14]: 2021-10-15
$ chage -l biden
Last password change : Oct 15, 2020
Password expires : Oct 30, 2020
Password inactive : Nov 06, 2020
Account expires : Oct 15, 2021
Minimum number of days between password change : 3
Maximum number of days between password change : 15
Number of days of warning before password expires : 5
不過這種做法通常還是用在手動設定,如果要用 Shell Script
大量設定的話還是用 option
會比較方便。
如果在 useradd
的時候加入了錯誤的資料,可以直接去 /etc/passwd
和 /etc/shadow
修改,不過 Linux 也有提供指令可以直接修改。
usermod [option] [user name]
option :
YYYY-MM-DD
,會更改 /etc/shadow 的第八個欄位。-G
搭配使用,會修改 /etc/group 的第四欄。passwd -l
。-L
,會修改 /etc/shadow 的第二欄。等於 passwd -u
。範例
首先先針對幾個比較簡單的欄位做修改,結果如下 :
$ usermod -c "will biden beat trump ?" -e 2021-05-08 -f 120 biden
$ cat /etc/passwd
...略...
biden:x:7788:1000:will biden beat trump ?:/home:/bin/bash
$ cat /etc/shadow
...略...
biden::18550:3:15:5:120:18755:
下面這個範例主要示範群組的修改,首先更改初始群組這個這個比較沒有問題,接著修改支援群組要特別注意,可以看到修改成 simon
後是直接覆蓋過去不是加上去。要加支援群組要使用 -aG
才能新增。
# 修改初始群組
$ usermod -g gina biden
$ id biden
uid=7788(biden) gid=7789(gina) groups=7789(gina)
# 修改支援群組
$ usermod -G tony biden
$ id biden
uid=7788(biden) gid=7789(gina) groups=7789(gina),1000(tony)
# 修改支援群組
$ usermod -G simon biden
$ id biden
uid=7788(biden) gid=7789(gina) groups=7789(gina),1001(simon)
# 增加支援群組
$ usermod -aG tony biden
$ id biden
uid=7788(biden) gid=7789(gina) groups=7789(gina),1000(tony),1001(simon)
接著我們用 -l
將使用者的帳號名稱做修改,下面這個範例可以看到 biden
被改成 biden2
之後就找不到 biden
了。不過這裡也可以觀察到改名過後的 biden2
的 UID
還是 7788
,這也證實了前面提到的 Linux 系統只認得 UID
並不認得使用者名稱。
$ usermod -l biden2 biden
$ id biden
id: biden: no such user
$ id biden2
uid=7788(biden2) gid=7789(gina) groups=7789(gina),1000(tony),1001(simon)
而 UID
建議不要隨便更改,容易造成系統對應錯亂。
刪除使用者會將使用者所有相關的資料都刪除,包含 :
所以在刪除前需要確定是真的要清除整個帳號的所有資料
還是只要暫時性停用這個帳號
。如果只是要 暫時停用帳號
可以將 /etc/shadow/
的第八個欄位 (Account Experiation Date) 設為 0 就可以讓帳號不能使用。
userdel [option] [user name]
option :
加了 -r
並不代表就可以完全刪除這個使用者所有建立的檔案,因為使用者可能會在家目錄以外的地方建立檔案。所以可以先用 find
指令找到該使用者擁有的所有檔案再進行刪除。
範例
這裡我們就將 biden
這個帳號刪除,如下 :
$ userdel -r biden
$ id biden
id: biden: no such user
群組也可以建立及刪除,甚至可以設定群組管理員來管理帳號的加入和移除。
建立群組可以使用 groupadd
指令來完成。
groupadd [option] [group name]
option :
已加密
的密碼,不過群組密碼並不常用。範例
這個範例新增一個群組並且指定 GID 和密碼,由於密碼必須是加密的,所以可以使用 openssl
進行加密。如果沒有加密會在 /etc/gshadow
可以直接看到明碼。
$ groupadd -g 8877 -p `openssl 1q2w3e4r5t_ -1` group4
groupmod 可以修改群組的 GID 或是群組名稱。
groupmod [option] [group name]
option :
範例
下面這個範例先新增一個群組並將群組 GID 和名稱都進行修改。不過 GID
建議還是不要亂改,會造成系統對應錯亂。
$ groupadd -g 9100 group5
$ cat /etc/group
...略...
group5:x:9100:
$ groupmod -g 9200 -n group6 group5
$ cat /etc/group
...略...
group6:x:9200:
刪除群組可以使用 groupdel
指令來完成。
groupdel [group name]
範例
這個範例我們直接刪除剛剛改過名稱的 group6
。不過可以看到再刪除另一個群組 tony
的時候會發現不能刪除,因為有帳號使用這個群組作為初始群組,如果刪掉的話會造成這個帳號登入後找不到 GID
。如果一定要刪除要先到 /etc/passwd
中確定沒有帳號的 GID
使用這個群組作為初始群組。
$ groupdel group6
$ groupdel tony
groupdel: cannot remove the primary group of user 'tony'
Linux 系統針對群組還有再開放一個群組管理員的功能,root
可以針對每一個群組指定群組的管理員,群組管理員可以決定要讓誰加入群組以及將誰移出群組。
gpasswd [option] [group name]
option :
user1,user2,...
,可以一次指定多個。admin1, admin2,...
,可以一次指定多個。以上這些選項,-M
和 -A
只有 root
可以操作。
範例
這個範例首先先新增多個使用者來讓後面操作,然後新增一個群組並且給予密碼。接著 root
指定群組的管理員和群組的成員。
指定完群組管理員後,我們切換使用者到其中一個群組管理員 tim
,接著 tim
就可以新增和刪除使用者了。
# 新增帳號
$ useradd tim
$ useradd frank
$ useradd mary
$ useradd lin
$ useradd henry
# 新增群組並給予密碼
$ groupadd group10
$ gpasswd group10
Changing the password for group group10
New Password: 1q2w3e4r5t_
Re-enter new password: 1q2w3e4r5t_
# root 指定群組管理員&群組成員
$ gpasswd -A tim,frank -M mary,lin group10
$ cat /etc/group
...略...
group10:x:8867:mary,lin
# 切換到群組管理員 tim
$ su tim
# 加入 henry 到群組
$ gpasswd -a henry group10
Adding user henry to group group10
$ cat /etc/group
...略...
group10:x:8867:mary,lin,henry
# 將 mary 從群組移除
$ gpasswd -d mary group10
Removing user mary from group group10
$ cat /etc/group
...略...
group10:x:8867:lin,henry
本篇介紹了非常多關於帳號和群組管理的方式,如果身為一個 Linux 的系統管理員那一定要熟悉上面這些設定的方法。
[1] /etc/passwd 檔案解讀
[2] Linux 帳號管理與 ACL 權限設定
[3] Linux 新增使用者 useradd 指令用法教學與範例
[4] Linux 的 /etc/shadow 檔案結構:儲存真實密碼的地方
[5] Linux useradd 命令介紹
[6] 歷史命令
[7] Linux Groups Can Have Paswords
Linux