Linux 基础学习训练教材 - RockyLinux 9.x

第 10 堂课:用户管理与 ACL 权限设置

针对 Linux 用户的高端管理,同时还有处理一下重要的 ACL 这玩意儿,针对单一用户、群组所进行的权限设计!

最近更新时间: 2023/05/16

帐号管理是一门大学问,用户可以回想一下之前玩过的 useradd, userdel, usermod 等指令的功能,同时再回想一下之前的权限概念, 就能够知道用户帐号管理的行为有多重要了!这一堂课还会针对同一个文件给予个别帐号或个别群组的权限功能,激活的是所谓的 ACL 的概念! 都是非常重要的管理行为!

10.1:Linux 帐号管理

在管理权限时,操作者可以借由 id 这个指令查找用户所加入的次要群组支持,借以了解用户对于某个文件的权限。 而主要的文件记录其实是用户的 UID 与 GID。

10.1.1:Linux 帐号之 UID 与 GID

系统记录用户 UID 与 GID 的文件主要在:

  • 记录 UID : /etc/passwd
  • 记录 GID : /etc/passwd 与 /etc/group

针对 UID 的部份,在 CentOS 7.x 以后,系统管理员、系统帐号与一般帐号的 UID 范围为:

id 范围该 ID 用户特性
0
(系统管理员)
当 UID 是 0 时,代表这个帐号是『系统管理员』!
1~999
(系统帐号)
保留给系统使用的 ID,其实除了 0 之外,其他的 UID 权限与特性并没有不一样。缺省 1000 以下的数字让给系统作为保留帐号只是一个习惯。根据系统帐号的由来,通常这类帐号又约略被区分为两种:
  • 1~200:由 distributions 自行创建的系统帐号;
  • 201~999:若用户有系统帐号需求时,可以使用的帐号 UID。
1000~60000
(可登录帐号)
给一般用户用的。事实上, Linux 内核支持 32 比特的 UID 记载, 所以目前 linux 内核至少已经可以支持到 4294967295 (2^32-1) 这么大的 UID 号码
例题 10.1.1-1: 测试系统支持到的最大 UID 为何
  1. 请使用 useradd 创建一个名为 maxuser1 的帐号,且设置 uid 为 4294967294
  2. 承上,创建 maxuser2 的帐号,且 uid 为 4294967295。
  3. 上述两个帐号,若有建置成功,请将该帐号删除

Linux 的帐号数据记录在 /etc/passwd 当中,这个文件的内容中,以冒号 (:) 为区隔,共有七个字段,每个字段的意义为:

  1. 帐号名称:就是登录的帐号名称
  2. 密码:已经挪到 /etc/shadow 中,因此在此都是 x
  3. UID:如上说明的 UID 信息
  4. GID:为用户『初始群组』的 ID
  5. 用户信息说明栏
  6. 家目录所在处
  7. 缺省登录时所取得的 shell 名称

更多的说明可以参考 man 5 passwd 的内容。早期用户加密过的密码记录在 /etc/passwd 第二个字段,但这个文件的权限是任何人均可读取, 因此,有心人士可以查阅到加密过的密码,再以暴力破解法就可能可以获取所有人的密码。因此,密码字段已经移动到另一个文件去, 这就是 /etc/shadow 的由来。 /etc/shadow 以冒号 (:) 分隔成 9 字段,各字段功能为 (详细数据可查找 man 5 shadow):

  1. 帐号名称
  2. 密码:目前大多使用 SHA 的加密格式来取代旧的 md5,因为密码的长度较长,比较不容易被破解。
  3. 最近更动密码的日期:主要以 1970/01/01 累积来的总日数
  4. 密码不可被更动的天数:修改好密码后,几天内不能变更之意,0 代表没限制
  5. 密码需要重新变更的天数:修改好密码后,几天内一定要变更的意思,0 代表没限制
  6. 密码需要变更期限前的警告天数:第 3 与第 5 字段相加后的几天内,当用户登录系统时,会警告该修改密码了
  7. 密码过期后的帐号宽限时间(密码失效日):密码有效日期为『更新日期(第3字段)』+『重新变更日期(第5字段)』, 过了该期限后用户依旧没有更新密码,那该密码就算过期了。(参考底下例题的说明)
  8. 帐号失效日期:亦使用 1970/01/01 累加的总日数,这个字段表示,此帐号在此字段规定的日期之后,将无法再使用。
  9. 系统保留尚未使用

用户的密码加密机制是可变的,从早期的 md5 到新的 sha512 改善了密码的数据长度,对于暴力破解法来说, 解密的时间会比较长。至于目前系统的加密机制可使用底下的方式查阅:

[root@localhost authselect]# authselect test sssd -s | grep password
password    requisite         pam_pwquality.so local_users_only
password    sufficient        pam_unix.so sha512 shadow nullok use_authtok
password    sufficient        pam_sss.so use_authtok
password    required          pam_deny.so

[root@localhost authselect]# cat /etc/login.defs | grep -i encrypt
.....
ENCRYPT_METHOD SHA512

用户的初始群组 (原生家庭) 记载在 /etc/passwd 文件的第四个字段,不过该 GID 对应到人类认识的群组名称就得到 /etc/group 当中查找。 这个文件的内容同样使用冒号 (:) 分隔成四个字段,内容为:

  1. 群组名称
  2. 群组密码:目前很少使用
  3. GID
  4. 加入此群组的帐号,使用逗号 (,) 分隔每个帐号

