00:00/00:00

本章节已编写及校对完毕,现有奖征集建议、若您发现本章中有错别字或补充欢迎联系刘遄老师QQ:5604241。

章节简述:

Linux系统具有多用户、多任务的历史发展特点,所以也迫使其具有了很好的安全性,保障Linux系统安全的背后是复杂的配置工作,本章节中刘遄老师将为您详细讲述Linux系统中文件的所有者所有组以及其他人所对应的读(r)写(w)执行(x)的一般权限的作用,会添加、删除、修改用户帐户信息。咱们还可以使用SUID、SGID与SBIT特殊权限位让系统权限功能更加的灵活,弥补单纯对文件设置一般权限的功能不足。隐藏权限能够让系统多一层隐形的防护层,让黑客对关键日志信息最多只能看,而不能修改或删除。通过ACL访问控制列表再进一步的针对单一用户、用户组对单一文件或目录进行特殊的权限安排,让文件的权限最大限度满足工作的需求。最后还将学习到使用su命令与sudo服务来让普通用户既能够使用到超级管理员的权限来满足日常的工作需求还兼顾系统的安全性,最佳搭配方案。

5.1 用户身份与能力

咱们前面提到过Linux系统的设计初衷之一就是为了满足让多用户同时工作的需求,因此也就迫使Linux系统必须具备很好的安全性,在第1章安装红帽RHEL7操作系统时特别要求设置root用户密码,这个所说的root用户就是存在于所有类UNIX系统中的超级用户。它拥有最高的系统所有权,能够管理系统的各项功能,如添加/删除用户启动/关闭服务进程开启/禁用硬件设备等权限。虽然使用root用户工作时不会受到系统的种种限制,但老话讲能力越大,责任就越大,一旦使用这个高能的root用户执行了错误的命令也有可能会直接毁掉整个系统,真得好好权衡下啊。

面对学习时是否要使用root管理员身份来控制系统这个问题,网络文章中普遍会推荐同学们使用普通用户来操作,这无疑是更加安全,也更“无责任”的回答。但今天刘遄老师就要冒天下之大不韪讲下自己的心得——学习时强烈推荐使用root超级用户,是强烈推荐!这种不模棱两可的为root管理员用户正名应该还是在网络中还是很少见的吧,而我力荐的原因其实很简单,第一点是因为同学们在学习过程中如果使用的是普通用户身份,那么当配置服务后出现错误则很难判断是系统的问题还是因为权限不足导致的,无疑会让学习过程增添很多不必要的坎坷。第二点是因为咱们的实验环境统一Vmware虚拟机软件,可以把安装好的系统设置成一次快照,这样即便是系统彻彻底底的崩溃了,您也能够在5秒内就快速还原成一台全新的系统,不用担心数据丢失。总之刘遄老师的每个学生在学习期间都会被推荐使用root超级身份来学习,而到了工作的时候则根据生产环境再决定使用谁即可,这些都不是技术性问题。

另外很多书籍或老师总会告诉您在Linux系统中的超级用户就是root,但其实这是错误的。因为Linux系统的超级用户之所以是root,并不是因为它的名字叫root,而是因为该用户身份号码——即UID(User IDentification)的数值为0,在Linux系统中的UID就相当于人类社会中的身份证号码一样权威、唯一性,因此Linux系统是通过用户的UID的值来判断用户身份,RHEL7系统中的用户身份包括有:

超级用户UID0:系统的超级用户。

系统用户UID1-999:系统中程序服务由不同用户运行,更加安全,默认被限制不能登录系统。

普通用户UID1000~:即管理员创建的用于日常工作而不能管理系统的普通用户。

注意UID一定是不能冲突的,管理员创建的普通用户UID从1000开始(即便前面有闲置的号码)

为了方便管理同一组的用户还有个叫做用户组的概念,用户组号码——即GID(Group IDentification),使得咱们可以把多个用户加入到同一个组中,方便统一规划权限或任务,想象公司中有多个部门,而每个部门中又有很多同事,那么如果只想让员工获取到本部门内的共享资源,则就可以针对部门设置权限,而非针对于某个人,例如只有属于技术部分组的人才可以访问公司的数据库信息等等。另外在Linux系统中每个用户在建立时也会自动创建一个与其同名的基本用户组,这个基本用户组只有该用户一个人,而该用户以后被归纳入的用户组则叫做扩展用户组,因此一个用户只有一个基本用户组,而可以有多个扩展用户组,来满足日常的工作需要。

useradd命令用于创建新的用户,格式为:“useradd [选项]  用户名”。

可以使用这个命令来创建用户帐号,默认的用户家目录会被存放在/home目录中,默认的Shell解释器会是/bin/bash,默认会创建一个与该用户同名的基本用户组以及默认该用户不包含其他的扩展用户组,这些默认值可以依据下面useradd命令的参数来自行修改:

