Linux 系统传统的权限控制方式,无非是利用 3 种身份(文件所有者,所属群组,其他用户),并分别搭配 3 种权限(读 r,写 w,访问 x)。比如,我们可以通过 ls -l 命令查看当前目录中所有文件的详细信息,其中就包含对各文件的权限设置:
以上输出信息中,“rwxr-xr-x”就指明了不同用户访问文件的权限,即文件所有者拥有对文件的读、写、访问权限(rwx),文件所属群组拥有对文件的读、访问权限(r-x),其他用户拥有对文件的读、访问权限(r-x)。
权限前的字符,表示文件的具体类型,比如 d 表示目录,- 表示普通文件,l 表示连接文件,b 表示设备文件,等等。
但在实际应用中,以上这 3 种身份根本不够用,给大家举个例子。
图 1 的根目录中有一个 /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 权限。
设定 ACl 权限,常用命令有 2 个,分别是 setfacl 和 getfacl 命令,前者用于给指定文件或目录设定 ACL 权限,后者用于查看是否配置成功。
getfacl 命令用于查看文件或目录当前设定的 ACL 权限信息。该命令的基本格式为:
getfacl 命令的使用非常简单,且常和 setfacl 命令一起搭配使用。
setfacl 命令可直接设定用户或群组对指定文件的访问权限。此命令的基本格式为:
表 1 罗列出了该命令可以使用的所用选项及功能。
回归上面的案例,解决方案如下:
- 老师使用 root 用户,并作为 /project 的所有者,对 project 目录拥有 rwx 权限;
- 新建 tgroup 群组,并作为 project 目录的所属组,包含本班所有的班级学员(假定只有 zhangsan 和 lisi),拥有对 project 的 rwx 权限;
- 将其他用户访问 project 目录的权限设定为 0(也就是 ---)。
- 对于试听学员 st 来说,我们对其设定 ACL 权限,令该用户对 project 拥有 rx 权限。
具体的设置命令如下:
可以看到,通过设定 ACL 权限,我们可以单独给 st 用户分配 r-x 权限,而无需给 st 用户设定任何身份。同样的道理,也可以给用户组设定 ACL 权限,例如:
既然已经对 project 目录设定了 ACL 权限,那么,如果在这个目录中新建一些子文件和子目录,这些文件是否会继承父目录的 ACL 权限呢?执行以下命令进行验证:
可以看到,这两个新建立的文件权限位后面并没有 "+",表示它们没有继承 ACL 权限。这说明,后建立的子文件或子目录,并不会继承父目录的 ACL 权限。
当然,我们可以手工给这两个文件分配 ACL 权限,但是如果在目录中再新建文件,都要手工指定,则显得过于麻烦。这时就需要用到默认 ACL 权限。
默认 ACL 权限的作用是,如果给父目录设定了默认 ACL 权限,那么父目录中所有新建的子文件都会继承父目录的 ACL 权限。需要注意的是,默认 ACL 权限只对目录生效。
例如,给 project 文件设定 st 用户访问 rx 的默认 ACL 权限,可执行如下指令:
原先的 abc 和 d1 还是没有 ACL 权限,因为是针对新建立的文件生效的。
对目录设定的默认 ACL 权限,可直接使用 setfacl -k 命令删除。例如:
通过此命令,即可删除 project 目录的默认 ACL 权限
递归 ACL 权限指的是父目录在设定 ACL 权限时,所有的子文件和子目录也会拥有相同的 ACL 权限。
例如,给 project 目录设定 st 用户访问权限为 rx 的递归 ACL 权限,执行命令如下:
注意,默认 ACL 权限指的是针对父目录中后续建立的文件和目录会继承父目录的 ACL 权限;递归 ACL 权限指的是针对父目录中已经存在的所有子文件和子目录会继承父目录的 ACL 权限。
使用 命令,可以删除指定的 ACL 权限,例如,删除前面建立的 st 用户对 project 目录的 ACL 权限,执行命令如下:
此命令可删除所有与指定文件或目录相关的 ACL 权限。例如,现在我们删除一切与 project 目录相关的 ACL 权限,执行命令如下: