深入理解Linux中的文件权限

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解Linux中的文件权限相关的知识,希望对你有一定的参考价值。

Linux中文件权限

Linux中每个文件都有一个特定的拥有者(一般是创建它的用户)和所属用户组,这是它的固有属性。文件可以利用这两个固有属性来规定它的拥有者或者是所属用户组内的用户是否拥有对它的访问权利,即读、写和执行的权利。此外为了提高适应性,文件还规定了其他不相关的人等的访问权限,也就是第三个固有属性。这三个固有属性和三个权利合起来,就构成了文件针对系统中所有用户的访问控制,也就构成了Linux中的文件权限体系。


1.1 使用ls命令的-l选项查看root家目录,结果如下

[[email protected] ~]# ll
total6
lrwxrwxrwx. 1 root root     9 Apr  9 02:46 a -> test1.txt
drwxr-xr-x. 2 root root     6 Apr  9 05:22 day01
rw-r--r--. 1 root root 71680 Apr  2 22:52 demo01
rwxr-xr-x. 1 root root    18 Apr  9 02:59 test1.txt

1.2 单独拿出一行来分析,结果如下:

技术分享

图1 文件属性结构


1.3 文件权限和类型(图1中的第1个字段)

这些属性当中最重要的就是前面的文件类型和权限了,那么rwx代表什么呢?详见下图:

技术分享

图2 文件类型和权限


Linux中的权限控制是当某个用户需要访问某个文件时,系统就读取这个文件的属性和权限信息与当前的UID和GID进行对比,来确定当前用户是文件的拥有者还是其所属组的用户,或者是毫无关系。然后根据这些比对结果和用户执行的动作来判断是否满足权限要求。这也引出了文件权限与命令的一些关系,因为Linux系统中一个文件是否为可执行文件是通过属性来决定的,而不是后缀名。


首先说说“r”权限,顾名思义(read简写)

对目录而言,“r”表示的是遍历目录中的所有文件名和子目录名,仅仅是遍历文件名而已,并不是实际内容。

例:

[[email protected] demo2]$ ll
total 0
[[email protected] demo2]$ mkdir dir1  #在当前目录中创建目录dir1
[[email protected] demo2]$ ll
total 0
drwxrwxr-x. 2 user1 user1 6 Apr 10 00:30 dir1       #看出dir1的权限是775
[[email protected] demo2]$ touch ./dir1/a.txt ./dir1/b.txt    #在目录dir1中创建a和b两个文件
[[email protected] demo2]$ ll ./dir1/                
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 04:21 a.txt         #查看a和b文件
-rw-rw-r--. 1 user1 user1 0 Apr 10 04:21 b.txt
[[email protected] demo2]$ chmod -r dir1/            #去除dir1目录的“r”权限
[[email protected] demo2]$ ll
total 0
d-wx-wx--x. 2 user1 user1 32 Apr 10 04:21 dir1        #“r”权限去除成功
[[email protected] demo2]$ ll ./dir1/
ls: cannot open directory ./dir1/: Permission denied        #再次查看dir1中的内容被拒绝
                                                            #提示权限不够

#######这说明“r”权限在目录中的控制作用,要查看目录中文件列表,必须具有“r”权限


对于文件而言,“r”表示的是遍历文件中的实际内容,文件中不管有没有内容,拥有“r”权限,在操作的时候都会去遍历一遍。

例:

[[email protected] demo2]$ ll
total 0
[[email protected] demo2]$ echo "helloword" >aest.txt  #创建aest.txt文件,并写入内容
[[email protected] demo2]$ ll
total 4
-rw-rw-r--. 1 user1 user1 10 Apr 10 05:45 aest.txt    #查看aest.txt文件权限664

[[email protected] demo2]$ cat aest.txt     ##查看aest.txt文件的内容
helloword
[[email protected] demo2]$ chmod -r aest.txt         #去除aest.txt的“r”权限
[[email protected] demo2]$ ll
total 4                                            #“r”权限已被取消
--w--w----. 1 user1 user1 10 Apr 10 05:45 aest.txt
[[email protected] demo2]$ cat aest.txt         #再次查看aest.txt文件内容
cat: aest.txt: Permission denied        #访问被拒绝,提示权限不够


######这就是“r”权限对于文件的访问控制
######执行者要查看文件的内容,就必须具有该文件的“r”权限