这三个文件中心以 /etc/passwd 为主,链接到 /etc/group 与 /etc/shadow 的示意图如下:

图 10.1.1-1、帐号相关文件之间的 UID/GID 与密码相关性示意图
图 10.1.1-1、帐号相关文件之间的 UID/GID 与密码相关性示意图
例题 10.1.1-2: 与帐号的密码、系统的无归属文件、密码过期与失效的计算相关信息
  1. 通过密码过期问题,强迫用户第一次登录系统时,必需要修改密码:
    1. 创建一个名为 check 的帐号,密码设置为 check123
    2. 请使用『 chage -d 0 check 』让这个帐号的密码建置日期强迫归零,亦即强迫该帐号密码过期。
    3. 当密码过期后,check 这个帐号登录系统会有什么应该要进行的任务?
  2. 查找 find 的选项,尝试找出系统中『不属于任何人』的文件文件名
    1. 使用 userdel check 删除这个用户,并且查找 /home 及 /var/spool/mail 里面,有没有无归属文件?
    2. 使用 find 的方法,找出无归属的文件文件名与权限。
    3. 最后,请手动删除这几个文件!
  3. 有一个 /etc/shadow 内的数据如下,尝试回答下列问题:
    student:$6$3iq4VYrt$Hg62ID...RVbE/:16849:5:180:7:::
    1. 这个帐号的密码最近一次被修改的日期为何 (查找 date 的 example 用法)
    2. 这个帐号的密码在那一个日期以前不可以被修改?
    3. 这个帐号的密码在那一个日期以内最好能够被修改?
    4. 这个帐号是否会失效?

10.1.2:帐号与群组管理

从上述数据我们可以知道,Linux 的帐号信息大概都记录在 /etc/passwd, /etc/shadow, /etc/group 当中,那如果我们要新建帐号时, 系统会怎么做呢?先测试建置帐号:

[root@localhost ~]# useradd testuser1
[root@localhost ~]# passwd testuser1
Changing password for user testuser1.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

让我们观察一下 testuser 这个帐号的相关数据,先看一下用户的 UID 与 GID:

[root@localhost ~]# id testuser1
uid=1008(testuser1) gid=1010(testuser1) groups=1010(testuser1)

[root@localhost ~]# grep testuser1 /etc/passwd /etc/group /etc/shadow
/etc/passwd:testuser1:x:1008:1010::/home/testuser1:/bin/bash
/etc/group:testuser1:x:1010:
/etc/shadow:testuser1:$6$t4R4uBMlGGSsvPpH$K/...s.elrZ0/:19478:0:99999:7:::

上述 shadow 的数据可以简易的使用如下的指令来查找:

[root@localhost ~]# LANG=C chage -l testuser1
Last password change                                : May 01, 2023
Password expires                                    : never
Password inactive                                   : never
Account expires                                     : never
Minimum number of days between password change      : 0
Maximum number of days between password change      : 99999
Number of days of warning before password expires   : 7

一般来说,新建帐号时,系统会搞定底下的事情:

  • 『拿既有的最大的 UID + 1 作为新的 UID』提供给新用户
  • 在 /home 创建与帐号同名的目录作为用户家目录
  • 给予 bash 这个 shell
  • 然后 RockyLinux 也会创建一个与帐号同名的群组给该帐号
  • 创建密码时,会依据默认值给予该帐号一些限制数据

至于新建用户时,上述的动作参考数据其实是参考 /etc/default/useradd 文件而来,该文件内容如下:

[root@localhost ~]# cat /etc/default/useradd
# useradd defaults file
GROUP=100               <==若为公开群组,使用 GID 100 的群组名称
HOME=/home              <==缺省用户家目录位置
INACTIVE=-1             <==密码是否失效,缺省不会失效!
EXPIRE=                 <==帐号是否需要失效 (shadow 第 8 字段)
SHELL=/bin/bash         <==缺省使用的 shell
SKEL=/etc/skel          <==缺省用户家目录的参考依据
CREATE_MAIL_SPOOL=yes   <==是否要创建用户邮件信箱

除了 /etc/default/useradd 之外,其他像是密码字段的默认值,则写入在 /etc/login.defs 这个文件中,这个文件的内容如下:

[root@localhost ~]# grep -v '#' /etc/login.defs | grep -v '^$'
MAIL_DIR        /var/spool/mail     <==用户缺省邮件信箱放置目录
UMASK           022                 <==一般用户设计缺省 umask 是拿掉 w 的 022
HOME_MODE       0700                <==用户家目录创建的权限会是 700
PASS_MAX_DAYS   99999               <==/etc/shadow 内的第 5 栏,多久需变更密码日数
PASS_MIN_DAYS   0                   <==/etc/shadow 内的第 4 栏,多久不可重新设置密码日数
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
SUB_UID_MIN                100000
SUB_UID_MAX             600100000
SUB_UID_COUNT               65536
GID_MIN                  1000       <==用户自订群组的最小 GID,小于 1000 为系统保留
GID_MAX                 60000       <==用户自订群组的最大 GID
SYS_GID_MIN               201       <==保留给用户自行设置的系统帐号最小值 GID
SYS_GID_MAX               999       <==保留给用户自行设置的系统帐号最大值 GID
SUB_GID_MIN                100000
SUB_GID_MAX             600100000
SUB_GID_COUNT               65536
ENCRYPT_METHOD SHA512               <==密码加密的机制使用的是 sha512 这一个机制!
USERGROUPS_ENAB yes                 <==使用 userdel 删除时,是否会删除初始群组
CREATE_HOME     yes                 <==在不加 -M 及 -m 时,是否主动创建用户家目录?
HMAC_CRYPTO_ALGO SHA512

