Linux下文件与目录的权限分主要由标准LINUX文件权限与控制访问列表(ACL)两块进行控制。一般情况下标准文件权限已经满足我们大多数情况下的需求,但其存的一个局限性问题是:限制访问的文件权限仅限授权予文件所有者、单组成员或其他人。而无法细化到具体的某个用户的权限(other用户)。本篇就分别介绍下普通文件权限与ACL权限。

一、标准文件权限

普通文件权限是通过十位进行表示的,如下图:

perm

第一位代表的“ 文件” 类型,其可能的值有:-(文件)、d(目录)、b(块设备)、l (link文件)、c (字符设备,如串口)、s(socket套接字)。

第2~4位表示文件属于的权限

第5~7位表示文件属组的权限

第8~10位表示其他用户和组具有的权限。

1、rwx权限设置

文件或目录每三位用rwx表示相应的权限值,其中r值为4、w值为2、x值为1 ,可以使用chmod 对文件或目录进行权限更改。权限的设置有两种表示方式:

1权限值表示法,如
2# chmod 777 file1
3字母值表示法,如
4# chmod a+x file1

chmod

2、umask

在/etc/profile文件有umask值的默认设置,默认值为022,该值对应的是默认文件和目录创建后的权限值:

1目录的默认权限是:777-umask
2文件的默认权限是:666-umask

所以umask为022的情况下,默认创建的目录的权限是755 ,默认创建的文件权限为644 。

3、特殊权限

除了上面的提到的rwx权限外,系统还有三个特殊权限 s s t 权限(冒险位与粘滞位) ,具体描述如下:

sticky

这三个特殊权限也可以用字母和数字表示,具体如下:

1设置suid:    $ chmod  u+s  test
2设置sgid:    $ chmod  g+s  test
3设置sticky:  $ chmod  o+t  test
4suid:4
5sgid:2
6sticky:1

在一些特殊情况下会用到特殊权限位,如passwd命令,如果没有s权限,其他用户会无法使用passwd命令修改自己的密码。

1[root@361way etc]# ls -l /usr/bin/passwd
2-rwsr-xr-x. 1 root root 27832 Jun 10  2014 /usr/bin/passwd

下面给一个增加了s s t 权限的示例:

 1[root@361way tmp]# touch test
 2[root@361way tmp]# ll test
 3-rw-r--r--. 1 root root   0 Aug  5 01:03 test
 4[root@361way tmp]# chmod 7777 test
 5[root@361way tmp]# ll test
 6-rwsrwsrwt. 1 root root   0 Aug  5 01:03 test
 7[root@361way tmp]# su - usera
 8[usera@361way ~]$ cd /tmp/
 9[usera@361way tmp]$ echo 'www.361way.com' > test
10[usera@361way tmp]$ cat test
11www.361way.com
12[usera@361way tmp]$ rm -rf test
13rm: cannot remove test: Operation not permitted

上面的示例中由于增加了t权限,所以普通用户usera,可以通文件写入和更改,无法删除文件。

注:
1、需要注意的是特殊权限是把双刃剑 ,很多木马提供也会利用到s 权限位,所以经常在查找主机木马时,我们会用find查找所有4777 和 6777文件;
2、假如本来在该位上有x, 则这些特别标志 (suid, sgid, sticky) 显示为小写字母 (s, s, t) ,否则, 显示为大写字母 (S, S, T)
3、还有一个大X权限,后面在ACL时也会提到。

二、ACL

1、启用ACL

在rhel 7下的xfs和ext4 文件系统下,默认已经支持了ACL规则(在rhel6下的ext4已经默认支持)---fstab里的defaults里已经集成有ACL支持,但在一些老的发行版上,需要mount挂载文件系统时指定ACL参数挂载才行。如:

1# mount -t ext3 -o remount,acl /home
23# mount -o acl /dev/sdb /data

2、ACL设置与命令

在启用ACL的文件权限位,会有第11个字符(算上第一文件类型字符),在设置过ACL的文件第11位显示的是加号 。具体的权限可以通过getfacl 获取:

 1[root@361way acl]# ll
 2total 4
 3-rw-rwxr--+ 1 root root 5 Aug  4 21:08 a
 4[root@361way acl]# getfacl a
 5# file: a
 6# owner: root
 7# group: root
 8user::rw-
 9user:mysql:rwx
10group::r--
11mask::rwx
12other::r--

