Skip to main content

第 6 章:帳號管理與 ACL 權限

使用者識別碼: UID 與 GID

一個是使用者 ID (User ID ,簡稱 UID)、一個是群組 ID (Group ID ,簡稱 GID)

# 1. 先察看一下,系統裡面有沒有一個名為 dmtsai 的用戶

id dmtsai
uid=1000(dmtsai) gid=1000(dmtsai) groups=1000(dmtsai),10(wheel) <==確定有這個帳號喔!

ll -d /home/dmtsai

drwx------. 17 dmtsai dmtsai 4096 Jul 17 19:51 /home/dmtsai
# 瞧一瞧,使用者的欄位正是 dmtsai


# 2. 修改一下,將剛剛我們的 dmtsai 的 1000 UID 改為 2000 看看:
vim /etc/passwd....(前面省略)....
dmtsai:x:2000:1000:dmtsai:/home/dmtsai:/bin/bash <==修改一下特殊字體部分,由 1000 改過來

ll -d /home/dmtsai
drwx------. 17 1000 dmtsai 4096 Jul 17 19:51 /home/dmtsai

# 很害怕吧!怎麼變成 1000 了?因為檔案只會記錄 UID 的數字而已!
# 因為我們亂改,所以導致 1000 找不到對應的帳號,因此顯示數字!

# 3. 記得將剛剛的 2000 改回來!
vim /etc/passwd....(前面省略)....
dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash <==『務必一定要』改回來!

/etc/passwd 檔案結構

head -n 4 /etc/passwdroot: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

UID

id 範圍該 ID 使用者特性
0(系統管理員)當 UID 是 0 時,代表這個帳號是『系統管理員』! 所以當你要讓其他的帳號名稱也具有 root 的權限時,將該帳號的 UID 改為 0 即可。 這也就是說,一部系統上面的系統管理員不見得只有 root 喔! 不過,很不建議有多個帳號的 UID 是 0 啦~容易讓系統管理員混亂!
1~999(系統帳號)保留給系統使用的 ID,其實除了 0 之外,其他的 UID 權限與特性並沒有不一樣。預設 1000 以下的數字讓給系統作為保留帳號只是一個習慣。由於系統上面啟動的網路服務或背景服務希望使用較小的權限去運作,因此不希望使用 root 的身份去執行這些服務, 所以我們就得要提供這些運作中程式的擁有者帳號才行。這些系統帳號通常是不可登入的, 所以才有 /sbin/nologin 這個特殊的 shell 存在。根據系統帳號的由來,通常這類帳號又約略被區分為兩種
1-200:由 distributions 自行建立的系統帳號。201~999:若使用者有系統帳號需求時,可以使用的帳號 UID。
1000~60000(可登入帳號)給一般使用者用的。事實上,目前的 linux 核心 (3.10.x 版)已經可以支援到 4294967295 (2^32-1) 這麼大的 UID 號碼喔!

/etc/shadow 檔案結構

head -n 4 /etc/shadowroot:$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:::

useradd 建立 user

useradd
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
useradd vbird1
ll -d /home/vbird1
drwx------. 3 vbird1 vbird1 74 Jul 20 21:50 /home/vbird1
# 預設會建立使用者家目錄,且權限為 700 !這是重點!

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: <==預設會建立一個與帳號一模一樣的群組名

usermod 權限調整

usermod
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』的說明。
usermod -c "VBird's test" vbird2
grep vbird2 /etc/passwd
vbird2:x:1500:100:VBird's test:/home/vbird2:/bin/bash

範例二:使用者 vbird2 這個帳號在 2015/12/31 失效。
usermod -e "2015-12-31" vbird2
chage -l vbird2 | grep 'Account expires'
Account expires : Dec 31, 2015

範例三:我們建立 vbird3 這個系統帳號時並沒有給予家目錄,請建立他的家目錄
ll -d ~vbird3
ls: cannot access /home/vbird3: No such file or directory <==確認一下,確實沒有家目錄的存在!
cp -a /etc/skel /home/vbird3
chown -R vbird3:vbird3 /home/vbird3
chmod 700 /home/vbird3
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 ,是因為我們僅要修改目錄的權限而非內部檔案的權限!

userdel 刪除使用者

  • 使用者帳號/密碼相關參數:/etc/passwd, /etc/shadow
  • 使用者群組相關參數:/etc/group, /etc/gshadow
  • 使用者個人檔案資料: /home/username, /var/spool/mail/username..
userdel
userdel [-r] username選項與參數:
-r :連同使用者的家目錄也一起刪除範例一:刪除 vbird2 ,連同家目錄一起刪除
userdel -r vbird2

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

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