一般来说,除非有特殊的需求,例如需要创建的是云端集中帐号管理,所以需要修改上述的设置档数据 (/etc/default/useradd, /etc/login.defs),否则尽量使用自订的手动修改用户相关参数,不要随意更动上述的文件内容。

例题 10.1.2-1:尝试使用 passwd 这个指令完成如下的任务:
  1. 使用 passwd 这个指令观察 testuser1 的密码状态
  2. 设置密码存活时间从 99999 改为 180 天
  3. 设置警告期限从 7 天改为 14 天
  4. 暂时将这个帐号的密码锁定,让这个帐号无法登录系统

passwd 就含有很多功能!只是, passwd -S 显示的消息比较简略,有时候我们可以通过另外几个程序来了解!

例题 10.1.2-2:尝试使用 chage 以及 usermod 完成如下任务 (不要使用 passwd 喔!)
  1. 使用 chage 这个指令观察 testuser1 的密码状态
  2. 使用 chage 设置密码存活时间从 180 改为 365 天
  3. 使用 chage 设置警告期限从 14 天改为 30 天
  4. 使用 usermod 将这个帐号的密码放行,让这个帐号可以登录系统

若需要删除帐号,使用 userdel 即可。不过需要加上 -r 的选项较佳!如果忘记加上 -r 的选项时,你应该要这样做:

[root@localhost ~]# userdel testuser1
[root@localhost ~]# ll -d /home/testuser1 /var/spool/mail/testuser1
drwx------. 3 1008 1010 78 May  1 11:06 /home/testuser1
-rw-rw----. 1 1008 mail  0 May  1 11:06 /var/spool/mail/testuser1
[root@localhost ~]# find / -nouser 2> /dev/null
/home/testuser1
/home/testuser1/.mozilla
/home/testuser1/.mozilla/extensions
/home/testuser1/.mozilla/plugins
/home/testuser1/.bash_logout
/home/testuser1/.bash_profile
/home/testuser1/.bashrc
/var/spool/mail/testuser1

[root@localhost ~]# rm -rfv /home/testuser1 /var/spool/mail/testuser1

如上所示,系统会有一堆暂存数据需要删除,因此管理员可能需要使用 rm -rf /home/testuser1 /var/spool/mail/testuser1 来删除掉这些没主人的文件。

10.1.3:bash shell script 的循环控制

某些时刻,我们可能需要同时从 /etc 底下的 passwd, shadow, group 抓出同一个帐号的相关信息, 如果我们想要将所有的帐号一个一个的列出,并且慢慢观察时,或使用 shell script 的 for 循环, 会是个有效率的方法喔!for 循环基本语法如下:

for 变量名 in 内容1 内容2 内容3 ...
do
	运行的脚本
done

变量名称会在 do..done 当中被取用,然后第一次运行循环为『变量名=内容1』,第二次为『变量名=内容2』,以此类推! 依据上面的基本语法,我们可以通过管线命令取出 /etc/passwd 内的第 1 个字段的帐号数据后,丢进循环处理。如下所示:

[root@localhost ~]# mkdir bin; cd bin
[root@localhost bin]# vim allid.sh
#!/bin/bash
# VBird 2023/05/01
users=$( cut -d ':' -f 1 /etc/passwd )
for username in ${users}
do
        echo
        getent passwd ${username}
        getent shadow ${username}
        getent group  ${username}
        echo
        read -p "press enter to continue." res
done

[root@localhost bin]# chmod a+x allid.sh
[root@localhost bin]# allid.sh

root:x:0:0:root:/root:/bin/bash
root:$6$XeZr.pMraahNczJu$2XQiaCdvrFu9V....OLUO.4Sq84/::0:99999:7:::
root:x:0:

press enter to continue.

bash shell script 的循环控制主要是根据 for ... do ... done 来处理,所以也称为 for 循环。上述的脚本中:

  1. 先使用 cut 取得系统所有帐号的数据,并带入 users 这个变量中
  2. 之后以 for 循环定义出名为 username 的变量,这个变量一次取出一个 ${users} 内的帐号数据
  3. 在 do ... done 动作中间,每次使用 getent 进行数据的截取
  4. 因为数据量太大,所以通过 read 的功能协助,按下 enter 才继续!
例题 10.1.3-1:使用下列的功能建置名为 account.sh 的指令来大量建置帐号
  1. 创建一个名为 users.txt 的文件,内容填写三行,每行一个帐号名称 (假设帐号为 linuxuser1~linuxuser3)
  2. 在 account.sh 当中,依序处理如下的行为:
    1. 确认 users.txt 的存在,若不存在就显示错误然后离开
    2. 创建名为 users 的变量,这个变量的内容为取出 users.txt 的内容
    3. 创建 for 循环,创建名为 username 的变量,此变量取用 ${users} 的内容
    4. 在循环内,针对每个用户进行 (1)创建帐号 (2)使用 passwd --stdin 创建同帐号名称的密码 (3)使用 chage -d 0 ${username} 强制用户第一次登录时需要修改自己的密码。

