权限管理这方面,非常清楚地记得刚开始实习那会儿是仔细研究过的,不知道为什么没有笔记留痕。。除了一些基本的知识点早就忘光了,无奈只好从头开始学习一遍。。
■基本权限知识
这部分实在是比较基础,不想多讲了。主要就是9格权限的理解。搞清楚读权限、写权限和执行权限对于文件和目录来说分别以为着什么,就可以了。下面是一些以前没怎么注意,今天听完培训之后觉得有些意思的点:
● 管理权限的权限
文件权限信息和其他文件信息一样,并不属于文件内容的一部分,而基本的权限是针对文件内容而言的。比如说:
-rwxrwxrwx 1 zabbix zabbix 0 8月 11 14:01 file1
这个file1属于zabbix,而其权限是最开放的777,另一个非root用户比如user1可以读取,修改,执行这个文件,但是user1仍然没有权限对file1进行chmod,chown等操作。一般而言,对某个文件或目录有chmod,chown权限的用户只有root和该文件/目录的所有者。所以说在linux中,应该还存在一种管理权限的权限机制,只不过这种机制没有开放接口给用户修改使用而已。
● 多层级目录的权限按就近原则
对于多层的目录,可能存在这样一种情况:one/two/three/file 对于目录one,three和文件file,用户都是有权限的,而对于two目录,用户没有执行权限的话(即使他有读写权限),也是无法获得level_three以及file的信息和内容的,甚至无法往level_two目录下level_three目录的同级创建删除文件。因为系统默认,如果要读取或修改目录下的内容,一定要先进入目录,这和我感觉中的是不一样的。因为需要进入目录,自然就要求要有x权限,否则一切都是抓瞎白谈。
可以指出的一点是,上面这个例子,如果用户在one这个目录下ll目录two中的内容,会看到这样一幅场景:
可以看到,three目录和与three同级的文件testfile(再强调一次,和这两者的具体权限无关)被显示了出来,但是也提示了权限不够且显示出来两者的信息是很有限的(仅名字而已)。至于想看three里面的是不可能的了。
● passwd中的uid就代表了用户是谁
这点在用户管理哪一篇文章中应该也提到过。核心要义就是,Linux中,大部分用户识别的工作都是靠了uid这个数字,而不是用户名。所以如果我们把passwd中的某一个用户的uid改成0(root的uid),那么他就成了root用户,可以在很多地方直接按root权限干事情了。
● chage命令的使用
众所周知passwd可以用来修改自己的密码,如果是root的话还可以利用这个命令来修改所有用户的密码。但是这个密码的很多配置选项都是默认选项。如果需要进一步细化密码配置的话就要用到chage这个命令了。在其他地方说不定也说过了,chage命令的基础是/etc/shadow这个文件。而通过chage获得的信息以及chage要修改的基本上也都是这个shadow文件。shadow文件的说明写在用户管理那一章里了,至于chage的基本使用如下:
$chage [-ldEImMW] <username>
参数:
-l 列出该账号所有的密码配置
-d 接日期 修改shadow的第三字段(最近一次更改密码的日期)
-E 接日期 修改shadow的第八字段(账号失效日)
-I 接天数 修改shadow的第七字段(密码失效日期)
-m 接天数 修改shadow的第四字段(密码最短保留天数)
-M 接天数 修改shadow的第五字段(密码多久后需要修改)
-W 接天数 修改shadow的第六字段(密码过期前警告日期)
■稍微深入一点的权限知识
基本权限知识在八成的场合下都够用了,再权限控制需求更加复杂的权限管理手段。下面来讲几个linux常常可以听到,偶尔也会用到的权限管理方面的内容。
● umask默认权限
在用户创建默认文件/目录时,会自动赋这个文件/目录一定的权限。这个默认值就由umask来控制。默认情况下的umask是0022,第一位0是留给特殊权限SUID,SBIT这些的,先不管。后三位分别对应了owner,group和others。
需要注意的是,新文件和新目录的umask基准值不一样。对于用户创建的文件,基准值是666,所以在022的umask下创建的新文件默认的权限是644。而用户创建新目录时基准值是777,所以在022umask下的新目录默认权限是755。
● chattr,lsattr
注意,这两个命令只在部分文件系统上有效。且据说chattr不对/,/var,/dev等目录下的文件起作用。
文件可以通过chattr和lsattr来进行隐藏权限属性的管理。所谓隐藏属性,就是默认情况下,所有新建的文件和目录都没有的,需要用户根据需要自己精细化设置的权限管理手段。之前培训也没有讲到这块内容,但是我一看发现还是很有用的!
先来看下lsattr把。lsattr <文件名>可以查看一个文件/目录的所有隐藏权限,如果不带文件名参数,则给出当前目录下所有文件/目录的隐藏属性信息。因为默认情况下隐藏权限是全空的,所以我们通常看到的是一马平川:
[root@localhost tmp]# lsattr
---------------- ./test.py
---------------- ./demofile
---------------- ./uwsgiconfig.ini
---------------- ./libcurl-devel-7.29.0-35.el7.centos.i686.rpm
---------------- ./libcurl-devel-7.29.0-35.el7.centos.x86_64.rpm
---------------- ./systemd-private-ca6e7179ff254d749f6efc37e1a66006-httpd.service-gSl2nW
---------------- ./test.c
---------------- ./file1
---------------- ./level_one
---------------- ./test
再来看看chattr的用法:
chattr [+-=] [ASacdistu] <文件名或目录名>
+,- 后面跟一个字母参数,表明为目标文件增加或减去一个隐藏属性
-R可以递归地设置目录下所有文件的隐藏属性,一定要写在“+-属性”前面。
A:设置了A属性后,访问该文件不会修改访问时间atime,对于需要频繁I/O的文件而言,加上这个属性可以提高IO效率
S:一般写入文件都是异步的(经过缓存),如果加上这个隐藏属性则写入磁盘操作是同步的
a:设置了a之后,这个文件将只能增加数据,不能修改或减少数据。只有root用户可以设置这个属性
c:设置了c属性的文件会自动压缩文件,以压缩状态存储在磁盘上,当读取时自动解压缩。对于内存充足但是磁盘捉急的情况适用
d:设置了d属性的文件不被dump程序备份
i:设置了i属性的文件将无法被删除(即使是root用户删),也无法修改其内容,在保证重要文件的安全性方面有很大作用,只有root用户可以设置这个属性
u:设置了u属性的文件被删除之后并不会从硬盘上抹去,而是可以通过一定手段找回来(什么手段我也不知道。。)
其中当属i属性和a属性有用,特别是保证系统安全性方面。由于是隐藏属性,具有很大的隐蔽性,所以有时候会引起意想不到的问题。比如突然碰到了无论如何都无法删除的文件时。。就可以想想是不是隐藏属性的问题。这也从反面说明,在设置隐藏属性的时候一定要慎重&留痕,别心血来潮一设置,以后想都想不起来了。
■SUID,SGID和SBIT
这方面内容在杂乱笔记中有简单说明过。现在再来明确一下。
● SUID
SUID,表现在文件所有者的执行权限位上显示为s。SUID权限只对二进制文件有效(判断是不是二进制文件可以通过file <filename>来查看,像我之前认为的.py,.sh什么的加上x权限就是二进制文件了是不对的。。像用gcc编译出来的东西才是真的二进制文件)。
s权限的具体含义是,当某个文件的拥有者执行权限位是s的话,其他用户执行这个二进制时,在执行期间,用户获得文件拥有者的权限。需要注意的是,执行程序的用户本身要对这个程序有x权限。如果一个属于root:root的文件的权限是-rws------,那么让一般用户来执行还是没有权限的。必须改成-rws-----x才可。
使用SUID的场景比较经典的有“有限制地对文件进行读写”。比如我有一个属于root的文件file,我希望其他用户可以在一定限制下对其进行读写。显然不能开放rw给他们。那么我可以这么做,将这个文件设置成只有root可读可写,然后写一个二进制程序(程序所有者得是root),在程序中做出读写的控制,而后把这个程序的所属者执行位设置为s。这样其他用户可以通过这个程序来对文件读写,做到了“有限制的读写”。这种做法有点类似于面向对象编程中的私有变量。不允许直接改变变量,但是留出setVar方法作为接口来改变变量值。事实上,linux中用户改密码的机制就是通过SUID来实现的。一般用户可以执行/usr/bin/passwd来改变自己的密码,不过密码信息都放在/etc/shadow里面,这个文件只有root可读可强制写。普通用户修改密码,即修改这个文件不能直接修改,只能通过/usr/bin/passwd这个二进制文件来进行,所以/usr/bin/passwd是具有SUID权限的一个文件。
增加SUID权限可以通过chmod 4xxx <文件名> 来进行。可以看到权限码的第四位出现了。也可以用chmod u+s <文件名> 的方法来添加SUID权限。
● SGID
SGID权限和SUID是类似的,无非是把“执行中具有文件所有者权限”改成了“执行中具有文件所有组的组员的权限”。也就是说SGID是类似于-rwxr-sr-x这种地方有个s权限。
另外SGID有一个挺大的不同在于它可以应用在目录上。对于目录而言其效果是:首先用户要有对这个目录的读和执行权限,这样才能保证他能够进到目录中,然后用户在此目录下的所有动作,其有效用户组都是该目录的用户组;再次,如果用户对该目录有w权限,那么用户创建的所有新文件的用户组都和这个目录的用户组相同。
● SBIT
SBIT权限只对目录有效,设置了SBIT的目录的效果是:前提条件还是一样的,用户需要对目录有w和x权限,也就是说用户有在这个目录下新建和删除文件的权限,然后特别的地方在于,用户在这个目录下只能删除自己创建的文件和目录,对于别人创建的是不能删除的。SBIT权限体现在10位权限符的第11位上是t。。比如这样的就是有SBIT权限的目录:drwxrwxrwxt。
以上三种特殊权限也有特别的编码方式,SUID是4,SGID是2,SBIT是1。把特殊权限放在权限符的第一位,就可以得到完整的权限符了比如chmod 4711就会把权限改成-rws--x--x。
■更精细的权限规划
以上的所有权限管理都还是基于用户和用户组的,而文件只能随之而动,不能做到不同文件间的权限的精细化。比如大多文件都适应group1中的user1,user2,user3的三个用户的权限,但是现有一个新文件要求即使在group1中也要细分,让user1,user2可读,user3不可读,这时就需要更加精细的权限管理工具了。这个工具就是ACL。
首先需要指出的是,ACL需要在挂载文件系统时指出该文件系统应该加入ACL支持。
和chattr,lsattr类似的,ACL有getfacl和setfacl来进行ACL权限的获取和设置。下面来详细看下两个命令的用法:
#setfacl [-bkRd] [{-m|-x} acl 参数] <文件名>
-m 赋予文件相关的acl参数,不能与-x同时设置
-x 删除文件相关的acl参数,不能与-m同用
-b 删除所有acl参数
-k 删除默认的acl参数
-R 递归设置ACL参数
-d 为一个目录设置默认的ACL参数,之后目录下新建的所有子目录(不包括文件)都会适用这个参数
上面也说过了,ACL是针对一个个用户精细设置权限的,所以也需要在使用命令时指出针对的用户或者用户组。一般而言,这个命令可以有以下几种比较常见的使用方法:
setfacl -m u:user1:rx file这个命令意义就是设置文件file针对用户user1的权限是r-x。设置成功之后,在ll文件的时候给出的权限界面在权限符的最后一位多出一个“+”,比如-rwxr-xr-x+。如果在ACL参数中以u开头( 表示针对单个用户)而后面又没有写用户名的话比如u::rwx,那就是默认针对文件所有者设置。当然,如果是针对文件所有者,通过ACL设置了权限的话,文件最终可能也不会展现那个+号,因为文件所有者的权限信息和管理通过传统的9格权限符已经可以得到展现,改变那部分就可以了。另外除了针对单个用户,还可以针对某个用户组来设置ACL权限。用法只不过是把ACL权限中的u:xx:xx改成g:xx:xx这样子。 再另外,除了u和g这两个ACL参数的开头之外,还有一种m开头的ACL参数。m是mask的意思,且用法是类似于m:rwx,中间不用接任何具体的用户或用户组,它的意思是为某个文件的ACL权限设置一个天花板,超出这个天花板的部分的权限将不被承认。比如某个文件被m:r 设置过了之后,后续再设置u:user:rwx,虽然可以设置成功,但是用户仍然对这个文件只有读权限(当然如果你是root用户,可以强制写就另当别论了)
对于权限信息中有+号的这些文件,我们可以用getfacl <filename>来获取它的ACL详细权限。对于设置的权限和mask冲突的,系统还会给出冲突的提示,告诉你实际上有效的权限是什么。