1、概念
1.1 Linux权限位
Linux 系统,最常见的文件权限有 3 种,即对文件的读( r )、写( w )和执行( x ,针对可执行文件或目录)权限。
除此之外,我们有时会看到 s(针对可执行文件或目录,使文件在执行阶段,临时拥有文件所有者的权限)和 t(针对目录,任何用户都可以在此目录中创建文件,但只能删除自己的文件),文件设置 s 和 t 权限,会占用 x 权限的位置。
[root@localhost ~]# ls -altotal 156drwxr-x---. 4 root root 4096 Sep 8 14:06 .drwxr-xr-x. 23 root root 4096 Sep 8 14:21 ..-rw-------. 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg-rw-------. 1 root root 199 Sep 8 17:14 .bash_history-rw-r--r--. 1 root root 24 Jan 6 2007 .bash_logout
可以看到,每行的第一列表示的就是各文件针对不同用户设定的权限,一共 11 位,但第 1 位用于表示文件的具体类型,最后一位此文件受 SELinux 的安全规则管理
因此,为文件设定不同用户的读、写和执行权限,仅涉及到 9 位字符,以 ls 命令输出信息中的 .bash_logout 文件为例,设定不同用户的访问权限是 rw-r—r—,各权限位的含义如图 1 所示

除了所有者,以及所属群组中的用户可以访问文件外,其他用户(其他群组中的用户)也可以访问文件,这部分用户都归为其他人范畴。
很显然,Linux 系统为 3 种不同的用户身份,分别规定了是否对文件有读、写和执行权限。拿图 1 来说,文件所有者拥有对文件的读和写权限,但是没有执行权限;所属群组中的用户只拥有读权限,也就是说,这部分用户只能读取文件内容,无法修改文件;其他人也是只能读取文件。
1.2 Linux读写执行权限(-r、-w、-x)的含义
rwx 权限对文件的作用
文件,是系统中用来存储数据的,包括普通的文本文件、数据库文件、二进制可执行文件,等等。不同的权限对文件的含义如表 1 所示。
| rwx 权限 | 对文件的作用 |
|---|---|
| 读权限(r) | 表示可读取此文件中的实际内容,例如,可以对文件执行 cat、more、less、head、tail 等文件查看命令。 |
| 写权限(w) | 表示可以编辑、新增或者修改文件中的内容,例如,可以对文件执行 vim、echo 等修改文件数据的命令。注意,无权限不赋予用户删除文件的权利,除非用户对文件的上级目录拥有写权限才可以。 |
| 执行权限(x) | 表示该文件具有被系统执行的权限。Window系统中查看一个文件是否为可执行文件,是通过扩展名(.exe、.bat 等),但在 Linux 系统中,文件是否能被执行,是通过看此文件是否具有 x 权限来决定的。也就是说,只要文件拥有 x 权限,则此文件就是可执行文件。但是,文件到底能够正确运行,还要看文件中的代码是否正确。 |
对于文件来说,执行权限是最高权限。给用户或群组设定权限时,是否赋予执行权限需要慎重考虑,否则会对系统安装造成严重影响。
rwx 权限对目录的作用
目录,主要用来记录文件名列表,不同的权限对目录的作用如表 2 所示。
| rwx 权限 | 对目录的作用 |
|---|---|
| 读权限(r) | 表示具有读取目录结构列表的权限,也就是说,可以看到目录中有哪些文件和子目录。一旦对目录拥有 r 权限,就可以在此目录下执行 ls 命令,查看目录中的内容。 |
| 写权限(w) | 对于目录来说,w 权限是最高权限。对目录拥有 w 权限,表示可以对目录做以下操作: - 在此目录中建立新的文件或子目录; - 删除已存在的文件和目录(无论子文件或子目录的权限是怎样的); - 对已存在的文件或目录做更名操作; - 移动此目录下的文件和目录的位置。 |
一旦对目录拥有 w 权限,就可以在目录下执行 touch、rm、cp、mv 等命令。 | | 执行权限(x) | 目录是不能直接运行的,对目录赋予 x 权限,代表用户可以进入目录,也就是说,赋予 x 权限的用户或群组可以使用 cd 命令 |
对目录来说,如果只赋予 r 权限,则此目录是无法使用的。很简单,只有 r 权限的目录,用户只能查看目录结构,根本无法进入目录(需要用 x 权限),更不用说使用了。
因此,对于目录来说,常用来设定目录的权限其实只有 0(—-)、5(r-x)、7(rwx)这 3 种。
【例 1】
某目录的权限如下所示:
drwxr--r--. 3 root root 4096 Jun 25 08:35 .ssh
系统有个账号名称为 vbird,此账户并不包含在 root 群组中,请问 vbird 对这个目录有何权限?是否可切换到此目录中?
答案:vbird 对此目录仅具有 r 的权限,因此 vbird 可以查询此目录下的文件名列表。因为 vbird 不具有 x 的权限,因此 vbird 并不能切换到此目录内。
【例 2】
假设有个账号名称为dmtsai,他的家目录在/home/dmtsai/,dmtsai对此目录具有[rwx]的权限。若在此目录下有个名为 the_root.data 的文件,该文件的权限如下:
-rwx------. 1 root root 4365 Sep 19 23:20 the_root.data
请问 dmtsai 对此文件的权限为何?可否删除此文件?
答案:由于 dmtsai 对此文件来说是其他人的身份,因此这个文件他无法读、无法编辑也无法执行,也就是说,他无法变动这个文件的内容就是了。但是由于这个文件在他的家目录下,他在此目录下具有 rwx 的完整权限,因此对于 the_root.data 这个文件来说,是能够删除的。
1.3 Linux ACL访问控制权限
Linux 系统传统的权限控制方式,无非是利用 3 种身份(文件所有者,所属群组,其他用户),并分别搭配 3 种权限(读 r,写 w,访问 x)。比如,我们可以通过 ls -l 命令查看当前目录中所有文件的详细信息,其中就包含对各文件的权限设置:
[root@localhost ~]# ls -l
total 36
drwxr-xr-x. 2 root root 4096 Apr 15 16:33 Desktop
drwxr-xr-x. 2 root root 4096 Apr 15 16:33 Documents
...
-rwxr-xr-x. 2 root root 4096 Apr 15 16:33 post-install
...
以上输出信息中,“rwxr-xr-x”就指明了不同用户访问文件的权限,即文件所有者拥有对文件的读、写、访问权限(rwx),文件所属群组拥有对文件的读、访问权限(r-x),其他用户拥有对文件的读、访问权限(r-x)。
权限前的字符,表示文件的具体类型,比如 d 表示目录,- 表示普通文件,l 表示连接文件,b 表示设备文件,等等。
但在实际应用中,以上这 3 种身份根本不够用,给大家举个例子。
图中根目录中有一个 /project 目录,这是班级的项目目录。班级中的每个学员都可以访问和修改这个目录,老师需要拥有对该目录的最高权限,其他班级的学员当然不能访问这个目录。
需要怎么规划这个目录的权限呢?应该这样,老师使用 root 用户,作为这个目录的属主,权限为 rwx;班级所有的学员都加入 tgroup 组,使 tgroup 组作为 /project 目录的属组,权限是 rwx;其他人的权限设定为 0(也就是 —-)。这样一来,访问此目录的权限就符合我们的要求了。
有一天,班里来了一位试听的学员 st,她必须能够访问 /project 目录,所以必须对这个目录拥有 r 和 x 权限;但是她又没有学习过以前的课程,所以不能赋予她 w 权限,怕她改错了目录中的内容,所以学员 st 的权限就是 r-x。可是如何分配她的身份呢?变为属主?当然不行,要不 root 该放哪里?加入 tgroup 组?也不行,因为 tgroup 组的权限是 rwx,而我们要求学员 st 的权限是 r-x。如果把其他人的权限改为 r-x 呢?这样一来,其他班级的所有学员都可以访问 /project 目录了。
显然,普通权限的三种身份不够用了,无法实现对某个单独的用户设定访问权限,这种情况下,就需要使用 ACL 访问控制权限。
ACL,是 Access Control List(访问控制列表)的缩写,在 Linux 系统中, ACL 可实现对单一用户设定访问文件的权限。也可以这么说,设定文件的访问权限,除了用传统方式(3 种身份搭配 3 种权限),还可以使用 ACL 进行设定。拿本例中的 st 学员来说,既然赋予它传统的 3 种身份,无法解决问题,就可以考虑使用 ACL 权限控制的方式,直接对 st 用户设定访问文件的 r-x 权限。
2、权限相关命令
2.1 chgrp 修改文件和目录的所属组
chgrp 命令用于修改文件(或目录)的所属组。 可以将 chgrp 理解为是 “change group” 的缩写。
语法 chgrp [-R] 所属组 文件名(目录名)
示例
[root@localhost ~]# groupadd group1
#新建用于测试的群组 group1
[root@localhost ~]# chgrp group1 install.log
#修改install.log文件的所属组为group1
[root@localhost ~]# ll install.log
-rw-r--r--. 1 root group1 78495 Nov 17 05:54 install.log
#修改生效
[root@localhost ~]# chgrp testgroup install.log
chgrp: invaild group name 'testgroup' # 不存在的组名会报错
2.2 chown 修改文件和目录的所有者和所属组
chown 命令,可以认为是 “change owner” 的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。
语法chown [-R] 所有者 文件或目录
-R(注意大写)选项表示连同子目录中的所有文件,都更改所有者。
如果需要同时更改所有者和所属组,chown 命令的基本格式为chown [-R] 所有者:所属组 文件或目录
【例 1】 修改文件的所有者,更多时候是为了得到更高的权限
[root@localhost ~]# touch file
#由root用户创建file文件
[root@localhost ~]# ll file
-rw-r--r--. 1 root root 0 Apr 17 05:12 file
#文件的所有者是root,普通用户user对这个文件拥有只读权限
[root@localhost ~]# chown user file
#修改文件的所有者
[root@localhost ~]# ll file
-rw-r--r--. 1 user root 0 Apr 17 05:12 file
#所有者变成了user用户,这时user用户对这个文件就拥有了读、写权限
【例 2】普通用户只能修改自己文件的权限(所有者是自己的文件)
[root@localhost ~]# cd /home/user
#进入user用户的家目录
[root@localhost user]# touch test
#由root用户新建文件test
[root@localhost user]# ll test
-rw-r--r--. 1 root root 0 Apr 17 05:37 test
#文件所有者和所属组都是root用户
[root@localhost user]# su - user
#切换为user用户
[user@localhost ~]$ chmod 755 test
chmod:更改"test"的权限:不允许的操作 #user用户不能修改test文件的权限
[user@localhost ~]$ exit
#退回到root身份
[root@localhost user]# chown user test
#由root用户把test文件的所有者改为user用户
[root@localhost user]# su - user
#切换为user用户
[user@localhost ~]$ chmod 755 test
#user用户由于是test文件的所有者,所以可以修改文件的权限
[user@localhost ~]$ ll test
-rwxr-xr-x. 1 user root 0 Apr 17 05:37 test
#查看权限
【例 3】同时修改用户和组
[root@localhost ~]# chown user:group file
[root@localhost ~]# ll file
-rw-r--r--. 1 user group 0 Apr 17 05:12 file
2.3 chmod命令使用数字修改文件权限
Linux 系统中,文件的基本权限由 9 个字符组成,以 rwxrw-r-x 为例,我们可以使用数字来代表各个权限,各个权限与数字的对应关系如下:
r --> 4
w --> 2
x --> 1
由于这 9 个字符分属 3 类用户,因此每种用户身份包含 3 个权限(r、w、x),通过将 3 个权限对应的数字累加,最终得到的值即可作为每种用户所具有的权限。
拿 rwxrw-r-x 来说,所有者、所属组和其他人分别对应的权限值为:
所有者 = rwx = 4+2+1 = 7
所属组 = rw- = 4+2 = 6
其他人 = r-x = 4+1 = 5
所以,此权限对应的权限值就是 765。
使用数字修改文件权限的 chmod 命令基本格式为:chmod [-R] 权限值 文件名
-R(注意是大写)选项表示连同子目录中的所有文件,也都修改设定的权限。
例如,使用如下命令,即可完成对 .bashrc 目录文件的权限修改:
[root@localhost ~]# ls -al .bashrc
-rw-r--r--. 1 root root 176 Sep 22 2004 .bashrc
[root@localhost ~]# chmod 777 .bashrc
[root@localhost ~]# ls -al .bashrc
-rwxrwxrwx. 1 root root 176 Sep 22 2004 .bashrc
再举个例子,通常我们以 Vim 编辑 Shell 文件批处理文件后,文件权限通常是 rw-rw-r—(644),那么,如果要将该文件变成可执行文件,并且不让其他人修改此文件,则只需将此文件的权限该为 rwxr-xr-x(755)即可
2.4 chmod命令使用字母修改文件权限
既然文件的基本权限就是 3 种用户身份(所有者、所属组和其他人)搭配 3 种权限(rwx),chmod 命令中用 u、g、o 分别代表 3 种身份,还用 a 表示全部的身份(all 的缩写)。另外,chmod 命令仍使用 r、w、x 分别表示读、写、执行权限。
使用字母修改文件权限的 chmod 命令,其基本格式如图 1 所示。
例如,如果我们要设定 .bashrc 文件的权限为 rwxr-xr-x,则可执行如下命令:
[root@localhost ~]# chmod u=rwx,go=rx .bashrc
[root@localhost ~]# ls -al .bashrc
-rwxr-xr-x. 1 root root 176 Sep 22 2004 .bashrc
再举个例子,如果想要增加 .bashrc 文件的每种用户都可做写操作的权限,可以使用如下命令:
[root@localhost ~]# ls -al .bashrc
-rwxr-xr-x. 1 root root 176 Sep 22 2004 .bashrc
[root@localhost ~]# chmod a+w .bashrc
[root@localhost ~]# ls -al .bashrc
-rwxrwxrwx. 1 root root 176 Sep 22 2004 .bashrc
2.5 sudo命令
我们知道,使用 su 命令可以让普通用户切换到 root 身份去执行某些特权命令,但存在一些问题,比如说:
- 仅仅为了一个特权操作就直接赋予普通用户控制系统的完整权限;
- 当多人使用同一台主机时,如果大家都要使用 su 命令切换到 root 身份,那势必就需要 root 的密码,这就导致很多人都知道 root 的密码;
考虑到使用 su 命令可能对系统安装造成的隐患,最常见的解决方法是使用 sudo 命令,此命令也可以让你切换至其他用户的身份去执行命令。
相对于使用 su 命令还需要新切换用户的密码,sudo 命令的运行只需要知道自己的密码即可,甚至于,我们可以通过手动修改 sudo 的配置文件,使其无需任何密码即可运行。
sudo 命令默认只有 root 用户可以运行,该命令的基本格式为:
sudo [-b] [-u 新使用者账号] 要执行的命令
常用的选项与参数:
- -b :将后续的命令放到背景中让系统自行运行,不对当前的 shell 环境产生影响。
- -u :后面可以接欲切换的用户名,若无此项则代表切换身份为 root 。
- -l:此选项的用法为 sudo -l,用于显示当前用户可以用 sudo 执行那些命令。
【例 1】
[root@localhost ~]# grep sshd /etc/passwd
sshd:x:74:74:privilege-separated SSH:/var/empty/sshd:/sbin.nologin
[root@localhost ~]# sudo -u sshd touch /tmp/mysshd
[root@localhost ~]# ll /tmp/mysshd
-rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd
本例中,无法使用 su - sshd 的方式成功切换到 sshd 账户中,因为此用户的默认 Shell 是 /sbin/nologin。
这时就显现出 sudo 的优势,我们可以使用 sudo 以 sshd 的身份在 /tmp 目录下创建 mysshd 文件,
可以看到,新创建的 mysshd 文件的所有者确实是 sshd。
【例 2】
[root@localhost ~]# sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
> echo 'This is index.html file' > index.html"
[root@localhost ~]# ll -a ~vbird1/www
drwxr-xr-x 2 vbird1 vbird1 4096 Feb 28 17:51 .
drwx------ 5 vbird1 vbird1 4096 Feb 28 17:51 ..
-rw-r--r-- 1 vbird1 vbird1 24 Feb 28 17:51 index.html
这个例子中,使用 sudo 命令切换至 vbird1 身份,并运行 sh -c 的方式来运行一连串的命令。
前面说过,默认情况下 sudo 命令只有 root 身份可以使用,那么,如何让普通用户也能使用它呢?
解决这个问题之前,先给大家分析一下 sudo 命令的执行过程。sudo命令的运行,需经历如下几步:
- 当用户运行 sudo 命令时,系统会先通过 /etc/sudoers 文件,验证该用户是否有运行 sudo 的权限;
- 确定用户具有使用 sudo 命令的权限后,还要让用户输入自己的密码进行确认。出于对系统安全性的考虑,如果用户在默认时间内(默认是 5 分钟)不使用 sudo 命令,此后使用时需要再次输入密码;
- 密码输入成功后,才会执行 sudo 命令后接的命令。
显然,能否使用 sudo 命令,取决于对 /etc/sudoers 文件的配置(默认情况下,此文件中只配置有 root 用户)。所以接下来,我们学习对 /etc/sudoers 文件进行合理的修改。
