一、用户身份与能力
Linux用户有三类:
1.管理员 root
2.系统用户
3.普通用户
在Linux系统中,UID就相当于我们的身份证号码一样具有唯一性,因此可通过用户的UID值来判断用户身份。在RHEL 7系统中,用户身份有下面这些。
管理员UID为0:系统的管理员用户。
系统用户UID为1~999: Linux系统为了避免因某个服务程序出现漏洞而被黑客提权至整台服务器,默认服务程序会有独立的系统用户负责运行,进而有效控制被破坏范围。
普通用户UID从1000开始:是由管理员创建的用于日常工作的用户。
需要注意的是,UID是不能冲突的,而且管理员创建的普通用户的UID默认是从1000开始的(即使前面有闲置的号码)。
1. useradd命令
useradd命令用于创建新的用户,格式为“useradd [选项] 用户名”。
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)【扩展组】
2. groupadd命令
groupadd命令用于创建用户组,格式为“groupadd [选项] 群组名”。
为了能够更加高效地指派系统中各个用户的权限,在工作中常常会把几个用户加入到同一个组里面,这样便可以针对一类用户统一安排权限。创建用户组的步骤非常简单,例如使用如下命令创建一个用户组ronny:
[root@linuxprobe ~]# groupadd ronny
3. usermod命令
usermod命令用于修改用户的属性,格式为“usermod [选项] 用户名”。
用户的信息保存在/etc/passwd文件中,可以直接用文本编辑器来修改其中的用户参数项目,也可以用usermod命令修改已经创建的用户信息,诸如用户的UID、基本/扩展用户组、默认终端等。
usermod命令中的参数及作用
参数 | 作用 |
-c | 填写用户账户的备注信息 |
-d -m | 参数-m与参数-d连用,可重新指定用户的家目录并自动把旧的数据转移过去 |
-e | 账户的到期时间,格式为YYYY-MM-DD |
-g | 变更所属用户组 |
-G | 变更扩展用户组 |
-L | 锁定用户禁止其登录系统 |
-U | 解锁用户,允许其登录系统 |
-s | 变更默认终端 |
-u | 修改用户的UID |
我们先来看一下账户linuxprobe的默认信息:
[root@linuxprobe ~]# id linuxprobe uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe)
然后将用户linuxprobe加入到root用户组中,这样扩展组列表中则会出现root用户组的字样,而基本组不会受到影响:
[root@linuxprobe ~]# usermod -G root linuxprobe [root@linuxprobe ~]# id linuxprobe uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
再来试试用-u参数修改linuxprobe用户的UID号码值。除此之外,我们还可以用-g参数修改用户的基本组ID,用-G参数修改用户扩展组ID。
[root@linuxprobe ~]# usermod -u 8888 linuxprobe [root@linuxprobe ~]# id linuxprobe uid=8888(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
4. passwd命令
passwd命令用于修改用户密码、过期时间、认证信息等。普通用户只能使用passwd命令修改自身的系统密码,而root管理员则有权限修改其他所有人的密码。既然root管理员可以修改其他用户的密码,就表示完全拥有该用户的管理权限。
passwd命令中的参数以及作用
参数 | 作用 |
-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.
假设您有位同事正在度假,而且假期很长,那么可以使用passwd命令禁止该用户登录系统,等假期结束回归工作岗位时,再使用该命令允许用户登录系统,而不是将其删除。这样既保证了这段时间内系统的安全,也避免了频繁添加、删除用户带来的麻烦:
[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.)
5. userdel命令
userdel命令用于删除用户,格式为“userdel [选项] 用户名”。
如果我们确认某位用户后续不再会登录到系统中,则可以通过userdel命令删除该用户的所有信息。在执行删除操作时,该用户的家目录默认会保留下来,此时可以使用-r参数将其删除。userdel命令的参数以及作用如表5-4所示。
userdel命令的参数以及作用
参数 | 作用 |
-f | 强制删除用户 |
-r | 同时删除用户及用户家目录 |
下面使用userdel命令将linuxprobe用户删除,其操作如下:
[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
二、文件权限与归属
尽管在Linux系统中一切都是文件,但是每个文件的类型不尽相同,因此Linux系统使用了不同的字符来加以区分,常见的字符如下所示。
-:普通文件。
d:目录文件。(需要使用cd命令切换进去,是不能查看的)
l:链接文件。(只是一个链接文件,并不是真是存在)
b:块设备文件。(鼠标啊,光盘啊,键盘)
c:字符设备文件。(少见)
p:管道文件。(少见)
文件权限的字符与数字表示
目录文件的权限设置。对目录文件来说,“可读”表示能够读取目录内的文件列表;“可写”表示能够在目录内新增、删除、重命名文件;而“可执行”则表示能够进入该目录。例如,若某个文件的权限为7则代表可读、可写、可执行(4+2+1);若权限为6则代表可读、可写(4+2)。
三、文件的特殊权限
在复杂多变的生产环境中,单纯设置文件的rwx权限无法满足我们对安全和灵活性的需求,因此便有了SUID、SGID与SBIT的特殊权限位。这是一种对文件权限进行设置的特殊功能,可以与一般权限同时使用,以弥补一般权限不能实现的功能。
1. SUID
SUID是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限(仅对拥有执行权限的二进制程序有效)。例如,所有用户都可以执行passwd命令来修改自己的用户密码,而用户密码保存在/etc/shadow文件中。仔细查看这个文件就会发现它的默认权限是000,也就是说除了root管理员以外,所有用户都没有查看或编辑该文件的权限。但是,在使用passwd命令时如果加上SUID特殊权限位,就可让普通用户临时获得程序所有者的身份,把变更的密码信息写入到shadow文件中。
查看passwd命令属性时发现所有者的权限由rwx变成了rws,其中x改变成s就意味着该文件被赋予了SUID权限。另外大家可能会好奇,那么如果原本的权限是rw-呢?如果原先权限位上没有x执行权限,那么被赋予特殊权限后将变成大写的S。
[root@localhost ~]# ls -l /etc/shadow ----------. 1 root root 1163 3月 28 21:30 /etc/shadow [root@localhost ~]# ls -l /bin/passwd -rwsr-xr-x. 1 root root 27832 1月 30 2014 /bin/passwd [root@localhost ~]#
2. SGID
SGID主要实现如下两种功能:
让执行者临时拥有属组的权限(对拥有执行权限的二进制程序进行设置);
在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置)。
SGID的第一种功能是参考SUID而设计的,不同点在于执行程序的用户获取的不再是文件所有者的临时权限,而是获取到文件所属组的权限。每个文件都有其归属的所有者和所属组,当创建或传送一个文件后,这个文件就会自动归属于执行这个操作的用户(即该用户是文件的所有者)。如果现在需要在一个部门内设置共享目录,让部门内的所有人员都能够读取目录中的内容,那么就可以创建部门共享目录后,在该目录上设置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命令是一个非常实用的命令,能够用来设置文件或目录的权限,如果要把一个文件的权限设置成其所有者可读可写可执行、所属组可读可写、其他人没有任何权限,则相应的字符法表示为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,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
3. SBIT
SBIT特殊权限位可确保用户只能删除自己的文件,而不能删除其他用户的文件。换句话说,当对某个目录设置了SBIT粘滞位权限后,那么该目录中的文件就只能被其所有者执行删除操作了。与前面所讲的SUID和SGID权限显示方法不同,当目录被设置SBIT特殊权限位后,文件的其他*限部分的x执行权限就会被替换成t或者T,原本有x执行权限则会写成t,原本没有x执行权限则会被写成T。
[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
其实,文件能否被删除并不取决于自身的权限,而是看其所在目录是否有写入权限,为了避免现在很多读者不放心,所以上面的命令还是赋予了这个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
当然,要是也想对其他目录来设置SBIT特殊权限位,用chmod命令就可以了。对应的参数o+t代表设置SBIT粘滞位权限:
[blackshield@linuxprobe tmp]$ exit Logout [root@linuxprobe tmp]# cd ~ [root@linuxprobe ~]# mkdir linux [root@linuxprobe ~]# chmod -R o+t linux/ [root@linuxprobe ~]# ls -ld linux/ drwxr-xr-t. 2 root root 6 Feb 11 19:34 linux/
四、文件的隐藏属性
Linux系统中的文件除了具备一般权限和特殊权限之外,还有一种隐藏权限,即被隐藏起来的权限,默认情况下不能直接被用户发觉。有用户曾经在生产环境和RHCE考试题目中碰到过明明权限充足但却无法删除某个文件的情况,或者仅能在日志文件中追加内容而不能修改或删除内容,这在一定程度上阻止了黑客篡改系统日志的图谋,因此这种“奇怪”的文件也保障了Linux系统的安全性。
1. chattr命令
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
接下来我们再次新建一个普通文件,并为其设置不允许删除与覆盖(+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
2. lsattr命令
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
五、文件访问控制列表
前文讲解的一般权限、特殊权限、隐藏权限其实有一个共性—权限是针对某一类用户设置的。如果希望对某个指定的用户进行单独的权限控制,就需要用到文件的访问控制列表(ACL)了。如果针对某个目录设置了ACL,则目录中的文件会继承其ACL;若针对文件设置了ACL,则文件不再继承其所在目录的ACL。
我们先切换到普通用户,然后尝试进入root管理员的家目录中。在没有针对普通用户对root管理员的家目录设置ACL之前,其执行结果如下所示:
[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
1. setfacl命令
setfacl命令用于管理文件的ACL规则,文件的ACL提供的是在所有者、所属组、其他人的读/写/执行权限之外的特殊权限控制,使用setfacl命令可以针对单一用户或用户组、单一文件或目录来进行读/写/执行权限的控制。
其中,针对目录文件需要使用-R递归参数;针对普通文件则使用-m参数;如果想要删除某个文件的ACL,则可以使用-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表信息的,但是却可以看到文件的权限最后一个点(.)变成了加号(+),这就意味着该文件已经设置了ACL了。
[root@linuxprobe ~]# ls -ld /root dr-xrwx---+ 14 root root 4096 May 4 2017 /root
2. getfacl命令
getfacl命令用于显示文件上设置的ACL信息,想要设置ACL,用的是setfacl命令;要想查看ACL,则用的是getfacl命令。下面使用getfacl命令显示在root管理员家目录上设置的所有ACL信息。
[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::---
六、su命令与sudo服务
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命令与用户名之间有一个减号(-),这意味着完全切换到新的用户,即把环境变量信息也变更为新用户的相应信息,而不是保留原始的信息。强烈建议在切换用户身份时添加这个减号(-)。
另外,当从root管理员切换到普通用户时是不需要密码验证的,而从普通用户切换成root管理员就需要进行密码验证了;这也是一个必要的安全检查:
[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服务的配置原则也很简单—在保证普通用户完成相应工作的前提下,尽可能少地赋予额外的权限。
总结来说,sudo命令具有如下功能:
当然,如果担心直接修改配置文件会出现问题,则可以使用sudo命令提供的visudo命令来配置用户权限。这条命令在配置用户权限时将禁止多个用户同时修改sudoers配置文件,还可以对配置文件内的参数进行语法检查,并在发现参数错误时进行报错。限制用户执行指定的命令:
记录用户执行的每一条命令;
配置文件(/etc/sudoers)提供集中的用户管理、权限与主机等参数;
验证密码的后5分钟内(默认值)无须再让用户再次验证密码。
只有root管理员才可以使用visudo命令编辑sudo服务的配置文件。使用visudo命令配置sudo命令的配置文件时,其操作方法与Vim编辑器中用到的方法一致,因此在编写完成后记得在末行模式下保存并退出。在sudo命令的配置文件中,按照下面的格式将第99行(大约)填写上指定的信息:
[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:此处输入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参数就有些不合适了。如果需要让某个用户只能使用root管理员的身份执行指定的命令,切记一定要给出该命令的绝对路径,否则系统会识别不出来。我们可以先使用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命令后都会要求验证一下密码。虽然这个密码就是当前登录用户的密码,但是每次执行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.在RHEL 7系统中,root管理员是谁?
答:是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参数。
七、一切从“/”开始既然平时我们打交道的都是文件,那么又应该如何找到它们呢?在Linux系统中并不存在C/D/E/F等盘符,Linux系统中的一切文件都是从“根(/)”目录开始的,并按照文件系统层次化标准(FHS)采用树形结构来存放文件,以及定义了常见目录的用途。另外,Linux系统中的文件和目录名称是严格区分大小写的。例如,root、rOOt、Root、rooT均代表不同的目录,并且文件名称中不得包含斜杠(/)。
Linux系统中的文件存储结构
Linux系统中常见的目录名称以及相应内容
目录名称 | 应放置文件的内容 |
/boot | 开机所需文件—内核、开机菜单以及所需配置文件等 |
/dev | 以文件形式存放任何设备与接口(重要) |
/etc | 配置文件(重要) |
/home | 用户主目录(重要) |
/bin | 存放单用户模式下还可以操作的命令 |
/lib | 开机时用到的函数库,以及/bin与/sbin下面的命令要调用的函数 |
/sbin | 开机过程中需要的命令 |
/media | 用于挂载设备文件的目录(重要) |
/opt | 放置第三方的软件 |
/root | 系统管理员的家目录(重要) |
/srv | 一些网络服务的数据文件目录 |
/tmp | 任何人均可使用的“共享”临时目录(重要) |
/proc | 虚拟文件系统,例如系统内核、进程、外部设备及网络状态等 |
/usr/local | 用户自行安装的软件 |
/usr/sbin | Linux系统开机时不会使用到的软件/命令/脚本 |
/usr/share | 帮助与说明文件,也可放置共享文件 |
/var | 主要存放经常变化的文件,如日志(重要) |
/lost+found | 当文件系统发生错误时,将一些丢失的文件片段存放在这里 |
绝对路径(absolute path):首先坐飞机来到中国,到了北京出首都机场坐机场快轨到三元桥,然后换乘10号线到潘家园站,出站后坐34路公交车到农光里,下车后路口左转。
相对路径(relative path):前面路口左转。
八、物理设备的命名规则
Linux系统中常见的硬件设备的文件名称如表所示:
常见的硬件设备及其文件名称
硬件设备 | 文件名称 |
IDE设备 | /dev/hd[a-d] |
SCSI/SATA/U盘 | /dev/sd[a-p] |
软驱 | /dev/fd[0-1] |
打印机 | /dev/lp[0-15] |
光驱 | /dev/cdrom |
鼠标 | /dev/mouse |
磁带机 | /dev/st0或/dev/ht0 |
由于现在的IDE设备已经很少见了,所以一般的硬盘设备都会是以“/dev/sd”开头的。而一台主机上可以有多块硬盘,因此系统采用a~p来代表16块不同的硬盘(默认从a开始分配),而且硬盘的分区编号也很有讲究:
主分区或扩展分区的编号从1开始,到4结束;
逻辑分区从编号5开始。
/dev目录中sda设备之所以是a,并不是由插槽决定的,而是由系统内核的识别顺序来决定的,而恰巧很多主板的插槽顺序就是系统内核的识别顺序,因此才会被命名为/dev/sda。大家以后在使用iSCSI网络存储设备时就会发现,明明主板上第二个插槽是空着的,但系统却能识别到/dev/sdb这个设备就是这个道理。sda3只能表示是编号为3的分区,而不能判断sda设备上已经存在了3个分区。
现在我们来分析一下,/dev/sda5这个设备文件名称包含了哪些信息:
硬盘设备是由大量的扇区组成的,每个扇区的容量为512字节。其中第一个扇区最重要,它里面保存着主引导记录与分区表信息。就第一个扇区来讲,主引导记录需要占用446字节,分区表为64字节,结束符占用2字节;其中分区表中每记录一个分区信息就需要16字节,这样一来最多只有4个分区信息可以写到第一个扇区中,这4个分区就是4个主分区。
扩展分区其实并不是一个真正的分区,而更像是一个占用16字节分区表空间的指针—一个指向另外一个分区的指针。这样一来,用户一般会选择使用3个主分区加1个扩展分区的方法,然后在扩展分区中创建出数个逻辑分区,从而来满足多分区(大于4个)的需求。
所谓扩展分区,严格地讲它不是一个实际意义的分区,它仅仅是一个指向下一个分区的指针,这种指针结构将形成一个单向链表。
九、文件系统与数据资料
用户在硬件存储设备中执行的文件建立、写入、读取、修改、转存与控制等操作都是依靠文件系统来完成的。文件系统的作用是合理规划硬盘,以保证用户正常的使用需求。Linux系统支持数十种的文件系统,而最常见的文件系统如下:
Ext3:是一款日志文件系统,能够在系统异常宕机时避免文件系统资料丢失,并能自动修复数据的不一致与错误。
Ext4:Ext3的改进版本,作为RHEL 6系统中的默认文件管理系统,它支持的存储容量高达1EB(1EB=1,073,741,824GB),且能够有无限多的子目录。
XFS:是一种高性能的日志文件系统,而且是RHEL 7中默认的文件管理系统,它的优势在发生意外宕机后尤其明显,即可以快速地恢复可能被破坏的文件,而且强大的日志功能只用花费极低的计算和存储性能。并且它最大可支持的存储容量为18EB,这几乎满足了所有需求。
就像拿到了一张未裁切的完整纸张那样,我们首先要进行裁切以方便使用,然后在裁切后的纸张上画格以便能书写工整。在拿到了一块新的硬盘存储设备后,也需要先分区,然后再格式化文件系统,最后才能挂载并正常使用。也可以不进行分区,但是必须对硬盘进行格式化操作;
Linux只是把每个文件的权限与属性记录在inode中,而且每个文件占用一个独立的inode表格,该表格的大小默认为128字节,里面记录着如下信息:
该文件的访问权限(read、write、execute);
该文件的所有者与所属组(owner、group);
该文件的大小(size);
该文件的创建或内容修改时间(ctime);
该文件的最后一次访问时间(atime);
该文件的修改时间(mtime);
文件的特殊权限(SUID、SGID、SBIT);
该文件的真实数据地址(point)。
而文件的实际内容则保存在block块中(大小可以是1KB、2KB或4KB),一个inode的默认大小仅为128B(Ext3),记录一个block则消耗4B。当文件的inode被写满后,Linux系统会自动分配出一个block块,专门用于像inode那样记录其他block块的信息,这样把各个block块的内容串到一起,就能够让用户读到完整的文件内容了。对于存储文件内容的block块,有下面两种常见情况(以4KB的block大小为例进行说明)。
情况1:文件很小(1KB),但依然会占用一个block,因此会潜在地浪费3KB。
情况2:文件很大(5KB),那么会占用两个block(5KB-4KB后剩下的1KB也要占用一个block)。
为了使用户在读取或写入文件时不用关心底层的硬盘结构,Linux内核中的软件层为用户程序提供了一个VFS(Virtual File System,虚拟文件系统)接口,这样用户实际上在操作文件时就是统一对这个虚拟文件系统进行操作了。VFS的架构示意图:
十、挂载硬件设备
接下来我们会逐一学习在Linux系统中挂载和卸载存储设备的方法,以便大家更好地了解Linux系统添加硬件设备的工作原理和流程。前面讲到,在拿到一块全新的硬盘存储设备后要先分区,然后格式化,最后才能挂载并正常使用。“分区”和“格式化”大家以前经常听到,但“挂载”又是什么呢?简单来说就是:每当用户需要使用硬盘设备或分区中的数据时,需要先将其与一个已存在的目录文件进行关联,而这个关联动作就是“挂载”。
mount命令用于挂载文件系统,挂载是在使用硬件设备前所执行的最后一步操作。对于比较新的Linux系统来讲,一般不需要使用-t参数来指定文件系统的类型,Linux系统会自动进行判断。而mount 中的-a参数则厉害了,它会在执行后自动检查/etc/fstab文件中有无疏漏被挂载的设备文件,如果有,则进行自动挂载操作。
mount命令中的参数以及作用
参数 | 作用 |
-a | 挂载所有在/etc/fstab中定义的文件系统 |
-t | 指定文件系统的类型 |
例如,要把设备/dev/sdb2挂载到/backup目录,只需要在mount命令中填写设备与挂载目录参数就行,系统会自动去判断要挂载文件的类型,因此只需要执行下述命令即可:
[root@linuxprobe ~]# mount /dev/sdb2 /backup
虽然按照上面的方法执行mount命令后就能立即使用文件系统了,但系统在重启后挂载就会失效,如果想让硬件设备和目录永久地进行自动关联,就必须把挂载信息按照指定的填写格式“设备文件 挂载目录 格式类型 权限选项 是否备份 是否自检”(各字段的意义见表6-4)写入到/etc/fstab文件中。这个文件中包含着挂载所需的诸多信息项目,一旦配置好之后就能一劳永逸了。
用于挂载信息的指定填写格式中,各字段所表示的意义
字段 | 意义 |
设备文件 | 一般为设备的路径+设备名称,也可以写唯一识别码(UUID,Universally Unique Identifier) |
挂载目录 | 指定要挂载到的目录,需在挂载前创建好 |
格式类型 | 指定文件系统的格式,比如Ext3、Ext4、XFS、SWAP、iso9660(此为光盘设备)等 |
权限选项 | 若设置为defaults,则默认权限为:rw, suid, dev, exec, auto, nouser, async |
是否备份 | 若为1则开机后使用dump进行磁盘备份,为0则不备份 |
是否自检 | 若为1则开机后自动进行磁盘自检,为0则不自检 |
如果想将文件系统为ext4的硬件设备/dev/sdb2在开机后自动挂载到/backup目录上,并保持默认权限且无需开机自检,就需要在/etc/fstab文件中写入下面的信息,这样在系统重启后也会成功挂载。
[root@linuxprobe ~]# vim /etc/fstab # # /etc/fstab # Created by anaconda on Wed May 4 19:26:23 2017 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/rhel-root / xfs defaults 1 1 UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b /boot xfs defaults 1 2 /dev/mapper/rhel-swap swap swap defaults 0 0 /dev/cdrom /media/cdrom iso9660 defaults 0 0 /dev/sdb2 /backup ext4 defaults 0 0
umount命令用于撤销已经挂载的设备文件:[root@linuxprobe ~]# umount /dev/sdb2
十一、添加硬盘设备
第1步:首先把虚拟机系统关机,稍等几分钟会自动返回到虚拟机管理主界面,然后单击“编辑虚拟机设置”选项,在弹出的界面中单击“添加”按钮,新增一块硬件设备,如图所示:
第2步:选择想要添加的硬件类型为“硬盘”,然后单击“下一步”按钮就可以了,这确实没有什么需要进一步解释的,如图所示:
第3步:选择虚拟硬盘的类型为SCSI(默认推荐),并单击“下一步”按钮,这样虚拟机中的设备名称过一会儿后应该为/dev/sdb,如图所示:
第4步:选中“创建新虚拟磁盘”单选按钮,而不是其他选项,再次单击“下一步”按钮:
第5步:将“最大磁盘大小”设置为默认的20GB。这个数值是限制这台虚拟机所使用的最大硬盘空间,而不是立即将其填满,因此默认20GB就很合适了。单击“下一步”按钮:
第6步:设置磁盘文件的文件名和保存位置(这里采用默认设置即可,无需修改),直接单击“完成”按钮:
第7步:将新硬盘添加好后就可以看到设备信息了。这里不需要做任何修改,直接单击“确认”按钮后就可以开启虚拟机了:
1. fdisk命令
在Linux系统中,管理硬盘设备最常用的方法就当属fdisk命令了。
fdisk命令中的参数以及作用
参数 | 作用 |
m | 查看全部可用的参数 |
n | 添加新的分区 |
d | 删除某个分区信息 |
l | 列出所有可用的分区类型 |
t | 改变某个分区的类型 |
p | 查看分区表信息 |
w | 保存并退出 |
q | 不保存直接退出 |
第1步:我们首先使用fdisk命令来尝试管理/dev/sdb硬盘设备。在看到提示信息后输入参数p来查看硬盘设备内已有的分区信息,其中包括了硬盘的容量大小、扇区个数等信息:
[root@linuxprobe ~]# fdisk /dev/sdb Welcome to fdisk (util-linux 2.23.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table Building a new DOS disklabel with disk identifier 0x47d24a34. Command (m for help): p Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x47d24a34 Device Boot Start End Blocks Id System
第2步:输入参数n尝试添加新的分区。系统会要求您是选择继续输入参数p来创建主分区,还是输入参数e来创建扩展分区。这里输入参数p来创建一个主分区:
Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p
第3步:在确认创建一个主分区后,系统要求您先输入主分区的编号。我们在前文得知,主分区的编号范围是1~4,因此这里输入默认的1就可以了。接下来系统会提示定义起始的扇区位置,这不需要改动,我们敲击回车键保留默认设置即可,系统会自动计算出最靠前的空闲扇区的位置。最后,系统会要求定义分区的结束扇区位置,这其实就是要去定义整个分区的大小是多少。我们不用去计算扇区的个数,只需要输入+2G即可创建出一个容量为2GB的硬盘分区。
Partition number (1-4, default 1): 1 First sector (2048-41943039, default 2048):此处敲击回车 Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +2G Partition 1 of type Linux and of size 2 GiB is set