与ACL相关的命令有三个,getfacl (获取ACL相关信息)、setfacl (设置ACL权限) 、chacl (更改ACL 权限)。平时经常使用的是第二个命令setfacl,其具体常用参数有:

-m:设置文件或目录的ACL规则
-M:从文件读取ACL规则
-x:删除acl参数
-X:从文件读取ACL规则并进行删除
-b:删除全部的扩展ACL规则,基本ACL规则保留
-k:删除默认的acl规则,如果没有默认规则不提示
-R:递归设置acl,包括子目录
-d:设置默认acl
–mask 重新计算有效权限,即使ACL MASK被明确指定
–no-mask 不重新计算有效权限

setfack命令可以识别以下格式的规则:

1[d[efault]:] u[ser]:uid [:perms] 指定用户的权限,文件所有者的权限(如果uid没有指定)。
2[d[efault]:] g[roup]:gid [:perms] 指定群组的权限,文件所有群组的权限(如果gid未指定)
3[d[efault]:] m[ask][:] [:perms] 有效权限掩码
4[d[efault]:] o[ther] [:perms] 其他的权限

下面我们看一些具体的示例和用法

3、-m 设置权限

-m 参数进行设置时,如果之前文件已经具有ACL设置,则通过-m设置时会覆盖之前的ACL权限设置

 1[root@localhost acl]# setfacl  -m u:user1:rw a
 2[root@localhost acl]# getfacl a
 3# file: a
 4# owner: root
 5# group: root
 6user::rw-
 7user:user1:rw-
 8group::r--
 9mask::rw-
10other::r--

上面的设置是最简单的设置,具体指定时,我们也可以像chmod命令使用一样,同时指定多个权限:

1[root@localhost acl]# setfacl  -m u:user1:rw,g:test:rx  file1

注:需要注意的是,这里虽然给了文件相应的读写执行权限,不过user1用户可以读写执行文件a ,但无法删除该文件,想要删除该文件,需要其原属主root进行删除

1[user1@localhost acl]$ rm -rf a
2rm: cannot remove ‘a’: Permission denied

4、default 默认权限

这里的default是u、g、m、o几个参数前的default参数 。该权限只能针对目录,无法针对文件,如下:

1[root@localhost acl]# setfacl  -m d:u:user1:rw file1
2setfacl: file1: Only directories can have default ACLs

default权限设置过的目录,默认对该目录下已经存在的文件和目录都不具备读写权限,而对于设置权限以后的目录有相应的设置权限

 1[root@localhost ~]# setfacl  -m d:u:user1:rwx acl/
 2#之前已经存在的目录和文件都没有权限
 3[root@localhost /]# su - user1
 4[user1@localhost acl]$ ll
 5-rw-r--r--. 1 root root 0 Aug  4 23:08 filea
 6drwxr-xr-x. 2 root root 6 Aug  4 22:59 dir1
 7[user1@localhost acl]$ touch file1
 8touch: cannot touch ‘file1’: Permission denied
 9[user1@localhost acl]$ mkdir dir2
10mkdir: cannot create directory ‘dir2’: Permission denied
11[user1@localhost acl]$ cd dir1/
12[user1@localhost dir1]$ ll
13total 0
14[user1@localhost dir1]$ touch file1
15touch: cannot touch ‘file1’: Permission denied
16[user1@localhost acl]$ echo 'aaa' > filea
17-bash: filea: Permission denied
18#新创建的子目录有权限
19[root@localhost acl]# mkdir dir2
20[root@localhost acl]# su - user1
21[user1@localhost ~]$ cd /acl/
22[user1@localhost acl]$ ll
23total 4
24drwxr-xr-x. 2 root root 6 Aug  4 22:59 dir1
25drwxrwxr-x+ 2 root root 6 Aug  4 23:04 dir2
26[user1@localhost acl]$ cd dir2/
27[user1@localhost dir2]$ touch file1
28[user1@localhost dir2]$ ll
29total 4
30-rw-rw-r--+ 1 user1 user1 0 Aug  4 23:04 file1

5、mask参数

在通过getfacl 获取文件或目录的权限时,会发现除了user、group、other外还有mask 参数,在setfacl 里也有mask 与no-mask 参数,仅仅从man手册上的简单解释不好理解,这里我们看下下面的实验:

 1[root@localhost /]# cd acl/
 2[root@localhost acl]# touch file-mask
 3[root@localhost acl]# setfacl -m u:user1:rwx file-mask
 4[root@localhost acl]# getfacl file-mask
 5# file: file-mask
 6# owner: root
 7# group: root
 8user::rw-
 9user:user1:rwx