passwd 建立密碼

passwd
passwd [--stdin] [帳號名稱]  <==所有人均可使用來改自己的密碼
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 密碼

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. <==竟然還是成功修改了!

groupadd 建立群組

groupadd
groupadd [-g gid] [-r] 群組名稱

選項與參數:
-g :後面接某個特定的 GID ,用來直接給予某個 GID ~
-r :建立系統群組啦!與 /etc/login.defs 內的 GID_MIN 有關。範例一:新建一個群組,名稱為 group1
groupadd group1
grep group1 /etc/group /etc/gshadow
/etc/group:group1:x:1503:
/etc/gshadow:group1:!::
# 群組的 GID 也是會由 1000 以上最大 GID+1 來決定!

groupmod 設定 group 權限

groupmod
groupmod [-g gid] [-n group_name] 群組名

選項與參數:
-g :修改既有的 GID 數字;
-n :修改既有的群組名稱範例一:將剛剛上個指令建立的 group1 名稱改為 mygroup , GID 為 201
groupmod -g 201 -n mygroup group1
grep mygroup /etc/group /etc/gshadow
/etc/group:mygroup:x:201:
/etc/gshadow:mygroup:!::

groupdel 刪除 group

groupdel
groupdel [groupname]範例一:將剛剛的 mygroup 刪除!
groupdel mygroup範例二:若要刪除 vbird1 這個群組的話?
groupdel vbird1
groupdel: cannot remove the primary group of user 'vbird1'

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

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

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

也就是說,如果你有一個目錄,需要給一堆人使用,每個人或每個群組所需要的權限並不相同時,在過去,傳統的 Linux 三種身份的三種權限是無法達到的, 因為基本上,傳統的 Linux 權限只能針對一個用戶、一個群組及非此群組的其他人設定權限而已,無法針對單一用戶或個人來設計權限。 而 ACL 就是為了要改變這個問題啊!好了,稍微了解之後,再來看看如何讓你的檔案系統可以支援 ACL 吧!

如何啟動 ACL

事實上,原本 ACL 是 unix-like 作業系統的額外支援項目,但因為近年以來 Linux 系統對權限細部設定的熱切需求, 因此目前 ACL 幾乎已經預設加入在所有常見的 Linux 檔案系統的掛載參數中 (ext2/ext3/ext4/xfs等等)!所以你無須進行任何動作, ACL 就可以被你使用囉!不過,如果你不放心系統是否真的有支援 ACL 的話,那麼就來檢查一下核心掛載時顯示的資訊吧!

dmesg | grep -i acl
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

ACL 的設定技巧: getfacl, setfacl

  • setfacl:設定某個目錄/檔案的 ACL 規範
setfacl
setfacl [-bkRd] [{-m|-x} acl參數] 目標檔名選項與參數:
-m :設定後續的 acl 參數給檔案使用,不可與 -x 合用;
-x :刪除後續的 acl 參數,不可與 -m 合用;
-b :移除『所有的』 ACL 設定參數;
-k :移除『預設的』 ACL 參數,關於所謂的『預設』參數於後續範例中介紹;
-R :遞迴設定 acl ,亦即包括次目錄都會被設定起來;
-d :設定『預設 acl 參數』的意思!只對目錄有效,在該目錄新建的資料會引用此預設值

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

setfacl user permission
# 1. 針對特定使用者的方式:
# 設定規範:『 u:[使用者帳號列表]:[rwx] 』,例如針對 vbird1 的權限規範 rx

touch acl_test1
ll acl_test1

-rw-r--r--. 1 root root 0 Jul 21 17:33 acl_test1

setfacl -m u:vbird1:rx acl_test1
ll acl_test1

-rw-r-xr--+ 1 root root 0 Jul 21 17:33 acl_test1

# 權限部分多了個 + ,且與原本的權限 (644) 看起來差異很大!但要如何查閱呢?

setfacl -m u::rwx acl_test1
ll acl_test1

-rwxr-xr--+ 1 root root 0 Jul 21 17:33 acl_test1

# 設定值中的 u 後面無使用者列表,代表設定該檔案擁有者,所以上面顯示 root 的權限成為 rwx 了!
  • getfacl:取得某個檔案/目錄的 ACL 設定項目
getfacl
getfacl filename

選項與參數:
getfacl 的選項幾乎與 setfacl 相同!所以鳥哥這裡就免去了選項的說明啊!# 請列出剛剛我們設定的 acl_test1 的權限內容:
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 設定吧!