[linux 文件权限]linux中文件权限与ACL的深入分析

更新时间:2019-12-18    来源:linux    手机版     字体:

【www.bbyears.com--linux】

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 对文件或目录进行权限更改。权限的设置有两种表示方式:

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

2、umask

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

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

3、特殊权限

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

sticky

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

设置suid:    $ chmod  u+s  test
设置sgid:    $ chmod  g+s  test
设置sticky:  $ chmod  o+t  test
suid:4
sgid:2
sticky:1
在一些特殊情况下会用到特殊权限位,如passwd命令,如果没有s权限,其他用户会无法使用passwd命令修改自己的密码。

[root@361way etc]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10  2014 /usr/bin/passwd
下面给一个增加了s s t 权限的示例:

[root@361way tmp]# touch test
[root@361way tmp]# ll test
-rw-r--r--. 1 root root   0 Aug  5 01:03 test
[root@361way tmp]# chmod 7777 test
[root@361way tmp]# ll test
-rwsrwsrwt. 1 root root   0 Aug  5 01:03 test
[root@361way tmp]# su - usera
[usera@361way ~]$ cd /tmp/
[usera@361way tmp]$ echo "www.361way.com" > test
[usera@361way tmp]$ cat test
www.361way.com
[usera@361way tmp]$ rm -rf test
rm: 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参数挂载才行。如:

# mount -t ext3 -o remount,acl /home

# mount -o acl /dev/sdb /data
2、ACL设置与命令

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

[root@361way acl]# ll
total 4
-rw-rwxr--+ 1 root root 5 Aug  4 21:08 a
[root@361way acl]# getfacl a
# file: a
# owner: root
# group: root
user::rw-
user:mysql:rwx
group::r--
mask::rwx
other::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命令可以识别以下格式的规则:

[d[efault]:] u[ser]:uid [:perms] 指定用户的权限,文件所有者的权限(如果uid没有指定)。
[d[efault]:] g[roup]:gid [:perms] 指定群组的权限,文件所有群组的权限(如果gid未指定)
[d[efault]:] m[ask][:] [:perms] 有效权限掩码
[d[efault]:] o[ther] [:perms] 其他的权限
下面我们看一些具体的示例和用法

3、-m 设置权限

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

[root@localhost acl]# setfacl  -m u:user1:rw a
[root@localhost acl]# getfacl a
# file: a
# owner: root
# group: root
user::rw-
user:user1:rw-
group::r--
mask::rw-
other::r--
上面的设置是最简单的设置,具体指定时,我们也可以像chmod命令使用一样,同时指定多个权限:

[root@localhost acl]# setfacl  -m u:user1:rw,g:test:rx  file1
注:需要注意的是,这里虽然给了文件相应的读写执行权限,不过user1用户可以读写执行文件a ,但无法删除该文件,想要删除该文件,需要其原属主root进行删除。

[user1@localhost acl]$ rm -rf a
rm: cannot remove ‘a’: Permission denied
4、default 默认权限

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

[root@localhost acl]# setfacl  -m d:u:user1:rw file1
setfacl: file1: Only directories can have default ACLs
default权限设置过的目录,默认对该目录下已经存在的文件和目录都不具备读写权限,而对于设置权限以后的目录有相应的设置权限。

[root@localhost ~]# setfacl  -m d:u:user1:rwx acl/
#之前已经存在的目录和文件都没有权限
[root@localhost /]# su - user1
[user1@localhost acl]$ ll
-rw-r--r--. 1 root root 0 Aug  4 23:08 filea
drwxr-xr-x. 2 root root 6 Aug  4 22:59 dir1
[user1@localhost acl]$ touch file1
touch: cannot touch ‘file1’: Permission denied
[user1@localhost acl]$ mkdir dir2
mkdir: cannot create directory ‘dir2’: Permission denied
[user1@localhost acl]$ cd dir1/
[user1@localhost dir1]$ ll
total 0
[user1@localhost dir1]$ touch file1
touch: cannot touch ‘file1’: Permission denied
[user1@localhost acl]$ echo "aaa" > filea
-bash: filea: Permission denied
#新创建的子目录有权限
[root@localhost acl]# mkdir dir2
[root@localhost acl]# su - user1
[user1@localhost ~]$ cd /acl/
[user1@localhost acl]$ ll
total 4
drwxr-xr-x. 2 root root 6 Aug  4 22:59 dir1
drwxrwxr-x+ 2 root root 6 Aug  4 23:04 dir2
[user1@localhost acl]$ cd dir2/
[user1@localhost dir2]$ touch file1
[user1@localhost dir2]$ ll
total 4
-rw-rw-r--+ 1 user1 user1 0 Aug  4 23:04 file1
5、mask参数

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