10.1.4:缺省权限 umask

用户在新建数据时,缺省的权限会是如何规范?一般来说,依据帐号的差异而会给予这样的设置:

  • 如果用户为 root 时,缺省目录权限为 755 而缺省文件为 644
  • 如果用户为一般帐号时,缺省目录权限为 775 而缺省文件为 664

这样的权限设计是考量一般用户可能会有同群组互相操作『同群组共享目录』的可能之故。但其实该缺省权限是可以修改的, 其主要的设置为 umask 所管理。

[student@localhost ~]$ umask
0022

[root@localhost ~]# umask
0022

在这一版本的 RockyLinux 环境中,缺省的 umask 在 root 与一般帐号之间,同样都是 0022!跟以前的版本都不太相同! 这点要特别注意。至于 umask 的意义,最简单的思考方向,umask 为拿掉不想要给予的缺省权限。 而四组分数中,第一个为特殊权限分数,不用理会,后续三个分数即为一般权限设置的三种身份权限。

例题 10.1.4-1:新建数据与 umask 的关系!
  1. 用 root 的身份,分别『 mkdir /dev/shm/mydir 』与『 touch /dev/shm/myfile 』然后分别观察两者的权限。
  2. 尝试说明为何 root 在新建数据时,缺省权限会是 755(目录) 与 644(文件)?

如果 linuxuser1 在新建目录时,希望同群组的用户可以一同完整操作文件,但是其他人则没有任何权限,该如何处理 umask 呢? 简单的处理流程为:

[root@localhost ~]# su - linuxuser1
[linuxuser1@localhost ~]$ umask
0022
[linuxuser1@localhost ~]$ umask 007
[linuxuser1@localhost ~]$ umask
0007

[linuxuser1@localhost ~]$ mkdir newdir
[linuxuser1@localhost ~]$ touch newfile
[linuxuser1@localhost ~]$ ll -d new*
drwxrwx---. 2 linuxuser1 linuxuser1 6 May  1 11:45 newdir
-rw-rw----. 1 linuxuser1 linuxuser1 0 May  1 11:45 newfile

若需要这样的设置永远存在,就写入 ~/.bashrc 当中即可。

10.1.5:帐号管理实务

  • 任务一:关于新建用户的家目录与 bash 操作环境设置,未来所有系统新建的用户,在其家目录中:
  • 必须要创建名为 bin 的子目录
  • 在 .bashrc 之内,必须要让 HISTSIZE 达到 10000 的记录
  • 创建 cp, rm, mv 的 alias ,让这三个指令缺省要加上 -i 的选项

解决方案很简单,因为只是修改未来新用户的数据而已,因此只要修订 /etc/skel 即可处理完毕!

[root@localhost ~]# cd /etc/skel
[root@localhost skel]# mkdir bin
[root@localhost skel]# mkdir .bashrc.d
[root@localhost skel]# vim .bashrc.d/vbirdadd
HISTSIZE=10000
HISTFILESIZE=10000
alias cp="cp -i"
alias mv="mv -i"
alias rm="rm -i"

[root@localhost skel]# useradd testuser2
[root@localhost skel]# ll -A /home/testuser2
-rw-r--r--. 1 testuser2 testuser2  18 Jan 24 06:42 .bash_logout
-rw-r--r--. 1 testuser2 testuser2 141 Jan 24 06:42 .bash_profile
-rw-r--r--. 1 testuser2 testuser2 492 Jan 24 06:42 .bashrc
drwxr-xr-x. 2 testuser2 testuser2  22 May  1 11:48 .bashrc.d
drwxr-xr-x. 2 testuser2 testuser2   6 May  1 11:46 bin
drwxr-xr-x. 4 testuser2 testuser2  39 Feb 16 11:43 .mozilla

[root@localhost skel]# userdel -r testuser2

建置完毕后我们使用 useradd 创建一个名为 testuser2 的帐号来查看一下是否有问题,若没有问题就可以删除该帐号了!

  • 任务二:创建 mailuser1 ~ mailuser5 共五个仅用于邮件收发的帐号

这五个帐号需求大致有底下的要求:

  • 这五个帐号为纯 email 帐号,不许这五个帐号使用本机登录取得 shell,也不许通过网络取得可交互的 shell
  • 使用 openssl rand -base64 6 取得 8 位数密码,将密码设置给 mailuser[1-5]
  • 最终输出 mailuserpw.txt 的文件,内容就是这五个帐号与对应的密码

上述第一点主要是 shell 改成不可交互的 shell 即可,缺省建议使用 /sbin/nologin 较佳。 由于建置帐号的数据太多,因此建议使用 shell script 来处理较佳!

[root@localhost ~]# cd bin
[root@localhost bin]# vim mailuser.sh
#!/bin/bash
# This program will create mail users
# VBird 2016/05/03