参数 作用
-d 指定用户的家目录(默认为/home/username)
-e 帐号有效截至日期,格式:YYYY-MM-DD.
-u 指定该用户的默认UID
-g 指定一个初始的用户基本组(必须已存在)
-G 指定一个或多个扩展用户组
-N 不创建与用户同名的基本用户组
-s 指定该用户的默认Shell

创建一个普通用户并指定家目录路径、UID用户身份号码以及Shell解释器,其中/sbin/nologin是终端解释器的其中一员,它与bash解释器有着天壤之别,因为一旦用户的解释器被设置成了nologin,那么则代表该用户不能够登录到系统

[root@linuxprobe ~]# useradd -d /home/linux -u 8888 -s /sbin/nologin linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=8888(linuxprobe) gid=8888(linuxprobe) groups=8888(linuxprobe)

groupadd命令用于创建群组,格式为:"groupadd [选项] 群组名"。

为了能够让系统中各个用户的权限指派更加的有效率,工作中常常会把几个用户组设置成某个用户的扩展用户组,这样的话就可以针对于一类用户进行统一的权限安排了,而这个步骤非常的简单,例如创建一个名字叫做ronny的用户组:

[root@linuxprobe ~]# groupadd ronny

usermod命令用于修改用户的属性,格式为“usermod [选项] 用户名”。

在Linux系统中的一切都是文件,因此在系统中创建用户也是修改配置文件的过程,用户的信息被保存到了/etc/passwd文件中,可以直接用文本编辑器来修改其中的数值项目,也可以用usermod命令来修改已经创建的用户信息项目,诸如用户身份号码、基本/扩展用户组、默认终端等等:

参数 作用
-c 填写帐号的备注信息
-d -m -m与-d连用,可重新指定用户的家目录并自动把旧的数据转移过去。
-e 帐户到期时间,格式“YYYY-MM-DD”
-g 变更所属用户组
-G 变更扩展用户组
-L 锁定用户禁止其登陆系统
-U 解锁用户,允许其登陆系统
-s 变更默认终端
-u 修改用户的UID

不要被这么多参数吓坏啦~先来看下某个帐户的默认信息:

[root@linuxprobe ~]# id linuxprobe
uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe)

刘遄老师来逐一为您演示下如何为用户增添到一个额外的扩展用户组中,以及修改该用户的身份号码:

[root@linuxprobe ~]# usermod -G root linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
[root@linuxprobe ~]# usermod -u 8888 linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=8888(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)

passwd命令用于修改用户的密码,格式为:“passwd [选项] [用户名]”。

该命令用于修改用户的密码、过期时间、认证信息等,普通的用户只有权限修改自身的系统密码,而超级用户则有权限来修改其他所有人的密码。更酷的是Linux系统中root管理员修改自己或他人的密码是不需要验证旧密码的,这点特别的方便。既然root用户都有权限修改或登录了该用户,就代表已经对该用户有完全的管理权限了,因此尝试修改该用户密码时不再重复要求验证旧密码其实也并不存在安全隐患:

参数 作用
-l 锁定用户禁止其登陆
-u 解除锁定,允许用户登陆。
--stdin 允许从标准输入修改用户密码,如(echo "NewPassWord" | passwd --stdin Username)
-d 使帐号无密码
-e 强制用户下次登陆时修改密码
-S 显示用户的密码状态

接下来刘遄老师来为您依次演示下如何修改用户自己的密码,以及如何修改其他人的密码(该动作仅限root管理员用户可使用):

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

当有个同事请了长假时,还可以用这个命令来禁止或允许某个用户登录到本系统,而不是删除该用户,这样既保证了这段时间内系统的安全,也避免频繁添加、删除用户带来的麻烦:

[root@linuxprobe ~]# passwd -l linuxprobe
Locking password for user linuxprobe.
passwd: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe LK 2017-12-26 0 99999 7 -1 (Password locked.)
[root@linuxprobe ~]# passwd -u linuxprobe
Unlocking password for user linuxprobe.
passwd: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe PS 2017-12-26 0 99999 7 -1 (Password set, SHA512 crypt.)

userdel命令用于删除用户,格式为:“userdel [选项] 用户名”。

如果咱们确认以后不需要再让某个用户登录到本地系统中,则可以通过userdel命令来删除有关该用户的所有信息,默认该用户的家目录数据会被保留下来,而如果想要一起删除的话可以加上-r参数即可:

参数 作用
-f 强制删除用户
-r 同时删除用户,家目录与其相关文件

[root@linuxprobe ~]# id linuxprobe
uid=8888(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
[root@linuxprobe ~]# userdel -r linuxprobe
[root@linuxprobe ~]# id linuxprobe
id: linuxprobe: no such user
5.2 文件权限与归属

Linux系统中的一切都是文件,但每个文件的类型不尽相同,并且Linux系统会用不同的符号来加以区分,常见的包括有

-:普通文件,d:目录文件,l:链接文件,b:块设备文件,c:字符设备文件,p:管道文件

每个文件都有其相对应的所有者和所有组,还有分别规定对所有者、所有组和其他人的可读、可写、可执行的权限。对于一般文件来讲的权限比较好理解,可读权限就是能够读取该文件的实际内容,可写权限就是能够编辑、新增、修改文件的实际内容,可执行则代表能够运行一个脚本程序的权限。但对于目录文件的权限设置就不太好掌握了,很多考下RHCA红帽认证架构师的“高手”其实也一直没有搞明白过,首先对于目录文件的可读权限就是能够读取该目录内的结构和文件列表,可写权限就是能够更改目录内文件结构列表、新增、删除、重命名文件,而可执行实质是代表进入该目录的权限。

读(read),写(write),执行(execute)简写即为(r,w,x),亦可用数字(4,2,1)表示,如下表:

权限值

数字法是基于rwx的权限计算而来,主要是为了简化权限的表示信息。举例来说若某个文件的权限为7则代表可读,可写,可执行(4+2+1),若权限为6则代表可读,可写(4+2)。因此例如说一个文件可以让所有者可读可写也可执行,对于文件的所属组来讲可读可写,而除了所有者和所有组以外的其他人则只有可读的权限,那么权限就是rwxrw-r--,数字法表示即为764,不过千万别给老师算出来7+6+4=17,这是小学的数学加减法,不是Linux系统的权限数字法,三组之间没有相通关系。

Linux系统的权限复杂而又广泛,同学们千万不要为了看书而看书,必须把这项权限搞清楚再进行下一小节,请您拿出一张草稿纸来计算下764、642、153、731所对应的rwx权限法表示法,再分别把rwxrw-r--、rw--w--wx、rw-r--r--转换成数字法表示法,不要偷懒呦~最后根据上面对文件所属和权限的学习经验,咱们来一起分析下如图片5-1所示的文件信息吧:

文件权限

图5-1 通过ls命令查看到的文件属性信息

图中所示包括有文件的类型、访问权限、所属者(属主)、所有组(属组)、占用大小、修改时间和文件名称等信息。通过分析可得知该文件类型为一般文件,所有者权限为可读可写(rw-),所有组权限为可读(r--),除此以外的其他人也只有可读权限(r--),文件的磁盘占用大小是34298字节,最近一次的修改时间为4月2日的凌晨23分,文件的名称为install.log。

5.3 文件的特殊权限

在复杂多变的生产环境中,单纯对文件设置rwx权限肯定不能满足咱们对安全、便捷工作的需求,因此便有了SUID、SGID与SBIT的特殊权限机制。特殊权限位是针对于文件设置的一种特殊的功能,而且与一般权限可同时出现使用,用于弥补一般权限不能实现的功能。

SUID:让执行者临时拥有属主的权限仅对拥有执行权限的二进制程序有效

这是一种针对于二进制程序设置的特殊权限,例如所有用户都可以执行用于修改用户密码的passwd命令,而用户密码是被保存在/etc/shadow文件中的,但只要仔细的看下就会发现这个文件的默认权限是000,也就是说除了不受系统限制的root管理员用户以外的所有用户都没有查看或编辑该文件的权限。那么把passwd命令加上SUID特殊权限位,便可让普通用户临时获得程序所有者的身份,即以root用户的身份把变更的密码信息写入到shadow文件中。这个很像在古装剧中看过拿着尚方宝剑的钦差大臣,他手持尚方宝剑惩治贪官的时候实际上也就代表了皇上的权威,以便他完成了想要的效果,但这并不意味着他就永远成为了皇上,因此这是一种有条件的、临时的特殊权限授权方法。

[root@linuxprobe ~]# ls -l /etc/shadow
----------. 1 root root 1004 Jan 3 06:23 /etc/shadow
[root@linuxprobe ~]# ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 Jan 29 2017 /bin/passwd

SGID功能一:让执行者临时拥有属组的权限对拥有执行权限的二进制程序设置

这种特殊权限就是参考SUID而设计的,不同点就是让程序的执行者获取的不再是文件所有者的临时权限,而是获取到文件的所有组的权限。举例来说,在早期的Linux系统中/dev/kmem是一个字符设备文件,用于存储内核程序要访问的数据,权限为:

cr--r-----   1 root system 2,  1 Feb 11 2017  kmem

读者们看出问题了吗?除了root超级用户身份属于system组成员外的所有用户都没有读取该文件的权限,但平时咱们需要查看系统进程状态,为了让用户能够获取到系统状态信息,因此将用于查看系统进程状态的ps命令权限上增加了SGID特殊权限位:

-r-xr-sr-x   1 bin system 59346 Feb 11 2017  ps

这样的话因为ps命令被赋予了SGID特殊权限位,所以当用户执行了该命令,实际上临时获取到了有效用户组system的权限啦,能够顺利的读取设备文件啦~

SGID功能二:在该目录中创建的文件自动继承此目录的用户组(只可以对目录设置

正如前面提到过每个文件都有其归属的所有者和所有组,而当创建或传送一个文件后,这个文件就会自动的归属于执行这个操作的用户。那么比如工作中需要设置一个部门内的共享目录,让所有组内的人都能够读取里面的内容,那么咱们就可以创建部门共享目录后,把该目录设置上SGID特殊权限位,这样任何用户在里面创建的任何文件都会归属于本目录的所有组,而不再是自己的基本用户组。

[root@linuxprobe ~]# cd /tmp
[root@linuxprobe tmp]# mkdir testdir
[root@linuxprobe tmp]# ls -ald testdir/
drwxr-xr-x. 2 root root 6 Feb 11 11:50 testdir/
[root@linuxprobe tmp]# chmod -Rf 777 testdir/
[root@linuxprobe tmp]# chmod -Rf g+s testdir/
[root@linuxprobe tmp]# ls -ald testdir/
drwxrwsrwx. 2 root root 6 Feb 11 11:50 testdir/

这样设置好777权限以保证普通用户可以写入文件,并为该目录设置了SGID特殊权限位后,就可以切换至一个普通用户尝试在该目录创建文件,看看新建出来的文件是否会继承上级目录的所有组名称:

[root@linuxprobe tmp]# su - linuxprobe
Last login: Wed Feb 11 11:49:16 CST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ cd /tmp/testdir/
[linuxprobe@linuxprobe testdir]$ echo "linuxprobe.com" > test
[linuxprobe@linuxprobe testdir]$ ls -al test
-rw-rw-r--. 1 linuxprobe root 15 Feb 11 11:50 test

chmod命令用于修改文件或目录的权限,格式为:"chmod [参数] 权限 文件或目录名称"。

这是一个非常实用的命令,能够用来设置文件或目录的权限,例如想要把一个文件的权限设置成所有者都可以可读写执行、所有组可读写而其他人没有任何权限,这样对应起来就是rwxrw----,用数字法来设置也就是760啦,于是通过前面的基础学习到当前实践操作,同学们马上就能感受到了数字法设置权限的便捷性了吧~

[root@linuxprobe ~]# ls -al test
-rw-rw-r--. 1 linuxprobe root 15 Feb 11 11:50 test
[root@linuxprobe ~]# chmod 760 test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test

chown命令用于修改文件或目录的所属主与所属组,格式为:“chown [参数] 所属主:所属组 文件或目录名称”。

除了修改文件的权限外,还可以使用chown命令来设置文件的所有者和所有组。chmod和chown命令是对文件属性和权限修改最常用的命令,它们还有一个特别的共性,就是对于目录文件时需要加上大写参数-R来表示递归操作,即对目录内所有的文件进行整体操作的意思。

[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test
[root@linuxprobe ~]# chown root:bin test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 root bin 15 Feb 11 11:50 test

SBIT(Sticky Bit):只可管理自己的数据而不能删除他人文件(仅对目录有效)

很多大学老师要求学生下课后统一把作业上传到服务器的特定共享目录中,但老是有几个小破坏分子喜欢删除其他同学的作业那就要设置SBIT特殊权限位了,当然也可以叫做特殊权限位之粘滞位。SBIT特殊权限位的设置目的和效果是不让其他人删除自己的文件,换句话说就是文件只能被所有者执行删除操作,不知道最初是那个呆瓜直接把英文Sticky Bit直译成了粘滞位,刘遄老师则推荐叫做保护位,既好记,又能让别人马上知道其功能作用。在RHEL7系统中的/tmp作为一个共享文件的目录默认已经被设置了SBIT特殊权限位,因此这里面的文件其他人是不能乱删除的:

[root@linuxprobe tmp]# su - linuxprobe
Last login: Wed Feb 11 12:41:20 CST 2017 on pts/0
[linuxprobe@linuxprobe tmp]$ ls -ald /tmp
drwxrwxrwt. 17 root root 4096 Feb 11 13:03 /tmp
[linuxprobe@linuxprobe ~]$ cd /tmp
[linuxprobe@linuxprobe tmp]$ ls -ald
drwxrwxrwt. 17 root root 4096 Feb 11 13:03 .
[linuxprobe@linuxprobe tmp]$ echo "Welcome to linuxprobe.com" > test
[linuxprobe@linuxprobe tmp]$ chmod 777 test
[linuxprobe@linuxprobe tmp]$ ls -al test 
-rwxrwxrwx. 1 linuxprobe linuxprobe 10 Feb 11 12:59 test

其实文件能否被删除并不取决于自身的权限大小,而是看上级目录是否有写入权限,这个是前面提到过的,但为了避免很多同学不放心,所以还是赋予了这个文件最大的777权限(rwxrwxrwx)。切换到另外一个普通用户然后尝试删除这个别人的文件就会发现,即便权限十分的充足,但是由于SBIT特殊权限位的缘故依然导致了无法删除其他人的文件:

[root@linuxprobe tmp]# su - blackshield
Last login: Wed Feb 11 12:41:29 CST 2017 on pts/1
[blackshield@linuxprobe ~]$ cd /tmp
[blackshield@linuxprobe tmp]$ rm -f test
rm: cannot remove ‘test’: Operation not permitted
5.4 文件的隐藏属性

在Linux系统中除了能对文件设置一般权限和特殊权限外还有一种叫做隐藏权限的功能,顾名思义就是被隐藏起来的权限,即在默认情况下是不能直接被用户发觉的。在真实的工作环境和红帽RHCE考试题目中碰到过明明权限很充足但却不能删除某个文件的情况,或者仅仅能对日志文件进行追加内容而不能删除或减少,一定程度上阻止了黑客篡改系统日志的图谋,因此这种很“奇怪”的文件让Linux系统更加的安全。

chattr命令用于设置文件的隐藏权限,格式为:“chattr [参数] 文件”。

可以使用chattr命令来设置文件的隐藏权限,如果想要把某个隐藏功能添加到文件上面,则使用+参数,如果想要把某个隐藏功能移出文件,则使用-参数。可供咱们选择的隐藏权限功能非常丰富,常见的隐藏权限包括有:

参数 作用
i 将无法对文件进行修改,若对目录设置后则仅能修改子文件而不能新建或删除。
a 仅允许补充(追加)内容.无法覆盖/删除(Append Only)。
S 文件内容变更后立即同步到硬盘(sync)。
s 彻底从硬盘中删除,不可恢复(用0填充原文件所在硬盘区域)。
A 不再修改这个文件的最后访问时间(atime)。
b 不再修改文件或目录的存取时间。
D 检查压缩文件中的错误。
d 当使用dump命令备份时忽略本文件/目录。
c 默认将文件或目录进行压缩。
u 当删除此文件后依然保留其在硬盘中的数据,方便日后恢复。
t 让文件系统支持尾部合并(tail-merging)。
X 可以直接访问压缩文件的内容。

为了能更好的见识到隐藏权限的效果,先来创建一个普通文件后立即尝试删除,这个肯定是毫无悬念会成功的:

[root@linuxprobe ~]# echo "for Test" > linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y

实践是检验真理的唯一标准,如果没有亲眼见见隐藏权限强大功能的美妙,就一定不会相信原来Linux系统会如此的安全且复杂。当咱们再次新建了一个普通文件并设置了不允许删除与覆盖(+a参数)权限后的效果:

[root@linuxprobe ~]# echo "for Test" > linuxprobe
[root@linuxprobe ~]# chattr +a linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y
rm: cannot remove ‘linuxprobe’: Operation not permitted

lsattr命令用于显示文件的隐藏权限,格式为:“lsattr [参数] 文件”。

对于Linux系统中的隐藏权限必须用lsattr命令才能够看到,平时使用的ls之类的命令是看不出异样的:

[root@linuxprobe ~]# ls -al linuxprobe
-rw-r--r--. 1 root root 9 Feb 12 11:42 linuxprobe

一旦使用了lsattr命令后文件上被赋予的隐藏权限就会马上原形毕露出来,只需要按照提示的隐藏权限的类型(字母)来使用chattr命令去掉即可:

[root@linuxprobe ~]# lsattr linuxprobe
-----a---------- linuxprobe
[root@linuxprobe ~]# chattr -a linuxprobe
[root@linuxprobe ~]# lsattr linuxprobe 
---------------- linuxprobe
[root@linuxprobe ~]# rm linuxprobe 
rm: remove regular file ‘linuxprobe’? y

出现问题?大胆提问!

因读者们硬件不同或操作错误都可能导致实验配置出错,请耐心再仔细看看操作步骤吧,不要气馁~

Linux技术交流请加A群:560843(),B群:340829(推荐),C群:463590(推荐),点此查看全国群

*本群特色:通过口令验证确保每一个群员都是《Linux就该这么学》的读者,答疑更有针对性,不定期免费领取定制礼品。

5.5 文件访问控制列表

不知同学们有没有发现其实上面讲到的一般权限特殊权限隐藏权限其实有个共性——权限是针对某一类用户设置的。而如果希望对某个指定的用户进行单独的权限控制,那么就需要用文件的访问控制列表来实现啦。基于普通文件或目录设置ACL访问控制策略,通俗来说就是设置指定的特定用户或用户组对某个文件的操作权限。另外如果对某个目录设置了访问控制策略,那么子文件则继承其访问策略,而若对文件设置了访问控制策略则不再继承上级目录的控制策略。

为了更直观的看到ACL访问控制列表对文件权限控制的强大效果,因此先切换到普通用户后尝试进入到root超级用户的家目录中:

[root@linuxprobe ~]# su - linuxprobe
Last login: Sat Mar 21 16:31:19 CST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ cd /root
-bash: cd: /root: Permission denied
[linuxprobe@linuxprobe root]$ exit

setfacl命令用于增加或者修改ACL规则,格式为:"setfacl [参数] 文件名称"。

ACL提供的是在所有者、所有组、其他人的读写执行权限外的特殊权限控制,使用setfacl命令可以让咱们能够针对单一用户或用户组、单一文件或目录来进行读写执行权限的控制,其中对于目录文件需要使用递归-R参数,对普通文件需要使用-m参数,而如果想要删除某个文件的访问控制策略的话可以使用-b参数,于是快来设置下用户在/root目录上面的权限吧:

[root@linuxprobe ~]# setfacl -Rm u:linuxprobe:rwx /root
[root@linuxprobe ~]# su - linuxprobe
Last login: Sat Mar 21 15:45:03 CST 2017 on pts/1
[linuxprobe@linuxprobe ~]$ cd /root
[linuxprobe@linuxprobe root]$ ls
anaconda-ks.cfg Downloads Pictures Public
[linuxprobe@linuxprobe root]$ cat anaconda-ks.cfg
[linuxprobe@linuxprobe root]$ exit

是不是觉得效果很酷呢?但是又遇到了一个小问题——怎么样去查看文件上面有那些ACL策略呢?常用的ls命令是看不到访问控制列表信息的,但是却可以看到文件的权限最后一个点(.)变成了加号(+),而这就意味着这个文件已经被设置有了ACL访问策略啦。现在是不是感觉学得越多,越不敢说自己精通于Linux系统了呢?这么一个不起眼的点(.)竟然还意味着这么一种重要的权限呢。

[root@linuxprobe ~]# ls -ld /root
dr-xrwx---+ 14 root root 4096 May 4 2017 /root

getfacl命令用于显示文件的ACL规则,格式为:"getfacl 文件名称"。

在Linux系统中的命令就是这么又可爱又好记,想要设置ACL访问策略的话就是setfacl命令,而查看ACL访问策略的话就是getfacl命令。使用getfacl命令能够显示出在文件上设置的所有访问策略规则信息。

[root@linuxprobe ~]# getfacl /root
getfacl: Removing leading '/' from absolute path names
# file: root
# owner: root
# group: root
user::r-x
user:linuxprobe:rwx
group::r-x
mask::rwx
other::---

出现问题?大胆提问!

因读者们硬件不同或操作错误都可能导致实验配置出错,请耐心再仔细看看操作步骤吧,不要气馁~

Linux技术交流请加A群:560843(),B群:340829(推荐),C群:463590(推荐),点此查看全国群

*本群特色:通过口令验证确保每一个群员都是《Linux就该这么学》的读者,答疑更有针对性,不定期免费领取定制礼品。

5.6 su命令与sudo服务

虽然咱们的学员在实验环境中很少碰到安全问题,并且为了避免因为权限因素导致配置服务失败而推荐您使用root超级用户身份来配合本书来学习,但是在真正的工作生产环境中还是要对安全多一份敬畏之心,不要用root超级用户身份去做一切的事情,因为一旦执行了错误命令后可能会直接导致系统崩溃,没准还会被领导痛批一顿。但转头一想,Linux系统中有许多的系统命令和服务为了安全性考虑,因此只有root超级用户才可以去使用,这无疑让普通用户受到了更多的权限束缚,有时也就没法顺利完成工作任务了。su命令便是为了解决切换用户身份的需求而设计的功能,使用su命令可以让使用者在不注销的情况下顺畅的切换至其他用户,例如从root超级用户切换至普通用户:

[root@linuxprobe ~]# id 
uid=0(root) gid=0(root) groups=0(root)
[root@linuxprobe ~]# su - linuxprobe
Last login: Wed Jan 4 01:17:25 EST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ id 
uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

细心的同学一定会发现上面的su命令与用户名之间有一个减号(-),这意味着完全的切换到新的用户,即把环境变量信息也变更为新的用户,而不保留原始的用户信息,这个是推荐必加的参数,一定要记下哦~另外当超级用户切换到普通用户时是不需要密码验证的,而普通用户切换成超级用户身份就需要密码验证后才能成功了,这是一个必要的安全检查:

[linuxprobe@linuxprobe root]$ su root
Password:
[root@linuxprobe ~]# su - linuxprobe
Last login: Mon Aug 24 19:27:09 CST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ exit
logout
[root@linuxprobe ~]#

虽说像上面使用su命令允许普通用户完全变更为root用户身份来完成工作,但这也无疑会暴露了root超级管理员的密码,使得系统密码被黑客获取的几率也大大提高了,这似乎并不是最安全的方案。因此刘遄老师决定教给同学们使用sudo程序来把特定命令的执行权限赋予给指定的用户,这样既可保证了正常工作的同时也避免了泄露root超级用户密码,平时只要合理的配置sudo服务便可以合理的兼顾系统的安全性和用户便捷性,配置的原则也很简单——在保证普通用户完成工作的前提下,尽可能少的给予额外的权限,总结来说sudo服务程序的特色功能有:

1:限制用户执行指定的命令。

2:记录用户执行的每一条命令。

3:配置文件(/etc/sudoers)提供集中的管理用户、权限与主机等参数。

4:验证过密码后5分钟(默认值)内无须再让用户验证密码,更加的方便。

sudo服务用于给普通用户提供额外权利来完成原本超级用户才能完成的任务,格式为:“sudo [参数] 命令名称”。

参数 作用
-h 列出帮助信息。
-l 列出当前用户可执行的命令。
-u 用户名或UID值 以指定的用户身份执行命令。
-k 清空安全时间,下次执行sudo时需要再次密码验证。
-b 在后台执行指定的命令。
-p 更改询问密码的提示语。

当然如果感觉直接修改配置文件不太放心,担心出现问题的话还可以使用sudo服务提供的visudo命令来配置用户权限,这条命令在配置用户权限时可以避免多个用户同时修改配置文件,以及对配置文件内的参数进行语法检查,在发现错误参数时会直接提示并报错。

只用超级用户才可以使用visudo命令编辑sudo程序的配置文件(/etc/sudoers),平时还可以使用visudo命令来配置用户权限吧,这样既能防止多个用户同时修改配置文件,还能对配置文件内的参数进行语法检查,对于错误的参数会直接提示并报错:

visudo: >>> /etc/sudoers: syntax error near line 111 <<<

What now?

Options are:

(e)dit sudoers file again

(x)it without saving changes to sudoers file

(Q)uit and save changes to sudoers file (DANGER!)

使用visudo命令配置sudo服务的服务文件时,操作的方法与咱们学习过的vim编辑器是一致的,因此在编写完成后记得在末行模式下保存并退出。sudo服务程序配置文件中约第99行按照下面的格式填写上指定的信息即可:

谁可以使用超级用户身份     允许使用sudo命令的主机=(以谁的身份执行命令)     可执行命令的列表

[root@linuxprobe ~]# visudo
 96 ##
 97 ## Allow root to run any commands anywhere
 98 root ALL=(ALL) ALL
 99 linuxprobe ALL=(ALL) ALL

这样填写后记得要保存后再退出,然后切换至指定的用户身份就可以用sudo -l命令查看到所有可执行的命令啦(此处验证的是该普通用户的密码,而不是root用户的密码,同学们不要搞混喽):

[root@linuxprobe ~]# su - linuxprobe
Last login: Thu Sep 3 15:12:57 CST 2017 on pts/1
[linuxprobe@linuxprobe ~]$ sudo -l
[sudo] password for linuxprobe:
Matching Defaults entries for linuxprobe on this host:
requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS
DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1
PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY
LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL
LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User linuxprobe may run the following commands on this host:
(ALL) ALL

接下来就是见证奇迹的时刻,因为作为一名普通用户是肯定不能查看到root超级用户家目录(/root)中的文件信息的,但咱们只需要在想执行的命令前面加上sudo命令就变得有权限了:

[linuxprobe@linuxprobe ~]$ ls /root
ls: cannot open directory /root: Permission denied
[linuxprobe@linuxprobe ~]$ sudo ls /root
anaconda-ks.cfg Documents initial-setup-ks.cfg Pictures Templates
Desktop Downloads Music Public Videos

效果非常明显哦!但是考虑到真实的工作环境中肯定不能允许某个普通用户拥有了整个系统中所有命令的最高执行权,也不符合刚刚提到的权限赋予原则——在保证普通用户完成工作的前提下,尽可能少的给予额外的权限,因此ALL的参数就显得有些不合适了,应该代之以具体的命令来既让用户满足了工作需求,也能够受到必要的权限约束。如果需要让某个用户只能使用超级用户的身份执行指定的命令,切记一定要写上的是该命令的绝对路径,否则系统会识别不出来哦,咱们可以先用whereis命令找出命令所对应的保存路径,然后把刚刚配置文件中约第99行的用户权限参数修改成对应的路径即可:

[linuxprobe@linuxprobe ~]$ exit
logout
[root@linuxprobe ~]# whereis cat
cat: /usr/bin/cat /usr/share/man/man1/cat.1.gz /usr/share/man/man1p/cat.1p.gz
[root@linuxprobe ~]# visudo
 96 ##
 97 ## Allow root to run any commands anywhere
 98 root ALL=(ALL) ALL
 99 linuxprobe ALL=(ALL) /bin/cat

这样编辑好后依然是记得要保存退出,然后咱们再次切换到指定的普通用户上面,尝试正常查看某个文件的内容被提示没有权限,然后再用sudo命令后就可以顺利的查看文件内容啦:

[root@linuxprobe ~]# su - linuxprobe
Last login: Thu Sep 3 15:51:01 CST 2017 on pts/1
[linuxprobe@linuxprobe ~]$ cat /etc/shadow
cat: /etc/shadow: Permission denied
[linuxprobe@linuxprobe ~]$ sudo cat /etc/shadow
root:$6$GV3UVtX4ZGg6ygA6$J9pBuPGUSgZslj83jyoI7ThJla9ZAULku3BcncAYF00Uwk6Sqc4E36MnD1hLtlG9QadCpQCNVJs/5awHd0/pi1:16626:0:99999:7:::
bin:*:16141:0:99999:7:::
daemon:*:16141:0:99999:7:::
adm:*:16141:0:99999:7:::
lp:*:16141:0:99999:7:::
sync:*:16141:0:99999:7:::
shutdown:*:16141:0:99999:7:::
halt:*:16141:0:99999:7:::
mail:*:16141:0:99999:7:::
operator:*:16141:0:99999:7:::
games:*:16141:0:99999:7:::
ftp:*:16141:0:99999:7:::
nobody:*:16141:0:99999:7:::
………………省略部分文件内容………………

不要以为到这里就算结束了,刘遄老师还有更压箱底的宝贝,不知同学们有没有发觉到在每次执行sudo命令后都会被要求验证一下密码,虽然这个密码就是当前登录用户的密码,但这样每条命令都要输入一次密码其实也挺麻烦的,因此再添加NOPASSWD参数来使得用户执行sudo命令时不再需要密码验证啦:

[linuxprobe@linuxprobe ~]$ exit
logout
[root@linuxprobe ~]# whereis poweroff
poweroff: /usr/sbin/poweroff /usr/share/man/man8/poweroff.8.gz
[root@linuxprobe ~]# visudo
 96 ##
 97 ## Allow root to run any commands anywhere
 98 root ALL=(ALL) ALL
 99 linuxprobe ALL=NOPASSWD: /usr/sbin/poweroff

这样当咱们切换到普通用户后再执行命令时,就不用再频繁麻烦的要求验证密码了,在日常工作会一定会感觉到痛快极了~

[root@linuxprobe ~]# su - linuxprobe
Last login: Thu Sep 3 15:58:31 CST 2017 on pts/1
[linuxprobe@linuxprobe ~]$ poweroff
User root is logged in on seat0.
Please retry operation after closing inhibitors and logging out other users.
Alternatively, ignore inhibitors and users with 'systemctl poweroff -i'.
[linuxprobe@linuxprobe ~]$ sudo poweroff

本章节的复习作业(答案就在问题的下一行哦,用鼠标选中即可看到的~)

1:在红帽RHEL7系统中的超级管理员是谁?

答案:是UID为0的用户,默认是叫做root。

2:如何在Linux系统的命令行中添加或删除用户?

答案:添加和删除用户的命令分别是useradd与userdel。

3:若某个文件所有者可读写与执行,其余人仅有读权限,用数字法表示应该是什么?

答案:所有者权限为rwx,所有组和其他人的权限为r--,因此数字法应是744。

4:某链接文件权限为755,权限信息应写成什么?

答案:Linux系统中的文件有不同的类型,应注意写成lrwxr-xr-x。

5:希望用户执行某命令时临时拥有该命令所有者的权限,应该设置什么特殊权限?

答案:特殊权限中的SUID能够实现这个效果。

6:若对文件设置了隐藏权限+i,则意味着什么?

答案:将无法对文件进行修改,若对目录设置后则仅能修改子文件而不能新建或删除。

7:通过访问控制列表(ACL)限制linuxprobe用户组所有成员不得在/tmp目录中写入内容。

答案:想要设置用户组的ACL则需要把u改成g,即setfacl -Rm g:linuxprobe:r-x /tmp。

8:当普通用户使用sudo执行命令时是否需要验证密码?

答案:默认是需要验证当前登录用户的密码,若不想要验证可修改参数为NOPASSWD即可。