文件共享与权限
| 原文作者: | Jerry Peek |
|---|---|
| 中文编译: | Tony Gu(digitalsatori) |
| 原文链接: | http://www.linux-mag.com/id/1209/ |
Linux系统是一个多用户系统,其权限管理子系统允许每个用户共享或者保护自己的文件。可是这个出色的系统也的确有让人颇费脑筋的时候。比如:你是否知道,要对一个文件做移除或改名操作,用户需要拥有文件所在目录的写权限?对权限系统的深入了解可以让你的系统更加安全,与他人共享文件更加便利,以及防止文件的意外改动。我们首先学习一下Linux文件权限系统的一些基础知识。
基础: 用户与组
Linux中每个用户都有一个用户名(比如 zoe)和一个对应的用户ID(或UID)比如1234。每个用户属于一个或几个组。每个组也有自己的名称和ID(GID)。运行 id 命令可以看到用户和组的信息:
% id
uid=1324(zoe) gid=1324(zoe) groups=1324(zoe),111(staff)
每个文件和目录都有所属的用户和组,以及一系列标记文件的拥有者,所属组,及其他用户的访问权限。比如, ls -ld 命令显示 Zoe 的HOME目录(-d 表示显示目录本身而不是其中的内容):
% pwd
/home/zoe
% ls -dl
drwxr-x–x 5 zoe zoe 4096 Nov 2 10:33 .
大多数的Linux参考书都会介绍 ls -l, 我们这里来复习一下。
ls -l 命令的输出行的第一个字母表示文件类型。这里d表示目录文件。该文件的所属用户是zoe,他的所属组的名称为zoe
接下来的字符表示不同类型用户的访问权限:拥有者访问权限(这里是rwx),组成员的访问权限(r-x),以及其他用户的访问权限(--x)。
rwx所标记的访问权限对于普通文件很简单:r允许读文件,w允许修改文件,x允许执行文件。但是对于目录文件就不是那么直观了。我们来进一步了解
对目录的读与写权限
如果有目录的读权限,就可以使用ls或一个图形化的文件浏览器显示目录中的内容。为什么呢?因为目录是一种特殊的文件类型,其内容包括存储于“其中”的文件的名称,那么如果能读目录文件的话,就能看到保存在其中的文件的名称。
同样道理,如果有目录的写权限就能修改目录中的内容-改变存储其中的文件的名称。要添加,删除,或者改名一个文件,你需要有这个文件所在目录的写权限。如果一个目录是不可写的,那么目录下的所有对象都不可更改。
目录的"x"权限
如果有目录的执行(x)权限,就可以访问目录下的对象。虽然拥有对目录的读权限(可以让你能到里面有什么),如果没有x执行权限,你仍然无法使用该目录下的任何对象。 例如, 尽管你对某个文件拥有读写权限,当你没有该文件所在目录的执行权限时,你仍然不能读写该文件:
% mkdir safe
% chmod og-rwx safe
% echo “Hello” > safe/secret
% chmod a-x safe
% ls safe
secret
% cat safe/secret
cat: safe/secret: Permission denied
% chmod u+x safe
% cat safe/secret
Hello
事实上,你必须要拥有待访问目录之上直至根目录的执行权限,才能访问该目录。同样道理,没有目录的执行权限,你就无法访问其子目录。
如果你知道目录下待访问对象的名称,你可以访问该对象而不必拥有对目录的读权限。
文件共享
Linux的权限设置可以方便的使用户间共享文件-或者在授权的情况下修改和删除其他用户的文件。目录和文件的权限往往设置成允许普通的文件共享,我们来看一个特别的例子。
比方Zoe的home目录是一个共享给办公室所有电脑的网络文件系统。她可以告诉他的朋友使用图片浏览器查看她的目录, ~zoe/xfotos (shell会扩展 ~zoe 为zoe的home目录绝对路径,Zoe自己只要用 ~ 就可以访问她的home目录)她设置的权限仅供他人读取她的照片,而不能添加,删除,修改文件:
% ls -dl ~ ~/xfotos
drwxr-x–x zoe zoe … /home/z/
drwxr-xr-x zoe zoe … /home/zoe/xfotos
% ls -l ~/xfotos
-rw-r–r– zoe zoe … alix.jpg
-rw-r–r– zoe zoe … boss.jpg
…
这个例子展示了Linux文件系统的一个强项:随心所欲的共享文件。Zoe不需要将照片发送到朋友的邮箱里,或者设置办公室的Web服务器使朋友们看到她的照片。她只要简单地“开放”自己的目录和文件使他们可被他人读取即可。
保持文件隐私的一个最简单的方法就设置home目录下的某个目录为“仅拥有者访问。比如创建一个叫personal的目录,并且输入 chmod 700 personal 命令,使自己拥有所有(rwx)权限,但是不给组成员及其他用户任何访问权限。所有在personal目录下的文件及子目录,无论他们的权限如何,除了自己和系统超级用户,其他人统统不能访问。
默认权限:umask
如果你既要实现文件共享又要保障访问安全,在设置共享前检查每个文件包括比如.bashrc这样的隐藏文件的访问授权。
你还应该正确设置umask。umask定义了新文件和目录的默认权限。umask是一个二进制掩码用以在创建新文件时“拒绝”某些权限。你可以在shell中输入 umask 来了解当前的umask设置。要设置新的umask,使用 umask nnn, 其中nnn就是新的umask。
不设置umask(或umask为0)时,新创建的目录的权限模式为777(用 ls -l 命令显示为 rwxrwxrwx ),而新创建的文件的权限模式为666(rw-rw-rw-)(如果你没见过权限模式用8进制数表示的方法,请记得r代表4,w代表2,x代表1。因此,rwx表示为7(4+2+1),rw-表示为6(4+2), r-(表示为4)
用以表示umask的3个数字和 用于 chmod 命令的数字有相同的顺序:第一个是拥有者掩码,第二个是群组掩码,最后的是其他用户掩码。因此,umask002,对拥有者和所属群组“不拒绝”任权限,对其他用户拒绝写(2)权限。umask 027对拥有者不拒绝任何权限(0),对群组拒绝写(2)权限,对于其他用户拒绝“所有”(7)权限。
要了解umask到底怎么回事,最简单的方法就是用 touch 和 mkdir 来创建一个空的文件和目录,然后使用 ls -l 命令来查看权限。(这里我们使用了Shell的(;)操作符,在一个命令行上运行两个命令):
% umask 027
% touch file; mkdir dir
% ls -l file; ls -ld dir
-rw-r—– jpeek jpeek … file
drwxr-x— jpeek jpeek … dir
% rm file; rmdir dir
当一个进程启动另一个进程时,umask也从父进程传递给了子进程( 参见: 消息的传递 )。你可以在shell里实验umask命令,要知道你改变的umask不会影响到其他现存的shell和进程。
消息的传递
一个进程比如一个文本编辑器或者一个shell在创建一个文件时是如何获取umask,以及用户和组的ID的?所有这些信息以及其他的信息(比如当前目录)都来自其父进程。当新的进程创建后,我们可以任意修改比如umask这类信息,但是请注意这些修改并不对父进程或已存在的进程发生作用。
你应该尽可能早的设置umask,比如在登录进程中或在启动窗口系统的脚本中。尽可能早的设置umask意味着所有的子进程(比如终端窗口,文件管理器等)会继承这个umask。
组的用法
我们再来看看本文开头处的输出的ID信息。Zoe同属于两个组:zoe和staff。 Linux的组可以有多个成员,而每个用户也可以属于多个组。
比如,所有的系统管理员和员工都属于员工(staff)组。他们可以访问属于该组的的私有文件和目录,而这些文件和目录非成员(非员工用户)是不能访问的。同理,Zoe的老板或者部门经理也可以是zoe组的成员,这样就可以以组成员的身份来访问Zoe的部分或全部文件和目录。
如果你属于某个组(你总是至少属于一个组:你自己的组),你可以使用 chgrp 命令来改变你拥有的文件或目录的所属组。
比如,Zoe要保存一个有关系统用户的文件,文件名为users.xml。她使用 chgrp staff users.xml 来设置文件的所属组为staff组。然后使用命令: chmod 640 users.xml (或者使用命令: chmod u=rw,g=r,o= users.xml) 来赋予自己读和写的权限,给staff组的成员读的权限,不给其他用户任何权限。staff成员都可以打开该文件,但是其他用户不能访问该文件。
如果你属于几个组,那么你创建的文件属于哪个组呢?默认情况下,属于你的首要组,即使用id命令输出中 gid= 之后的第一个组名。当处于一个为某个特定的组成员共享的目录下,多数情况下你并不希望创建的文件属于自己的首要组。
比如, prj/4staff 可能有这样的权限设置: drwxrwx- -- 因此所有的staff组的成员可以创建,删除,或改名在该目录中的文件。但是如果zoe在该目录中创建了一个文件,该文件使用了Zoe的默认组zoe,这样staff组的其他成员就无法读取该文件了。(除非他们也是zoe组的成员)。
解决这个问题的办法是设置该目录的 setgid 位。(该位在权限字串中表示为"s": drwxrws-) 在有 setgid 的目录中创建的文件或子目录会继承该目录所属的组。所以,只要按如下设置,在 prj/4staff 中创建的文件会自动设为所属组staff组:
pete$ chmod g+s /prj/4staff
pete$ ls -ld /prj/4staff
drwxrws— 5 pete staff /prj/4staff
保护文件
如果你是Linux系统上的唯一用户,而且你的文件系统也没有与其他电脑联网,你会想我还需要了解这些权限设置吗?答案是肯定的,一个很好的理由是为了防止意外,比如误删,或错误更改你的文件和目录。错误总会发生,保护文件就很有必要了。
比如report.doc是一个很重要的文件,你可以用命令: chmod a-w report.doc 来使所有人包括你自己无法写该文件。但是,正如之前所说,对文件本身设置权限并不能防止文件被删除或替换!(比如,你使用编辑器编辑report.doc,编辑器可以重命名report.doc为report.doc.bak,并且创建一个新的report.doc文件。这是完全合法的)为了防止所有这样的改变,文件所属的目录也应样设置为不可写。
我们所介绍的权限系统存在于Unix系统,同样也工作在Linux系统上。而一些Linux文件系统,比如普遍使用的ext2 ext2文件系统,还包括其他一些文件属性。 lsattr 和 chattr 的帮助页中介绍了如何来显示和改变这些文件属性。
以下是一个简单的例子。超级用户使用 chattr 来设置使文件只能附加的属性:不能修改现有内容,只能添加内容。使用 lsattr 来显示该属性,注意, ls -l 并不能显示出该属性。
# chattr +a log
# exit
% ls -l log
-rw-rw-r– 1 zoe staff 1168 Oct 30 12:29 log
% lsattr log
—–a– log
% cp /var/log/dmesg log
cp: overwrite `log’? y
cp: cannot create regular file `log’: Operation not permitted
% cat /var/log/dmesg >> log
% ls -l log
-rw-rw-r– 1 zoe staff 3109 Oct 30 12:33 log














umask 027
对应的文件权限应该是 640
对应的目录权限应该是 750
如何解释?
你大概没有注意这段话
对目录来说就是 777然后用umask来“减去“相应的权限;对文件来说就是用666来“减去“相应的权限