文件权限与归属
文件特殊权限
SUID
SUID是一种对二进制程序(如命令)进行设置的特殊权限,能够让二进制程序的执行者临时拥有所有者的权限(仅对拥有执行权限的二进制程序有效)。
例如,所有用户都可以执行passwd命令来修改自己的用户密码,而用户密码保存在/etc/shadow文件中。仔细查看这个文件就会发现它的默认权限是000,也就是说除了root管理员以外,所有用户都没有查看或编辑该文件的权限。但是,在使用passwd命令时如果加上SUID特殊权限位,就可让普通用户临时获得程序所有者的身份,把变更的密码信息写入到shadow文件中。
[root@linuxprobe ~]# ls -l /etc/shadow ----------. 1 root root 1312 Jul 21 05:08 /etc/shadow [root@linuxprobe ~]# ls -l /bin/passwd -rwsr-xr-x. 1 root root 34512 Aug 13 2018 /bin/passwd //所有者的权限由rwx变成了rws
SGID
SGID特殊权限有两种应用场景:当对二进制程序进行设置时,能够让执行者临时获取文件所属组的权限;当对目录进行设置时,则是让目录内新创建的文件自动继承该目录原有用户组的名称。
[root@superwu10 ~]# ll /usr/bin/locate
-rwx--s--x. 1 root slocate 47128 Aug 12 2018 /usr/bin/locate //除了root管理员或属于 slocate组的成员外,所有用户都没有读取该文件的权限。增加了SGID特殊权限位后,当用户执行该命令时,也就临时获取到了slocate用户组的权限,从而顺利地读取到了设备文件。
如果现在需要在一个部门内设置共享目录,让部门内的所有人员都能够读取目录中的内容,那么就可以在创建部门共享目录后,在该目录上设置SGID特殊权限位。这样,部门内的任何人员在里面创建的任何文件都会归属于该目录的所属组,而不再是自己的基本用户组。
[root@linuxprobe ~]# cd /tmp
[root@linuxprobe tmp]# mkdir testdir
[root@linuxprobe tmp]# ls -ald testdir
drwxr-xr-x. 2 root root 6 Oct 27 23:44 testdir //该目录所属组是root
[root@linuxprobe tmp]# chmod -R 777 testdir
[root@linuxprobe tmp]# chmod -R g+s testdir //对目录设置sgid权限
[root@linuxprobe tmp]# ls -ald testdir
drwxrwsrwx. 2 root root 6 Oct 27 23:44 testdir
[root@linuxprobe tmp]# su - linuxprobe [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 Oct 27 23:47 test //linuxprobe用户在有sgid权限的目录中创建文件或目录时,创建的文件或目录的所属组会自动继承所属目录的所属组。
chown命令
用于设置文件的所有者和所有组,英文全称为change own,语法格式为“chown所有者:所有组 文件名”。
[root@linuxprobe ~]# chown linuxprobe:linuxprobe anaconda-ks.cfg [root@linuxprobe ~]# ls -l anaconda-ks.cfg -rwxrw----. 1 linuxprobe linuxprobe 1407 Jul 21 05:09 anaconda-ks.cfg
SBIT
SBIT特殊权限位可确保用户只能删除自己的文件,而不能删除其他用户的文件。
例如zhangsan用户在tmp目录下创建了一个文件,并将权限设置为777(权限全开),此时用户linuxprobe还是无法删除zhangsan创建的文件。
[root@linuxprobe ~]# ls -ald /tmp //tmp目录是一个有SBIT权限的目录
drwxrwxrwt. 17 root root 4096 Oct 28 00:29 /tmp
[zhangsan@superwu10 tmp]$ touch zhangsan
[zhangsan@superwu10 tmp]$ chmod 777 zhangsan
[zhangsan@superwu10 tmp]$ ls -l
total 0
-rwxrwxrwx. 1 zhangsan zhangsan 0 Jan 25 02:21 zhangsan
[linuxprobe@superwu10 tmp]$ rm -f zhangsan
rm: cannot remove 'zhangsan': Operation not permitted
SUID、SGID、SBIT特殊权限的设置参数
参数 | 作用 |
u+s | 设置SUID权限 |
u-s | 取消SUID权限 |
g+s | 设置SGID权限 |
g-s | 取消SGID权限 |
o+t | 设置SBIT权限 |
o-t | 取消SBIT权限 |
文件的隐藏属性
文件的隐藏属性,使用常规的ls命令不能看到它的真面目。隐藏权限的专用设置命令是chattr,专用查看命令是lsattr。
在Linux系统中,文件的隐藏权限必须使用lsattr命令来查看,平时使用的ls之类的命令则看不出。
注意:隐藏权限只有管理员root可以设置,普通用户只可以使用lsattr查看文件是否被设置了隐藏权限。
chattr、lsattr命令
用于设置文件的隐藏权限,英文全称为change attributes,语法格式为“chattr [参数] 文件名称”。
如果想要把某个隐藏功能添加到文件上,则需要在命令后面追加“+参数”,如果想要把某个隐藏功能移出文件,则需要追加“-参数”。
chattr命令中的参数及其作用
i | 无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件 |
a | 仅允许补充(追加)内容,无法覆盖/删除内容(Append Only) |
S | 文件内容在变更后立即同步到硬盘(sync) |
s | 彻底从硬盘中删除,不可恢复(用0填充原文件所在硬盘区域) |
A | 不再修改这个文件或目录的最后访问时间(atime) |
b | 不再修改文件或目录的存取时间 |
D | 检查压缩文件中的错误 |
d | 使用dump命令备份时忽略本文件/目录 |
c | 默认将文件或目录进行压缩 |
u | 当删除该文件后依然保留其在硬盘中的数据,方便日后恢复 |
t | 让文件系统支持尾部合并(tail-merging) |
x | 可以直接访问压缩文件中的内容 |
例如:管理员对普通用户的文件设置了隐藏权限,即使用户本身也是无法更改的。
[root@superwu10 zhangsan]# ll
total 4
-rw-rw-r--. 1 zhangsan zhangsan 16 Jan 25 19:05 chattr.test
[root@superwu10 zhangsan]# chattr +a chattr.test //对zhangsan的文件添加a隐藏权限
[root@superwu10 zhangsan]# lsattr chattr.test
-----a------------ chattr.test
[root@superwu10 zhangsan]# su - zhangsan
[zhangsan@superwu10 ~]$ echo eihei > chattr.test //zhangsan自己无法覆盖文件内容
-bash: chattr.test: Operation not permitted
[zhangsan@superwu10 ~]$ rm -f chattr.test //zhangsan无法删除自己的文件
rm: cannot remove 'chattr.test': Operation not permitted
[zhangsan@superwu10 ~]$ chattr -a chattr.test //zhangsan无法取消隐藏权限(普通用户无法设置)
chattr: Operation not permitted while setting flags on chattr.test
[zhangsan@superwu10 ~]$ echo nihao >> chattr.test //a权限只能追加内容
[root@superwu10 zhangsan]# chattr -a chattr.test //取消隐藏权限
文件访问控制列表
对某个指定的用户进行单独的权限控制,就需要用到文件的访问控制列表(ACL)了。
通俗来讲,基于普通文件或目录设置ACL其实就是针对指定的用户或用户组设置文件或目录的操作权限,更加精准地派发权限。另外,如果针对某个目录设置了ACL,则目录中的文件会继承其ACL权限;若针对文件设置了ACL,则文件不再继承其所在目录的ACL权限。
注意:setfacl需使用管理员账户root进行设置。
setfacl、getfacl命令
setfacl命令用于管理文件的ACL权限规则,英文全称为“set files ACL”,语法格式为“setfacl [参数] 文件名称”。
setfacl命令中的参数以及作用
-m | 修改权限 |
-M | 从文件中读取权限 |
-x | 删除某个权限 |
-b | 删除全部权限 |
-R | 递归子目录 |
getfacl命令用于查看文件的ACL权限规则,英文全称为“get files ACL”,语法格式为“getfacl [参数] 文件名称”。
例如,zhangsan用户是不能访问lisi用户的家目录的,通过设置acl让zhangsan用户可以访问lisi的家目录。
[root@superwu lisi]# setfacl -Rm u:zhangsan:rwx /home/lisi/ //-R递归子目录,-Rm一同使用时需将R写在前面,让zhangsan用户有lisi家目录的rwx权限。
[root@superwu ~]# ll /home/
total 0
drwx------. 3 linuxprobe linuxprobe 78 Jan 11 16:39 linuxprobe
drwxrwx---+ 3 lisi lisi 131 Jan 28 17:30 lisi //lisi目录中的(.)已经变成了(+),说明此目录被设置了acl。
drwx------. 3 zhangsan zhangsan 99 Jan 28 17:14 zhangsan
[root@superwu ~]# getfacl /home/lisi //查看lisi目录文件的ACL
getfacl: Removing leading '/' from absolute path names
# file: home/lisi
# owner: lisi
# group: lisi
user::rwx
user:zhangsan:rwx //增加了一个zhangsan用户和rwx权限
group::---
mask::rwx
other::---
[root@superwu ~]# su - zhangsan
[zhangsan@superwu ~]$ cd /home/lisi/
[zhangsan@superwu lisi]$ ll //此时zhangsan用户是可以读写lisi的家目录的。
total 8
-rw-rw-r--. 1 lisi lisi 5 Jan 28 17:30 haha.txt
-rw-rwxr--+ 1 lisi lisi 5 Jan 28 17:24 hehe.txt
[root@superwu lisi]# setfacl -x u:zhangsan /home/lisi/haha.txt //删除一条权限-x
[root@superwu ~]# setfacl -b u:zhangsan /home/lisi //删除全部权限-b
ACL权限还可以针对某个用户组进行设置。例如,允许某个组的用户都可以读写/etc/fstab文件:
[root@linuxprobe ~]# setfacl -m g:linuxprobe:rw /etc/fstab [root@linuxprobe ~]# getfacl /etc/fstab getfacl: Removing leading '/' from absolute path names # file: etc/fstab # owner: root # group: root user::rw- group::r-- group:linuxprobe:rw- mask::rw- other::r--
ACL权限的设置都是立即且永久生效的,不需要再编辑什么配置文件,这一点特别方便。但是,这也带来了一个安全隐患。如果我们不小心设置错了权限,就会覆盖掉文件原始的权限信息,并且永远都找不回来了。
操作前备份一下,总是好的习惯
例如,在备份/home目录上的ACL权限时,可使用-R递归参数,这样不仅能够把目录本身的权限进行备份,还能将里面的文件权限也自动备份。另外,再加上第3章学习过的输出重定向操作,可以轻松实现权限的备份。需要注意,getfacl在备份目录权限时不能使用绝对路径的形式,因此我们需要先切换到最上层根目录,然后再进行操作。
[root@linuxprobe ~]# cd / [root@linuxprobe /]# getfacl -R home > backup.acl [root@linuxprobe /]# ls -l -rw-r--r--. 1 root root 834 Jul 18 14:14 backup.acl
ACL权限的恢复也很简单,使用的是--restore参数。由于在备份时已经指定是对/home目录进行操作,所以不需要写对应的目录名称,它能够自动找到要恢复的对象:
[root@linuxprobe /]# setfacl --restore backup.acl