接着说说“w”权限,(write的简写)

对目录而言,“w”权限就是说可以在该目录中修改信息,什么是修改信息呢?在目录中信息就是各种文件的名称,修改信息就是与该目录下的文件名或子目录名的变动有关的操作,注意:指的是名字。具体如下:

1)在该目录下新建新的文件或子目录。(就是增加文件名)

[[email protected] demo2]$ mkdir dir2;ll      #在demo2目录中创建dir2目录并查看其权限
total 0
drwxrwxr-x. 2 user1 user1 6 Apr 10 03:33 dir2        #当前dir2权限为775

[[email protected] demo2]$ touch ./dir2/a.txt;ll ./dir2/    #测试在dir2中创建a.txt文件
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 03:34 a.txt        #在dir2中成功创建a.txt文件

[[email protected] demo2]$ chmod -w dir2/          #去掉dir2目录的“w”权限
[[email protected] demo2]$ ll
total 0
dr-xr-xr-x. 2 user1 user1 19 Apr 10 03:34 dir2        #“w”权限去除成功

[[email protected] demo2]$ cd dir2/
[[email protected] dir2]$ touch b.txt            #再在dir2目录中创建b.txt文件
touch: cannot touch ‘b.txt’: Permission denied    #提示创建失败,权限不够

#######这就是“w”权限对在目录中添加文件的控制作用
#######要在目录中创建文件,执行者必须拥有该目录的“w”权限


2)删除该目录下已经存在的文件或子目录(不论该文件或子目录的权限如何),注意:这点很重要,用户能否删除一个文件或目录,看的是该用户是否具有该文件或目录所在的目录的w权限。

例:

[[email protected] demo2]$ ll    #查看dir2目录的权限
total 0
drwxrwxr-x. 2 user1 user1 36 Apr 10 08:48 dir2  #当前dir2的权限是775

[[email protected] demo2]$ ll ./dir2/    #查看dir2目录下的文件
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 a.txt
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 b.txt

[[email protected] demo2]$ rm -r dir2/a.txt     #删除dir2目录中的a.txt文件
[[email protected] demo2]$ ll dir2/    
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 b.txt    #dir2中的a.txt文件删除成功

[[email protected] demo2]$ chmod -w  dir2    #去除dir2目录的“w”权限
[[email protected] demo2]$ ll
total 0
dr-xr-xr-x. 2 user1 user1 19 Apr 10 09:01 dir2    #dir2的“w”权限去除成功

[[email protected] demo2]$ rm -r ./dir2/b.txt     #测试是否可以删除dir2目录下的b.txt文件
rm: cannot remove ‘./dir2/b.txt’: Permission denied    #删除失败,权限不够


######这就说明了“w”权限对删除目录中文件的控制作用
######要删除目录中的文件,执行者必须具有该目录的“w”权限


3)将该目录下已经存在的文件或子目录进行重命名。

[[email protected] demo2]$ ll        #显示当前目录下的dir2目录
total 0
drwxrwxr-x. 2 user1 user1 32 Apr 10 08:45 dir2        #dir2目录权限为775

[[email protected] demo2]$ ll ./dir2/        #显示dir2目录中的文件
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 a.txt
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 b.txt

[[email protected] demo2]$ mv ./dir2/a.txt ./dir2/a.new.txt     #修改dir2中的a.txt文件为a.new.txt
[[email protected] demo2]$ ll ./dir2/
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 a.new.txt    #修改成功
=-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 b.txt
[[email protected] demo2]$ chmod -w dir2/        #去除dir2目录的“w”权限
[[email protected] demo2]$ ll
total 0
dr-xr-xr-x. 2 user1 user1 36 Apr 10 08:48 dir2    #“w”权限去除成功

[[email protected] demo2]$ mv ./dir2/b.txt ./dir2/b.new.txt    #测试现在是否可以修改dir2目录中的b.txt文件名
mv: cannot move ‘./dir2/b.txt’ to ‘./dir2/b.new.txt’: Permission denied    #结果是拒绝修改!


#####这就说明“w”对目录中文件名的控制作用,执行者要修改目录下的文件名,必须拥有“w”权限



4)转移该目录内的文件或子目录的位置。

[[email protected] demo2]$ ll     #查看dir2目录的权限
total 0
drwxrwxr-x. 2 user1 user1 32 Apr 10 09:15 dir2    #dir2目录的权限为775