[root@localhost /]# cd acl/
[root@localhost acl]# touch file-mask
[root@localhost acl]# setfacl -m u:user1:rwx file-mask
[root@localhost acl]# getfacl file-mask
# file: file-mask
# owner: root
# group: root
user::rw-
user:user1:rwx
group::r--
mask::rwx
other::r--
[root@localhost acl]# setfacl -m m:r file-mask
[root@localhost acl]# getfacl file-mask
# file: file-mask
# owner: root
# group: root
user::rw-
user:user1:rwx                  #effective:r--
group::r--
mask::r--
other::r--
[root@localhost acl]# su - user1
Last login: Tue Aug  4 23:09:06 CST 2015 on pts/0
[user1@localhost ~]$ cd /acl/
[user1@localhost acl]$ echo "test" > file-mask
-bash: file-mask: Permission denied
在设置用户的ACL 权限时,除了看 “ user:对应的用户 ” 指定的权限外,还要看mask的权限值 。用户实际具有的权限为#effective后面标记的权限(即user权限与mask权限的交集--最小权限)。这里讲起来有些绕口,实际查看时如果有effective项,则用户权限以该字段后面的权限为准。

6、-R递归

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

[root@localhost /]# cd acl/
[root@localhost acl]# ll
total 0
[root@localhost acl]# mkdir dir1
[root@localhost acl]# touch file1
[root@localhost /]# setfacl -Rm u:user1:rwx /acl
[root@localhost /]# cd acl/
[root@localhost acl]# ls
dir1  file1
[root@localhost acl]# getfacl file1
# file: file1
# owner: root
# group: root
user::rw-
user:user1:rwx
group::r--
mask::rwx
other::r--
[root@localhost acl]# getfacl dir1/
# file: dir1/
# owner: root
# group: root
user::rwx
user:user1:rwx
group::r-x
mask::rwx
other::r-x
7、-X权限

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

[root@localhost acl]# ll
total 0
drw-------. 2 root root 6 Aug  4 23:51 dir1
-rw-r--r--. 1 root root 0 Aug  4 23:46 file1
-rwxr--r--. 1 root root 0 Aug  4 23:47 file2
[root@localhost /]# setfacl -Rm u:user1:rwX /acl
[root@localhost /]# cd acl/
[root@localhost acl]# getfacl file2
# file: file2
# owner: root
# group: root
user::rwx
user:user1:rwx
group::r--
mask::rwx
other::r--
[root@localhost acl]# getfacl file1
# file: file1
# owner: root
# group: root
user::rw-
user:user1:rw-
group::r--
mask::rw-
other::r--
[root@localhost acl]# getfacl dir1/
# file: dir1/
# owner: root
# group: root
user::rw-
user:user1:rwx
group::---
mask::rwx
other::---
从上面可以看到我创建的两个文件和一个目录。文件和目录我分别设置了相应的权限。在通过大X执行后,getfacl 查看到权限可以发现,如果之前文件属主没有x权限,增加的acl 里对应的用户也不具有x 权限 ;如果属主具有x权限,相应的user1也有x权限;目录则不同,尽管属主root没有x权限,user1确依然有x权限。

8、其他

备份权限
# getfacl -R /dir >permacl
利用上面的备份,恢复权限
# setfacl --set-file=permacl
# setfacl --restore permacl
设定B文件的ACL规则与A文件的相同(ACL复制)
# getfacl filea | setfacl --set-file=- fileb
上面的" - " 指定了getfacl的stdout为当前的stdin传参
删除用户或组的ACL权限
# setfacl -x u:username,g:groupname file
删除所有的ACL规则
# setfacl -b file
注:使用cp -p 或mv 对设置为acl 的文件进行移动操作时,ACL权限也会跟随移动,但目录挂载点不支持ACL规则除外。默认使用tar 打包文件时不会记录ACL规则,所以解包的后的文件不再有ACL规则。可以使用star 打包ACL 文件和目录:

[root@361way acl]# star -Hexustar -zv -acl -c f=file.star.gz *
a file1 0 bytes, 0 tape blocks
a hoho directory
star: 1 blocks + 0 bytes (total of 10240 bytes = 10.00k).
解包方法:
[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]这些字符组合的。其对应的参数有:

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

示例:

[root@361way tmp]# chattr  +i passwd
[root@361way tmp]# lsattr passwd
----i--------e- passwd
[root@361way tmp]# echo "aaa" >> passwd
-bash: passwd: Permission denied
[root@361way tmp]# chattr  -i passwd
[root@361way tmp]# lsattr passwd
-------------e- passwd
[root@361way tmp]# echo "aaa" >> passwd
用mv /etc/passwd等命令操作于该文件,都是得到Operation not permitted 的结果。vim编辑该文件时会提示W10: Warning: Changing a readonly file错误。要想修改此文件就要把i属性去掉: chattr -i /etc/passwd 。

[root@361way tmp]# touch test.log
[root@361way tmp]# chattr +a test.log
[root@361way tmp]# echo "www.361way" >> test.log
[root@361way tmp]# echo "www.361way" > test.log
-bash: test.log: Operation not permitted
[root@361way tmp]# echo "test" >> test.log
[root@361way tmp]# rm -rf test.log
rm: cannot remove `test.log": Operation not permitted
[root@361way tmp]# lsattr test.log
-----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 对文件和目录的权限设置是比较灵活的,三者各有所长,组合互补情况下可以方便应对不同的场景下的需求。

本文来源:http://www.bbyears.com/caozuoxitong/82961.html