for user in $(seq 1 5)
do
        username="mailuser${user}"
        userpass=$(openssl rand -base64 6)
        useradd -s /sbin/nologin ${username}
        echo ${userpass} | passwd --stdin ${username}
        echo "${username} ${userpass}" >> mailuserpw.txt
done

[root@localhost bin]# sh mailuser.sh
[root@localhost bin]# cat mailuserpw.txt
mailuser1 M8pk6GEt
mailuser2 HznQI88d
mailuser3 zKpg4eg/
mailuser4 aakuwjo/
mailuser5 VrJtokaT

[root@localhost bin]# grep mailuser /etc/passwd
mailuser1:x:1011:1013::/home/mailuser1:/sbin/nologin
mailuser2:x:1012:1014::/home/mailuser2:/sbin/nologin
mailuser3:x:1013:1015::/home/mailuser3:/sbin/nologin
mailuser4:x:1014:1016::/home/mailuser4:/sbin/nologin
mailuser5:x:1015:1017::/home/mailuser5:/sbin/nologin

上述即可创建好专门给 mail user 专用的帐号了!而且这些帐号还无法登录系统操作 bash,这样系统较为安全!

  • 任务三:特殊帐号的创建

由于软件的特殊需求,我们需要创建如下的帐号:

  • UID 为 399 的名为 sysuser1 的帐号
  • 这个帐号的初始群组为 users
  • 这个帐号的密码为 rocky9。

其实不难,只要两个指令即可结束!

[root@localhost ~]# useradd -u 399 -g users sysuser1
[root@localhost ~]# echo rocky9 | passwd --stdin sysuser1
[root@localhost ~]# id sysuser1
uid=399(sysuser1) gid=100(users) groups=100(users)

建议读者们最终一定要自己检查看看是否正确才好!所以上述我们使用了 id 这个指令来查找是否正确!

  • 任务四:同一项目人员的共享目录资源情况:

就是之前谈到文件权限概念时,提到的共享目录功能啰!

  • 我的用户 pro1, pro2, pro3 是同一个项目计划的开发人员
  • 我想要让这三个用户在同一个目录底下工作,但这三个用户还是拥有自己的家目录与基本的私有群组。
  • 假设我要让这个项目计划在 /srv/projecta 目录下开发

问题不难,读者应该会想到,之前处理权限数据时,就曾经玩过『共享目录』的信息,这里即是重新复习一次!

[root@localhost ~]# groupadd project
[root@localhost ~]# useradd -G project pro1
[root@localhost ~]# useradd -G project pro2
[root@localhost ~]# useradd -G project pro3
[root@localhost ~]# echo password | passwd --stdin pro1
[root@localhost ~]# echo password | passwd --stdin pro2
[root@localhost ~]# echo password | passwd --stdin pro3
[root@localhost ~]# mkdir /srv/projecta
[root@localhost ~]# chgrp project /srv/projecta
[root@localhost ~]# chmod 2770 /srv/projecta
[root@localhost ~]# ll -d /srv/projecta
drwxrws---. 2 root project 6 May  3 21:43 /srv/projecta

最终三个用户都加入 project 这个群组,而这个群组的用户均可在 /srv/projecta 目录里进行任何工作!

10.2:多人共管系统的环境:用 sudo

由于系统的工作比较复杂,经常有不同的用户会共同管理一部系统,这在社群的实务运作上经常发现。因为管理系统时需要管理员 (root) 的权限, 本章之前读者可以通过 su 来切换用户,但如此一来就得要提供所有的用户 root 的密码,对于系统的运作来说,可能会有些许的问题。 例如某位用户切换成 root 密码后,不小心改了 root 的密码,而且自己也忘记了改回来,则未来大家都不知道如何操作系统了。

相对于 su 需要了解新切换的用户密码 (常常是需要 root 的密码), sudo 的运行则仅需要自己的密码即可!甚至可以设置不需要密码即可运行 sudo ! 由于 sudo 可以让你以其他用户的身份运行指令 (通常是使用 root 的身份来运行指令),因此并非所有人都能够运行 sudo , 而是仅有规范到 /etc/sudoers 内的用户才能够运行 sudo 这个指令。

只有信任用户才能够操作 sudo 这个指令,因此一开始还是需要使用 root 的权限来管理 sudo 的使用权才行。 虽然 sudo 的设置档为 /etc/sudoers,不过建议使用 visudo 来编辑较佳,因为 visudo 可以进行设置档的语法检验功能。

[root@localhost ~]# visudo
## Allow root to run any commands anywhere
root                     ALL=(ALL)           ALL
用户帐号  登录者的来源主机=(可切换的身份) 可下达的指令

大约在 100 行附近,读者会看到上面的 root 开头那行。由于仅有 root 这一行,亦即一开始仅有 root 可以运行 sudo 的意思。

例题 10.2-1: 管理与使用 sudo 的用户
  1. 系统管理员的管理阶段:
    1. 如何让 student 这个帐号可以运行 sudo 来转换身份成为 root 进行系统管理?
  2. 一般用户操作行为
    1. 利用 student 身份操作 sudo ,进行 grep student /etc/shadow 的行为
    2. 让 student 操作 su - 时,输入的是自己的密码而非 root 密码

除了单一个人的设置之外,在 /etc/sudoers 若有底下这一行,亦代表加入 wheel 群组的用户也能够操作 sudo 之意