10group::r--
11mask::rwx
12other::r--
13[root@localhost acl]# setfacl -m m:r file-mask
14[root@localhost acl]# getfacl file-mask
15# file: file-mask
16# owner: root
17# group: root
18user::rw-
19user:user1:rwx                  #effective:r--
20group::r--
21mask::r--
22other::r--
23[root@localhost acl]# su - user1
24Last login: Tue Aug  4 23:09:06 CST 2015 on pts/0
25[user1@localhost ~]$ cd /acl/
26[user1@localhost acl]$ echo 'test' > file-mask
27-bash: file-mask: Permission denied

在设置用户的ACL 权限时,除了看 “ user:对应的用户 ” 指定的权限外,还要看mask的权限值 。用户实际具有的权限为#effective后面标记的权限(即user权限与mask权限的交集--最小权限)。这里讲起来有些绕口,实际查看时如果有effective项,则用户权限以该字段后面的权限为准。

6、-R递归

使用-R参数时,这可以chmod 和chown 使用-R 参数的效果一样,递归目录下的所有文件和目录的权限。

 1[root@localhost /]# cd acl/
 2[root@localhost acl]# ll
 3total 0
 4[root@localhost acl]# mkdir dir1
 5[root@localhost acl]# touch file1
 6[root@localhost /]# setfacl -Rm u:user1:rwx /acl
 7[root@localhost /]# cd acl/
 8[root@localhost acl]# ls
 9dir1  file1
10[root@localhost acl]# getfacl file1
11# file: file1
12# owner: root
13# group: root
14user::rw-
15user:user1:rwx
16group::r--
17mask::rwx
18other::r--
19[root@localhost acl]# getfacl dir1/
20# file: dir1/
21# owner: root
22# group: root
23user::rwx
24user:user1:rwx
25group::r-x
26mask::rwx
27other::r-x

7、-X权限

在基本的rwx权限之外,acl 里还有一个参数X(大写字母x),其主要在递归设置ACL时用到,其表示如果文件没有执行权限时,则只设置目录的执行权限,而不增加文件的执行权限。该处与chmod下的X相同。

 1[root@localhost acl]# ll
 2total 0
 3drw-------. 2 root root 6 Aug  4 23:51 dir1
 4-rw-r--r--. 1 root root 0 Aug  4 23:46 file1
 5-rwxr--r--. 1 root root 0 Aug  4 23:47 file2
 6[root@localhost /]# setfacl -Rm u:user1:rwX /acl
 7[root@localhost /]# cd acl/
 8[root@localhost acl]# getfacl file2
 9# file: file2
10# owner: root
11# group: root
12user::rwx
13user:user1:rwx
14group::r--
15mask::rwx
16other::r--
17[root@localhost acl]# getfacl file1
18# file: file1
19# owner: root
20# group: root
21user::rw-
22user:user1:rw-
23group::r--
24mask::rw-
25other::r--
26[root@localhost acl]# getfacl dir1/
27# file: dir1/
28# owner: root
29# group: root
30user::rw-
31user:user1:rwx
32group::---
33mask::rwx
34other::---

从上面可以看到我创建的两个文件和一个目录。文件和目录我分别设置了相应的权限。在通过大X执行后,getfacl 查看到权限可以发现,如果之前文件属主没有x权限,增加的acl 里对应的用户也不具有x 权限 ;如果属主具有x权限,相应的user1也有x权限;目录则不同,尽管属主root没有x权限,user1确依然有x权限。

8、其他

 1备份权限
 2# getfacl -R /dir >permacl
 3利用上面的备份,恢复权限
 4# setfacl --set-file=permacl
 5# setfacl --restore permacl
 6设定B文件的ACL规则与A文件的相同(ACL复制)
 7# getfacl filea | setfacl --set-file=- fileb
 8上面的" - " 指定了getfacl的stdout为当前的stdin传参
 9删除用户或组的ACL权限
10# setfacl -x u:username,g:groupname file
11删除所有的ACL规则
12# setfacl -b file

注:使用cp -p 或mv 对设置为acl 的文件进行移动操作时,ACL权限也会跟随移动,但目录挂载点不支持ACL规则除外。默认使用tar 打包文件时不会记录ACL规则,所以解包的后的文件不再有ACL规则。可以使用star 打包ACL 文件和目录:

1[root@361way acl]# star -Hexustar -zv -acl -c f=file.star.gz *
2a file1 0 bytes, 0 tape blocks
3a hoho directory
4star: 1 blocks + 0 bytes (total of 10240 bytes = 10.00k).
5解包方法:
6[root@361way acl]# star -acl -zvx f=file.star.gz

三、chattr 与 sticky 、ACL

1、chattr与lsattr

chattr是由Linux内核版本来支持的 ,与chmod这个命令相比,chmod只是改变文件的读写、执行权限,更底层的属性控制是由chattr来改变的。使用chattr锁定文件时,连root都无法对文件操作。所以其对权限的控制最强。

chattr命令的用法:chattr [ -RVf ] [ -v version ] [ mode ] files…

最关键的是在[mode]部分,[mode]部分是由+-=和[ASacDdIijsTtu]这些字符组合的。其对应的参数有:

 1+ :在原有参数设定基础上,追加参数。
 2- :在原有参数设定基础上,移除参数。
 3= :更新为指定参数设定。
 4A:文件或目录的 atime (access time)不可被修改(modified), 可以有效预防例如手提电脑磁盘I/O错误的发生。
 5S:硬盘I/O同步选项,功能类似sync。
 6a:即append,设定该参数后,只能向文件中添加数据,而不能删除,多用于服务器日志文件安全,只有root才能设定这个属性。
 7c:即compresse,设定文件是否经压缩后再存储。读取时需要经过自动解压操作。
 8d:即no dump,设定文件不能成为dump程序的备份目标。
 9i:设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容。i参数对于文件 系统的安全设置有很大帮助。
10j:即journal,设定此参数使得当通过mount参数:data=ordered 或者 data=writeback 挂 载的文件系统,文件在写入时会先被记录(在journal中)。如果filesystem被设定参数为 data=journal,则该参数自动失效。
11s:保密性地删除文件或目录,即硬盘空间被全部收回。
12u:与s相反,当设定为u时,数据内容其实还存在磁盘中,可以用于undeletion。

各参数选项中常用到的是a和i。a选项强制只可添加不可删除,多用于日志系统的安全设定。而i是更为严格的安全设定,只有superuser (root) 或具有CAP_LINUX_IMMUTABLE处理能力(标识)的进程能够施加该选项。

示例:

1[root@361way tmp]# chattr  +i passwd
2[root@361way tmp]# lsattr passwd
3----i--------e- passwd
4[root@361way tmp]# echo 'aaa' >> passwd
5-bash: passwd: Permission denied
6[root@361way tmp]# chattr  -i passwd
7[root@361way tmp]# lsattr passwd
8-------------e- passwd
9[root@361way tmp]# echo 'aaa' >> passwd

用mv /etc/passwd等命令操作于该文件,都是得到Operation not permitted 的结果。vim编辑该文件时会提示W10: Warning: Changing a readonly file错误。要想修改此文件就要把i属性去掉: chattr -i /etc/passwd 。

 1[root@361way tmp]# touch test.log
 2[root@361way tmp]# chattr +a test.log
 3[root@361way tmp]# echo 'www.361way' >> test.log
 4[root@361way tmp]# echo 'www.361way' > test.log
 5-bash: test.log: Operation not permitted
 6[root@361way tmp]# echo 'test' >> test.log
 7[root@361way tmp]# rm -rf test.log
 8rm: cannot remove `test.log': Operation not permitted
 9[root@361way tmp]# lsattr test.log
10-----a-------e- test.log

注:chattr命令修改属性能够提高系统的安全性,但是它并不适合所有的目录。chattr命令不能保护/、/dev、/tmp、/var目录

2、chattr 与 sticky 、ACL总结

上面提到的无论是sticky、ACL、chattr 都可以设置文件或目录无法删除的保护权限。不同的是:

1、sticky 只能对owner、group、other 设置粘滞位(t 权限),设置后其他用户无法删除,但root用户与属主用户可以正常的进行删除 。而且基属于在标准权限设置,所以比较局限;

2、ACL可以针对每个用户每个组单独的设置权限,权限为设置的比较灵活,在某些情况下对父目录普通用户确实无法正常删除,但root和属主用户一样可以删除;

3、chattr 功能比较单一,但其安全性较强,专注于权限设置,设置后其自己都不能进行删除操作。

综合来说,linux 对文件和目录的权限设置是比较灵活的,三者各有所长,组合互补情况下可以方便应对不同的场景下的需求。