[[email protected] demo2]$ ll ./dir2/    #查看dir2目录中的文件
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 09:15 a.txt
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 b.txt

[[email protected] demo2]$ mv ./dir2/a.txt /tmp/    #将dir2中的a.txt文件移动到/tmp中去
[[email protected] demo2]$ ll ./dir2/
total 0
-rw-rw-r--. 1 user1 user1 0 Apr 10 08:45 b.txt    #成功将a.txt文件移动到/tmp中去了

[[email protected] demo2]$ chmod -w dir2/    #去除dir2目录的“w”权限
[[email protected] demo2]$ ll
total 0
dr-xr-xr-x. 2 user1 user1 19 Apr 10 09:15 dir2    #权限去除成功

[[email protected] demo2]$ mv ./dir2/b.txt /tmp/    #测试是否可以移动dir2目录下的b.txt文件
mv: cannot remove ‘./dir2/b.txt’: Permission denied #权限不够,不能移动


#####这就说明“w”权限对移动目录的控制,其实就和删除是一样的,
#####只要文件要离开这个目录,就必须有“w”权限


对文件而言,“w”权限是对文件内容的控制,只要修改文件内容,就必须要有“w”权限,比如vim,echo等命令对文本的修改,执行者就必须有“w”权限,否则是不可以编辑文件的!

例:

[[email protected] demo2]$ ll        #查看当前目录下的a.txt文件
total 4
-rw-rw-r--. 1 user1 user1 14 Apr 10 09:30 a.txt    #权限为664

[[email protected] demo2]$ cat a.txt    #查看a.txt文件中的内容
helloword,one

[[email protected] demo2]$ echo "wordhello,two" >>a.txt  #向a.txt文件中增加内容

[[email protected] demo2]$ cat a.txt    #查看此时的a.txt文件内容
helloword,one
wordhello,two                #文件内容增加成功

[[email protected] demo2]$ chmod -w a.txt      #去除文件a.txt的“w”权限
[[email protected] demo2]$ ll
total 4
-r--r--r--. 1 user1 user1 28 Apr 10 09:31 a.txt    #权限去除成功

[[email protected] demo2]$ echo "wordhello,three" >>a.txt     #此时增加a.txt文件内容
-bash: a.txt: Permission denied        #结果增加失败,提示权限不够



再说说“x”权限,(exec简写)

对于目录文件,“x”权限控制用户是否能打开它,只有具备了“x”权限,才能打开目录。而要查看目录下的内容,就必须有“r”权限,即查看显示的相关命令都必须具有文件的“r”权限才可以访问文件,比如ls命令,要显示ls对目录文件的执行结果,执行者必须具有该文件的x和r权限,毕竟是先打开(x),再显示(r)嘛。

例如:

1.创建目录文件day001,看出默认创建目录文件权限是775
[[email protected] demo1]$ mkdir day001 ; ll
total 0
drwxrwxr-x. 2 user1 user1 6 Apr  9 23:03 day001

2.在该目录中创建文件a.txt和b.txt,看出默认创建文件权限是:661;执行ll命令会显示出a和b文件
[[email protected] demo1]$ cd day001/; touch a.txt b.txt;ll
total 0
-rw-rw-r--. 1 user1 user1 0 Apr  9 23:06 a.txt
-rw-rw-r--. 1 user1 user1 0 Apr  9 23:06 b.txt

3.我们去掉目录day001的“rw”权限,再执行cd命令和ll命令,看看结果:
[[email protected] day001]$ cd .. ; ll       #返回上级目录执行ll命令查看day001权限
total 0
drwxrwxr-x. 2 user1 user1 32 Apr  9 23:06 day001    #当前day001权限为775
[[email protected] demo1]$ chmod a-rw day001/         #修改day001权限为111,就是去掉所有的rw权限
[[email protected] demo1]$ ll
total 0
d--x--x--x. 2 user1 user1 32 Apr  9 23:06 day001    #发现权限已经为111了
[[email protected] demo1]$ cd day001/            #执行cd命令,可以进入day001目录,因为进入目录只需要“x”权限
[[email protected] day001]$ ll                   #在day001中执行ll命令发现权限不够,这就是没有“r”权限的结果
ls: cannot open directory .: Permission denied