[root@localhost ~]# visudo
## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL
# 这一行大概在 107 行前后喔!

例题 10.2-2: 测试加入 wheel 群组的效果!
  1. 一般帐号:测试一下 linuxuser1 能否操作 sudo 指令达成 tail /etc/shadow 任务?
  2. 系统管理员:将 linuxuser1 加入 wheel 群组内
  3. 一般帐号:再重新测试第 1 点任务。

上面这个练习过程,你可以发现到,让某个用户加入 wheel 是一个很可怕的决定!你必需要确认该用户不会乱用 sudo, 否则,就不应该让该用户加入 wheel 群组!这个 sudo 也是网络社共管 server 时,经常使用的技巧!可以避免 root 密码流落出去而导致的一些资安问题。

10.3 主机的细部权限规划:ACL 的使用

如果 10.1 小节最后的一个练习中, /srv/projecta 需要让 student 这个帐号登录去『查看』数据而已,不能变更现有的权限设置, 此时该如何设计呢?这时就可以考虑 ACL (Access Control List, 访问控制列表) 的使用了!

10.3.1:什么是 ACL 与如何支持启动 ACL

ACL 是 Access Control List 的缩写,主要的目的是在提供传统的 owner,group,others 的 read,write,execute 权限之外的细部权限设置。ACL 可以针对单一用户,单一文件或目录来进行 r,w,x 的权限规范,对于需要特殊权限的使用状况非常有帮助。

ACL 主要可以针对几个项目来加以控制:

  • 用户 (user):可以针对用户来设置权限;
  • 群组 (group):针对群组为对象来设置其权限;
  • 缺省属性 (mask):还可以针对在该目录下在创建新文件/目录时,规范新数据的缺省权限;

ACL 必须要配合文件系统的挂载启动才能生效,一般均将 acl 参数写入 /etc/fstab 的第四字段中。不过由于 ACL 几乎为目前 Linux 标准支持的文件系统参数, 因此读者仅须查找内核是否启动 ACL 即可,已无须将 acl 参数写入挂载设置中。

[root@localhost ~]# dmesg | grep -i acl
506:[    0.802661] systemd[1]: systemd 239 running in system mode. (+PAM +AUDIT +SELINUX 
   +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 
   +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy)
566:[    2.494185] SGI XFS with ACLs, security attributes, no debug enabled
582:[    4.244339] systemd[1]: systemd 239 running in system mode. (+PAM +AUDIT +SELINUX 
   +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 
   +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy)

除了内核已经有支持之外, systemd 也有支持~XFS 文件系统也缺省支持喔!使用 dmesg 就可以明显的查阅出来。另外, ext4 文件系统家族,在 CentOS 7 以后的版本 (包含 RockyLinux 9),缺省挂载时也会加上 acl 的参数!

例题 10.3.1-1: 查找 EXT4 是否缺省支持 ACL 列表
  1. 查找到系统应该有个 ext4 文件系统,找出来!并且查找目前系统记载的挂载参数有哪些?
  2. 使用 dumpe2fs 找出 EXT4 文件系统的挂载参数,尤其是缺省参数 (default mount option)

10.3.2:ACL 的设置技巧

ACL 针对单一用户的设置练习中,我们以『让 student 可以读取 /srv/projecta 』为范本来介绍。

[root@localhost ~]# ll -d /srv/projecta
drwxrws---. 2 root project 6 May  1 11:53 /srv/projecta

[root@localhost ~]# setfacl -m u:student:rx /srv/projecta
[root@localhost ~]# ll -d /srv/projecta
drwxrws---+ 2 root project 6 May  1 11:53 /srv/projecta

[root@localhost ~]# getfacl /srv/projecta
getfacl: Removing leading '/' from absolute path names
# file: srv/projecta
# owner: root
# group: project
# flags: -s-
user::rwx          <==缺省的拥有者权限
user:student:r-x   <==针对 student 的权限
group::rwx         <==缺省的群组权限
mask::rwx          <==缺省的 mask 权限
other::---

如上所示,setfacl -m 为设置的指令与选项,而设置的项目则主要有:

  • 针对个人: u:帐号名称:rwx-
  • 针对群组: g:群组名称:rwx-

至于 getfacl 则是查阅 ACL 设置的指令。输出结果与上述的设置项目类似,只是当帐号或群组名称没有写的时候,代表为文件拥有者的帐号与群组之意。 因此就能够得到上述的结果。

至于 getfacl 输出的结果中,有个 mask 的项目,10.1.4 所述,umask 为拿掉的权限,在 getfacl 当中,mask 则是可给予的权限之意。 缺省 mask 会全部都给予~如果我们将 mask 拿掉只剩下 x 时,会发生的问题如下:

[root@localhost ~]# setfacl -m m::x /srv/projecta
[root@localhost ~]# getfacl /srv/projecta
# file: srv/projecta
# owner: root
# group: project
# flags: -s-
user::rwx
user:student:r-x                #effective:--x
group::rwx                      #effective:--x
mask::--x
other::---

由于 mask 的关系,因此 student 这个帐号虽然给予 rx 的权限,但是实际上可以取得的权限则仅有 x 而已 (观察 effective 的输出项目)。 此外,如果要取消掉这个设置值时,可以使用如下的方式处理。

