针对 Linux 用户的高端管理,同时还有处理一下重要的 ACL 这玩意儿,针对单一用户、群组所进行的权限设计!
帐号管理是一门大学问,用户可以回想一下之前玩过的 useradd, userdel, usermod 等指令的功能,同时再回想一下之前的权限概念, 就能够知道用户帐号管理的行为有多重要了!这一堂课还会针对同一个文件给予个别帐号或个别群组的权限功能,激活的是所谓的 ACL 的概念! 都是非常重要的管理行为!
在管理权限时,操作者可以借由 id 这个指令查找用户所加入的次要群组支持,借以了解用户对于某个文件的权限。 而主要的文件记录其实是用户的 UID 与 GID。
系统记录用户 UID 与 GID 的文件主要在:
针对 UID 的部份,在 CentOS 7.x 以后,系统管理员、系统帐号与一般帐号的 UID 范围为:
id 范围 | 该 ID 用户特性 |
0 (系统管理员) | 当 UID 是 0 时,代表这个帐号是『系统管理员』! |
1~999 (系统帐号) | 保留给系统使用的 ID,其实除了 0 之外,其他的 UID 权限与特性并没有不一样。缺省 1000
以下的数字让给系统作为保留帐号只是一个习惯。根据系统帐号的由来,通常这类帐号又约略被区分为两种:
|
1000~60000 (可登录帐号) | 给一般用户用的。事实上,目前的 linux 内核 (3.10.x 版)已经可以支持到 4294967295 (2^32-1) 这么大的 UID 号码 |
Linux 的帐号数据记录在 /etc/passwd 当中,这个文件的内容中,以冒号 (:) 为区隔,共有七个字段,每个字段的意义为:
更多的说明可以参考 man 5 passwd 的内容。早期用户加密过的密码记录在 /etc/passwd 第二个字段,但这个文件的权限是任何人均可读取, 因此,有心人士可以查阅到加密过的密码,再以暴力破解法就可能可以获取所有人的密码。因此,密码字段已经移动到另一个文件去, 这就是 /etc/shadow 的由来。 /etc/shadow 以冒号 (:) 分隔成 9 字段,各字段功能为:
用户的密码加密机制是可变的,从早期的 md5 到新的 sha512 改善了密码的数据长度,对于暴力破解法来说, 解密的时间会比较长。至于目前系统的加密机制可使用底下的方式查阅:
[root@localhost ~]# authconfig --test | grep password shadow passwords are enabled password hashing algorithm is sha512 [root@localhost ~]# cat /etc/sysconfig/authconfig | grep -i passwd PASSWDALGORITHM=sha512 USEPASSWDQC=no
用户的初始群组 (原生家庭) 记载在 /etc/passwd 文件的第四个字段,不过该 GID 对应到人类认识的群组名称就得到 /etc/group 当中查找。 这个文件的内容同样使用冒号 (:) 分隔成四个字段,内容为:
这三个文件中心以 /etc/passwd 为主,链接到 /etc/group 与 /etc/shadow 的示意图如下:
从上述数据我们可以知道,Linux 的帐号信息大概都记录在 /etc/passwd, /etc/shadow, /etc/group 当中,那如果我们要新建帐号时, 系统会怎么做呢?先测试建置帐号:
[root@local ~]# useradd testuser1 [root@local ~]# passwd testuser1 Changing password for user testuser1. New password: Retype new password: passwd: all authentication tokens updated successfully.
让我们观察一下 testuser 这个帐号的相关数据,先看一下用户的 UID 与 GID:
[root@local ~]# id testuser1 uid=1002(testuser1) gid=1002(testuser1) groups=1002(testuser1) [root@local ~]# grep testuser1 /etc/passwd /etc/group /etc/shadow /etc/passwd:testuser1:x:1002:1002::/home/testuser1:/bin/bash /etc/group:testuser1:x:1002: /etc/shadow:testuser1:$6$bgAJnRxx$lvgO10GAMg1aoHSzm/cR.GcW..:16924:0:99999:7:::
上述 shadow 的数据可以简易的使用如下的指令来查找:
[root@localhost ~]# chage -l testuser1
Last password change : May 03, 2016
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
一般来说,新建帐号时,系统会:
至于新建用户时,上述的动作参考数据其实是参考 /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 <==用户缺省邮件信箱放置目录 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 这一个机制!
一般来说,除非有特殊的需求,例如需要创建的是云端集中帐号管理,所以需要修改上述的设置档数据 (/etc/default/useradd, /etc/login.defs),否则尽量使用自订的手动修改用户相关参数,不要随意更动上述的文件内容。
若需要删除帐号,使用 userdel 即可。不过需要加上 -r 的选项较佳!如果忘记加上 -r 的选项时,你应该要这样做:
[root@localhost ~]# userdel testuser1 [root@localhost ~]# ll -d /home/testuser1 /var/spool/mail/testuser1 drwx------. 3 1002 1002 74 May 3 18:26 /home/testuser1 -rw-rw----. 1 1002 mail 0 May 3 18:26 /var/spool/mail/testuser1 [root@localhost ~]# find / -nouser /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
如上所示,系统会有一堆暂存数据需要删除,因此管理员可能需要使用 rm -rf /home/testuser1 /var/spool/mail/testuser1 来删除掉这些没主人的文件。
我们知道 id 可以找出用户 UID 与 GID,但是 id 只能接一个参数而已,若需要 /etc/passwd 内所有帐号的 UID 与 GID 列表呢? 除了使用管线命令的 xargs 之外,我们可以使用 shell script 的循环控制来处理。Bash shell script 的 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 # This script will show all users id # VBird 2016/05/03 users=$( cut -d ':' -f 1 /etc/passwd) for username in ${users} do id ${username} done [root@localhost bin]# chmod a+x allid.sh [root@localhost bin]# allid.sh uid=0(root) gid=0(root) groups=0(root) uid=1(bin) gid=1(bin) groups=1(bin) uid=2(daemon) gid=2(daemon) groups=2(daemon) .......
bash shell script 的循环控制主要是根据 for ... do ... done 来处理,所以也称为 for 循环。上述的脚本中:
用户在新建数据时,缺省的权限会是如何规范?一般来说,依据帐号的差异而会给予这样的设置:
这样的权限设计是考量一般用户可能会有同群组互相操作『同群组共享目录』的可能之故。但其实该缺省权限是可以修改的, 其主要的设置为 umask 所管理。
[student@localhost ~]$ umask 0002 [root@localhost ~]# umask 0022
分别使用 root 与 student 查阅 umask 时,其输出的结果并不相同。最简单的思考方向,umask 为拿掉不想要给予的缺省权限。 而四组分数中,第一个为特殊权限分数,不用理会,后续三个分数 (root为022而student为002) 即为一般权限设置的三种身份权限。
如果 linuxuser1 在新建目录时,希望同群组的用户可以一同完整操作文件,但是其他人则没有任何权限,该如何处理 umask 呢? 简单的处理流程为:
[root@localhost ~]# su - linuxuser1 [linuxuser1@localhost ~]$ umask 007 [linuxuser1@localhost ~]$ mkdir newdir [linuxuser1@localhost ~]$ touch newfile [linuxuser1@localhost ~]$ ll -d new* drwxrwx---. 2 linuxuser1 linuxuser1 6 May 3 23:54 newdir -rw-rw----. 1 linuxuser1 linuxuser1 0 May 3 23:54 newfil
若需要这样的设置永远存在,就写入 ~/.bashrc 当中即可。
任务一:关于新建用户的家目录与 bash 操作环境设置,未来所有系统新建的用户,在其家目录中:
解决方案很简单,因为只是修改未来新用户的数据而已,因此只要修订 /etc/skel 即可处理完毕!
[root@localhost ~]# cd /etc/skel [root@localhost skel]# mkdir bin [root@localhost skel]# vim .bashrc # User specific aliases and functions 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 /home/testuser2; tail -n 4 /home/testuser2/.bashrc drwxr-xr-x. 2 testuser2 testuser2 6 May 3 19:56 bin HISTFILESIZE=10000 alias cp="cp -i" alias mv="mv -i" alias rm="rm -i" [root@localhost skel]# userdel -r testuser2
建置完毕后我们使用 useradd 创建一个名为 testuser2 的帐号来查看一下是否有问题,若没有问题就可以删除该帐号了!
任务二:创建 mailuser1 ~ mailuser5 共五个帐号,这五个帐号需求:
上述第一点主要是 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:1006:1006::/home/mailuser1:/sbin/nologin mailuser2:x:1007:1007::/home/mailuser2:/sbin/nologin mailuser3:x:1008:1008::/home/mailuser3:/sbin/nologin mailuser4:x:1009:1009::/home/mailuser4:/sbin/nologin mailuser5:x:1010:1010::/home/mailuser5:/sbin/nologin
上述即可创建好专门给 mail user 专用的帐号了!而且这些帐号还无法登录系统操作 bash,这样系统较为安全!
任务三:由于软件的特殊需求,我们需要创建如下的帐号:
其实不难,只要两个指令即可结束!
[root@localhost ~]# useradd -u 399 -g users sysuser1 [root@localhost ~]# echo centos | passwd --stdin sysuser1 [root@localhost ~]# id sysuser1 uid=399(sysuser1) gid=100(users) groups=100(users)
建议读者们最终一定要自己检查看看是否正确才好!所以上述我们使用了 id 这个指令来查找是否正确!
任务四:同一项目人员的共享目录资源情况:
问题不难,读者应该会想到,之前处理权限数据时,就曾经玩过『共享目录』的信息,这里即是重新复习一次!
[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 目录里进行任何工作!
由于系统的工作比较复杂,经常有不同的用户会共同管理一部系统,这在社群的实务运作上经常发现。因为管理系统时需要管理员 (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 用户帐号 登录者的来源主机=(可切换的身份) 可下达的指令
大约在 98 行附近,读者会看到上面的 root 开头那行。由于仅有 root 这一行,亦即一开始仅有 root 可以运行 sudo 的意思。
除了单一个人的设置之外,在 /etc/sudoers 若有底下这一行,亦代表加入 wheel 群组的用户也能够操作 sudo 之意。
[root@localhost ~]# visudo
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL
如果 10.1 小节最后的一个练习中, /srv/projecta 需要让 student 这个帐号登录去『查看』数据而已,不能变更现有的权限设置, 此时该如何设计呢?这时就可以考虑 ACL (Access Control List, 访问控制列表) 的使用了!
ACL 是 Access Control List 的缩写,主要的目的是在提供传统的 owner,group,others 的 read,write,execute 权限之外的细部权限设置。ACL 可以针对单一用户,单一文件或目录来进行 r,w,x 的权限规范,对于需要特殊权限的使用状况非常有帮助。
ACL 主要可以针对几个项目来加以控制:
ACL 必须要配合文件系统的挂载启动才能生效,一般均将 acl 参数写入 /etc/fstab 的第四字段中。不过由于 ACL 几乎为目前 Linux 标准支持的文件系统参数, 因此读者仅须查找内核是否启动 ACL 即可,已无须将 acl 参数写入挂载设置中。
[root@localhost ~]# dmesg | grep -i acl [ 0.609488] systemd[1]: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN) [ 1.763620] SGI XFS with ACLs, security attributes, no debug enabled
ACL 针对单一用户的设置练习中,我们以『让 student 可以读取 /srv/projecta 』为范本来介绍。
[root@localhost ~]# ll -d /srv/projecta drwxrws---. 2 root project 6 May 3 21:43 /srv/projecta [root@localhost ~]# setfacl -m u:student:rx /srv/projecta [root@localhost ~]# ll -d /srv/projecta drwxrws---+ 2 root project 6 May 3 21:43 /srv/projecta [root@localhost ~]# getfacl /srv/projecta # file: srv/projecta # owner: root # group: project # flags: -s- user::rwx <==缺省的拥有者权限 user:student:r-x <==针对 student 的权限 group::rwx <==缺省的群组权限 mask::rwx <==缺省的 mask 权限 other::---
如上所示,setfacl -m 为设置的指令与选项,而设置的项目则主要有:
至于 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 4 00:37 newdir -rw-rw-r--. 1 pro1 project 0 May 4 00:37 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 33 May 4 00:37 /srv/projecta/
读者可以发现到,权限位置最末位的 + 号不见了,因为已经完整的取消的缘故。
前置动作:请使用 unit10 的硬盘进入作业环境,并请先以 root 身分运行 vbird_book_setup_ip 指令设置好你的学号与 IP 之后,再开始底下的作业练习。
请使用 root 的身份进行如下实做的任务。直接在系统上面操作,操作成功即可,上传结果的程序会主动找到你的实做结果。 另外,因为题目是有连续性的,请依照顺序完成题目,尽量不要跳着做。
作业结果传输:请以 root 的身分运行 vbird_book_check_unit 指令上传作业结果。 正常运行完毕的结果应会出现【XXXXXX;aa:bb:cc:dd:ee:ff;unitNN】字样。若需要查阅自己上传数据的时间, 请在操作系统上面使用: http://192.168.251.250 检查相对应的课程文件。