#####对于目录而言,“x”权限就是一个开关,执行者拥有这个目录的开关“x”,才能进入该目录



对于脚本文件,要执行就必须具有“x”权限。

[[email protected] demo2]$ ll 
total 4
-rw-rw-r--. 1 user1 user1 44 Apr 10 09:46 a.txt
[[email protected] demo2]$ echo "echo ‘hello word‘" >a.txt 
[[email protected] demo2]$ cat a.txt 
echo ‘hello word‘
[[email protected] demo2]$ sh a.txt 
hello word
[[email protected] demo2]$ ./a.txt
-bash: ./a.txt: Permission denied
[[email protected] demo2]$ chmod +x a.txt 
[[email protected] demo2]$ ./a.txt 
hello word




1.4 修改文件基本权限:

chmod [OPTION]... MODE[,MODE]... FILE...

数字法:r=4 w=2 o=1
[[email protected] demo]$ ll test.txt 
-rw-rw-r--. 1 user1 user1 0 Apr  9 06:34 test.txt
[[email protected] demo]$ chmod 744 test.txt 
[[email protected] demo]$ ll test.txt 
-rwxr--r--. 1 user1 user1 0 Apr  9 06:34 test.txt
[[email protected] demo]$
字符法:
[[email protected] demo]$ ll test.txt 
-rw-r--r--. 1 user1 user1 0 Apr  9 06:34 test.txt
[[email protected] demo]$ chmod u+x test.txt 
[[email protected] demo]$ ll test.txt 
-rwxr--r--. 1 user1 user1 0 Apr  9 06:34 test.txt

[[email protected] demo]$ chmod o+w test.txt
[[email protected] demo]$ ll test.txt 
-rwxr--rw-. 1 user1 user1 0 Apr  9 06:34 test.txt

[[email protected] demo]$ chmod g+w test.txt 
[[email protected] demo]$ ll test.txt 
-rwxrw-rw-. 1 user1 user1 0 Apr  9 06:34 test.txt

[[email protected] demo]$ chmod a-r test.txt 
[[email protected] demo]$ ll test.txt 
--wx-w--w-. 1 user1 user1 0 Apr  9 06:34 test.txt

2.深入文件权限

其实Linux文件权限除了“r”、“w”、“x”外,还有“s”、“t”两种权限。只不过“s”和“t”比较特殊,是建立在“x”权限基础上的,它们与操作系统的账号和系统进程相关。

“s”和“t”存在的必要条件是相应的“x”权限必须存在。s”这个标记可以出现在文件拥有者的x权限位上,也可以出现在文件所属组的x权限位上。那么其他用户位上的“x”权限位是否也可以被取代呢?答案是肯定的,只不过不再是“s”取代,而是“t”去取代,如下图:

技术分享

图3

2.1 执行如下命令:

[[email protected] ~]$ ls -l /bin/su
-rwsr-xr-x. 1 root root 32088 Nov  5 18:27 /bin/su
[[email protected] ~]$

从上命令结果,能够看到su这个命令的文件权限是“-rws r-x r-x”,拥有者的“x”权限位上是“s”,这就是SUID了,SUID权限拥有这样的功能:

1).SUID仅对二进制程序有效

2).执行者对该程序有“x”权限

3).执行权限仅在执行过程中有效

4).执行者将具有该程序拥有者的权限

su这个命令,无论任何人,执行它的瞬间都将拥有root权限,因为su命令的拥有者是root,只是这个权限仅在执行su命令时有效。这也是su命令能切换用户的原理。

设置SUID的方法就是使用“u+s”来改变权限。SUID在Linux中是非常常见的,那些需要提供给普通用户,但又需要root权限才能正常运行的程序,基本上都拥有SUID,比如:passwd,mount等,这也是实际用户和有效用户不一致的触发条件。


2.1.1 下面显示了一些SUID权限的命令:

[[email protected] ~]$ ll /bin/ | grep "rws"        #发现的是只要有“s”出现,任何用户都具有“x”权限
-rwsr-xr-x.   1 root root      52960 Nov  5 14:16 at
-rwsr-xr-x.   1 root root      64240 Nov  5 16:17 chage
-rws--x--x.   1 root root      23960 Nov  5 18:27 chfn
-rws--x--x.   1 root root      23872 Nov  5 18:27 chsh
-rwsr-xr-x.   1 root root      57552 Mar 31  2016 crontab
-rwsr-xr-x.   1 root root      32008 Nov  5 14:06 fusermount
-rwsr-xr-x.   1 root root      78216 Nov  5 16:17 gpasswd
-rwsr-xr-x.   1 root root      61328 Nov  5 21:42 ksu
-rwsr-xr-x.   1 root root      44232 Nov  5 18:27 mount
-rwsr-xr-x.   1 root root      41776 Nov  5 16:17 newgrp
-rwsr-xr-x.   1 root root      27832 Jun 10  2014 passwd
-rwsr-xr-x.   1 root root      27680 Nov  5 18:09 pkexec
-rwsr-xr-x.   1 root root      32088 Nov  5 18:27 su
-rwsr-xr-x.   1 root root      31968 Nov  5 18:27 umount
-rwsr-xr-x.   1 root root    2409560 Nov  5 20:44 Xorg
[[email protected] ~]$


2.1.2 通过修改脚本文件的SUID权限,让所有人都可以执行:




2.2 执行如下命令:

[[email protected] ~]$ ls -l /usr/bin/locate       #查看locate命令文件
-rwx--s--x. 1 root slocate 40512 Nov  5 11:07 /usr/bin/locate
[[email protected] ~]$

从上述命令结果看出,locate命令的文件权限是“rwx --s --x”,这就是SGID,拥有SGID的权限有:

1).SGID对二进制有效

2).执行者对该程序有x权限

3).执行者在执行过程中将会获得该程序所属用户组的支持

SGID用在locate命令上,是期望任何用户在执行这个命令的时候能够读取mlocate.db文件的内容,这个文件位于/var/lib/mlocate/mlocate.db中,它与locate命令有相同的用户组,而且用户组具有“r”权限,其他用户没有任何权限。

SGID除了用在二进制程序上,还可以用在目录上。当一个目录设置了SGID权限后,它将具有如下功能:

1).用户若对此目录拥有“r”和“x”权限时,该用户能够进入此目录

2).该用户在此目录下的有效用户组将变成该目录的用户组。

3).若用户在此目录下具有“w”的权限,则用户所创建的新文件的用户组与此目录的用户组相同。

根据这一特性,进入这类目录的用户就会发生有效用户组和实际用户组不一致的情况。而另一种导致有效用户组与实际用户组不一致的情况是使用newgrp命令。而有效用户组所起到的作用就在于其创建文件时文件的用户组。


2.3 执行如下命令:

[[email protected] ~]$ ll / | grep "tmp"
drwxrwxrwt.  53 root root 8192 Apr  9 09:26 tmp
[[email protected] ~]$


如上命令结果看出,/tmp文件就是“rwx rwx rwt”权限,也就是SBIT。仅对目录有效。对目录的作用如下:

1).用户若对此目录有“w”和“x”的权限,即拥有写的权限

2).当用户在此目录下建立了文件或目录,仅自己或root才有权利删除文件

换句话说就是:当用户U在目录D下建立了文件F,若D拥有SBIT权限,则仅用户U和root可以删除文件。

SBIT应用的典型例子就是/tmp目录。


修改文件s或t权限:

同样的可以使用字符和数字来改变属性,下面就只说说数字表示法。原来rwx是3位(744)数字表示,而现在是4位(4755)表示,其中第一位是 SUID=4、SGID=2、SBIT=1中的一个。

[[email protected] demo]$ ll Test 
-rwxrwxr-x. 1 user1 user1 0 Apr  9 09:51 Test

[[email protected] demo]$ chmod 4775 Test 
[[email protected] demo]$ ll Test 
-rwsrwxr-x. 1 user1 user1 0 Apr  9 09:51 Test

[[email protected] demo]$ chmod 2775 Test 
[[email protected] demo]$ ll Test 
-rwxrwsr-x. 1 user1 user1 0 Apr  9 09:51 Test

[[email protected] demo]$ chmod 1775 Test 
[[email protected] demo]$ ll Test 
-rwxrwxr-t. 1 user1 user1 0 Apr  9 09:51 Test


以上是关于深入理解Linux中的文件权限的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Linux中的grep命令

深入理解SELinux

深入理解Linux文件系统

深入理解Linux文件系统与日志分析

深入理解linux源码安装三板斧

Linux中的文件权限怎么理解