[root@localhost ~]# setfacl -m m::rwx /srv/projecta
[root@localhost ~]# getfacl /srv/projecta

亦即重新设置进去即可。那如果使用 pro1 这个帐号实际在 /srv/projecta 操作时,会出现的权限状态情况如下:

[root@localhost ~]# su - pro1
[pro1@localhost ~]$ cd /srv/projecta
[pro1@localhost projecta]$ mkdir newdir
[pro1@localhost projecta]$ touch newfile
[pro1@localhost projecta]$ ll -d new*
drwxrwsr-x. 2 pro1 project 6 May 11 20:41 newdir
-rw-rw-r--. 1 pro1 project 0 May 11 20:41 newfile

读者们可以发现在 /srv/projecta 目录内的新文件并没有缺省的 ACL 设置值,因此 student 的权限很可能被修改掉而无法保持 rx 的权限设置。此时,我们可以额外指定『缺省的 ACL 权限』信息,如下设置:

[root@localhost ~]# setfacl -m d:u:student:rx /srv/projecta
[root@localhost ~]# getfacl /srv/projecta
# file: srv/projecta
# owner: root
# group: project
# flags: -s-
user::rwx
user:student:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:student:r-x
default:group::rwx
default:mask::rwx
default:other::---

若读者发现设置错误,想要将某一条 ACL 的权限设置取消时,例如将 student 的规则取消,则可以使用如下的方式来处理:

[root@localhost ~]# setfacl -x u:student /srv/projecta

取消设置比较单纯,不过要注意取消的情况得要使用 -x 这个选项,而非 -m 的选项。此外,由于取消设置是不需要处理权限的, 因此取消时,仅需要处理『 u:帐号 』或『 g:群组 』这样就好了!那如果要将该文件的所有 ACL 设置都取消时,可以使用底下的方式:

[root@localhost ~]# setfacl -b /srv/projecta
[root@localhost ~]# ll -d /srv/projecta/
drwxrws---. 3 root project 35 May  1 12:05 /srv/projecta/

读者可以发现到,权限位置最末位的 + 号不见了,因为已经完整的取消的缘故。

例题 10.3.2-1: 练习 ACL 操作,使用新的帐号与群组,搭配共享目录及 ACL 设计复杂权限功能:
  1. 先设计好需要的数据,包括老师群组、学生群组、老师帐号与学生帐号等信息。
    1. 有两个群组需要创建,一个是老师的 myteacher 一个是学生的 mystudent,两个群组创建时,请使用系统帐号的群组 GID 号码范围
    2. 两个群组各有三个人,分别是 myteacher1 ~ myteacher3 以及 mystudent1 ~ mystudent3,请使用缺省的情况创建好这六个帐号,同时注意, 六个人都需要有个别的次要群组支持
    3. 六个人的密码均是 password 喔!
  2. 开始建置共享目录与实际的老师仅具有观察功能的权限设置:
    1. mystudent1 ~ mystudent3 需要有共享目录,该目录名称 /srv/myshare ,同时,除了 mystudent 具有完整的权限之外,其他人不可有任何权限。
    2. 由于 myteacher 的群组是老师,老师们需要进入 /srv/myshare 查阅学生的进度,但是不可干扰学生的作业,因此应该要给予 rx 的权限才对
    3. 但由于 myteacher3 并不是这个班级的老师,因此这个老师帐号不可以进入该目录。

10.4:课后练习操作

  • 上课的课后练习,非作业:
  1. 创建各种群组与帐号:
    1. 创建一个系统群组,名为: sysgroup
    2. 创建三个系统帐号,名为: mysysuser1, mysysuser2, mysysuser3,(1)这三个帐号都支持 sysgroup 为次要群组, (2)这三个帐号都不需要家目录, (3)这三个帐号的密码都是 mysystem。
    3. 创建一个远程帐号,名为: mysysuser4,这个帐号的家目录指定到 /remote/mysysuser4,密码为 mysystem。
    4. 直接删除 linuxuser3 这个帐号,但是不要删除这个帐号的家目录。
    5. 参考余留下来的 linuxuser3 帐号数据,重建这个帐号信息。
  2. 权限相关设置
    1. 创建名为 /opt/sysdir 目录,这个目录可以让 sysgroup 群组所属的用户具有完整权限,其他人则无任何权限。
    2. mysysuser4 必须要在上述目录下进行可查阅的行为,且此可查阅 (不可写入) 的行为是具有默认值的。
    3. mysysuser3 很不乖,所以针对上述目录没有任何权限。
  • 作业 (不提供学生答案,仅提供教师参考答案)

作业硬盘一般操作说明:

  • 打开云端虚拟机前,请务必确认你打开的硬盘是『unit10』,否则就会做错题目
  • 若要使用图形界面,请务必使用 student 身份登录,若需要切换身份,再激活终端机处理。
  • 若有简答题需要使用中文,请自行以第一堂课的动作自行处理输入法安装。
  • 每部虚拟机均有独特的网卡地址,请勿使用他人硬盘上传,否则计分为 0 分。
  • 每位同学均有自己的 IP 尾数,请先向老师询问您的 IP 尾数,才可以进行作业上传。
  • 最终上传作业结果,请务必使用 root 身份上传。
  • 进入作业硬盘后,先用 root 身份运行 vbird_book_setup_ip , 运行流程请参考:vbird_book_setup_ip

作业当中,某些部份可能为简答题~若为简答题时,请将答案写入 /home/student/ans.txt 当中,并写好正确题号,方便老师订正答案。 请注意,文件名写错将无法上传!

请使用 root 的身份进行如下实做的任务。直接在系统上面操作,操作成功即可,上传结果的程序会主动找到你的实做结果。 另外,因为题目是有连续性的,请依照顺序完成题目,尽量不要跳着做。

  1. (12%)请回答底下问答题,答案请写入 /root/ans10.txt 当中:
    1. 一般我们在创建 linux 帐号时,哪三个文件会记录这个帐号的 UID, GID, 支持群组, 密码等信息?
    2. 一般帐号被创建后(假设帐号名称为 myusername),基本上会有哪一个目录与哪一个文件会被创建?
    3. 若设置 umask 033 后,新建的文件与目录权限各为几分?(写下两个权限的分数)
    4. 在本章操作系统的硬盘理, /etc /var 与 /usr 里面,各有一个不属于任何人的文件 (请略过 gooduser 文件名),请将文件的完整文件名找出来,并写下来
  2. (5%)创建一个名为 mysys1 的系统帐号,且这个系统帐号 (1)不需要家目录 (2)给予 /sbin/nologin 的 shell (3)也不需要密码
  3. (12%)修改新建帐号的缺省信息 (亦即,使用 useradd username 时,就可以具有底下的默认值)
    1. 让未来新建的用户,其家目录缺省都会有一个名为 web 的子目录存在?
    2. 让新建用户的 history 缺省可以记忆 5000 笔记录(已存在帐号不受影响)
    3. 让新建帐号的 shell 将使用 /sbin/nologin
  4. (10%)有个名为 gooduser 的帐号不小心被删除了,还好,这个帐号的家目录还存在。
    1. 请依据这个提示,重建这个帐号 (记住,UID与GID应该要回复到原本尚未被删除前的状态)
    2. 且该用户的密码设置为 mypassword, shell 设置为 /bin/bash
    3. 这个帐号请重新设置为可以使用 sudo 的权限
  5. (10%)由于你帮学校老师管理 FTP 服务器,这个服务器的用户不能提供可登录系统的 shell,但是可以使用 FTP 与 email 等网络服务:
    1. 帐号名称为: ftpuser1, ftpuser2, ftpuser3,这三个帐号可以使用 ftp 网络功能,但是不能在系统前登录 tty 或使用终端机登录系统;
    2. 这三个帐号的密码均为 MyPassWord
  6. (26%)创建一个名为 /root/myaccount.sh 的大量创建帐号的脚本,这个脚本运行后,可以完成底下的事件:
    1. 会创建一个名为 mygroup 的群组
    2. 会依据缺省环境创建 30 个帐号,帐号名称为 myuser01 ~ myuser30 共 30 个帐号,且这些帐号会支持 mygroup 为次要群组 (hint: 请 man seq 这个指令,找到如何自动补 0 的功能,以满足 01 到 09 的要求)
    3. 每个人的密码会使用【 openssl rand -base64 6 】随机取得一个 8 个字符的密码, 并且这个密码会被记录到 /root/account.password 文件中,每一行一个,且每一行的格式有点像【myuser01:AABBCCDD】
    4. 会使用 /bin/bash 这个 shell
  7. (15%)由于你管理的系统需要有专题群组的伙伴共同使用系统,因此你将这些专题伙伴加入同一个次要群组支持!
    1. 专题群组的名称设为: myproject
    2. 专题组员的名称分别为: mypro1, mypro2, mypro3,且这三个帐号都加入了 myproject 群组的次要支持
    3. 这三个帐号的密码均为 MyPassWord
    4. 使用 /bin/bash
    5. 这个专题组员可共用 /srv/mydir 目录,其他人则没有任何权限
  8. (10%)特别目录的权限应用:
    1. 刚刚创建的 /srv/mydir 目录,在不更改原有的权限设置下 (因为原本就是给 myproject 群组用的), 现在,要让加入 users 群组的帐号们,也能够进入该目录查阅数据 (只能进入与查阅,不能写入),该如何处置?
    2. 那个 gooduser 的帐号,其实是老师的帐号,在不更改既有权限的情况下, gooduser 也需要能够进入该目录做任何事情, 且未来在 /srv/mydir 所新创建的任何文件(或目录)数据,gooduser 也能够进行任何动作。(hint:就是有默认值的意思)

作业结果传输:请以 root 的身分运行 vbird_book_check_unit 指令上传作业结果。 正常运行完毕的结果应会出现【XXXXXX_aa:bb:cc:dd:ee:ff_unitNN】字样。若需要查阅自己上传数据的时间, 请在操作系统上面使用浏览器查找: http://192.168.251.254 检查相对应的课程文件。 相关流程请参考: vbird_book_check_unit

修改历史:
  • 2023/05/01:id 竟然可以主动支持多个帐号输入了!所以循环的方式有修改说明!
  • 2023/05/16:这才刚刚做好硬盘啊~
2023/05/01 以来统计人数
计数器
其他链接
环境工程模式篇
鸟园讨论区
鸟哥旧站

今日 人数统计
昨日 人数统计
本月 人数统计
上月 人数统计