27.2. 用户和访问权限

自 20 世纪 90 年代初期推出以来,Linux 一直是一种多用户系统。它支持任意数目的用户同时操作。用户在自己的工作站上启动会话之前必须先登录到系统中。每个用户都有一个用户名及对应的口令。设置用户名和口令可以确保未经授权的用户无法查看他们无权查看的文件。而且,进行这种设置后,通常也不可能对系统进行较大改动(如安装新程序),或者限制普通用户执行此类操作。只有根用户或超级用户才能不受限制地对系统进行更改并且不受限制地访问所有文件。有效运用这种概念的用户只在必要时才使用不受限制的根用户权限登录,这样可以减小意外丢失数据的风险。由于一般情况下只有根用户才能删除系统文件或格式化硬盘,所以来自特洛伊木马的威胁或意外输入破坏性命令的风险得以显著降低。

27.2.1. 文件系统权限

一般而言,Linux 文件系统中的每个文件都属于某个用户和某个组。可以为这些专有组和其它所有组授予读、写或执行这些文件的权限。

在这种情况下,可以将组定义为具有特定集合权限的一组相互连接的用户。例如,可以将共同处理某个项目的组称为 project3 。Linux 系统中的每个用户都是至少一个专有组(通常是 users)的成员。可以根据需要设置系统中组的数目,但只有根用户才能添加组。每个用户都可以使用 groups 命令查出自己所属的组。

文件访问

文件系统中的权限组织结构不同于文件和目录的组织结构。使用 ls -l 命令可以显示文件权限信息。命令输出可能如 例 27.1 “显示文件权限的示例输出” 中所示。

例 27.1. 显示文件权限的示例输出

-rw-r----- 1 tux project3 14197 Jun 21  15:03 Roadmap

如第三列中所示,此文件属于用户 tux。该文件被指派给组 project3。要确定 Roadmap 文件的用户权限,必须仔细检查第一列。

-

rw-

r--

---

类型

用户权限

组权限

其他用户的权限

此列含有一个前置字符,后接九个字符,每三个字符为一组。这十个字符中的第一个字符代表文件系统组件的类型。连字符 () 表示这是一个文件。也可以用 d 表示目录、l 表示链接、b 表示块设备,或指明字符设备。

后面的三组字符遵循标准模式。前三个字符表示该文件可读 (r) 还是不可读 ()。中间的 w 表示可以编辑相应的对象,而连字符 (-) 意味着不能写入该文件。排在第三位的 x 表示可以执行该对象。由于本例中的文件是不可执行的文本文件,所以不必为这个特定文件授予可执行权限。

在本例中,作为文件 Roadmap 的拥有者,tux 有权读 (r) 写 (w) 该文件,但无法执行它 (x)。project3 组中的成员可以读取该文件,但不能修改或执行它。其他用户无权访问此文件。通过 ACL(Access Control List,访问控制列表)可以指派其它权限。有关背景信息,请参见 第 27.2.6 节 “访问控制列表”

目录权限

目录的访问权限类型用 d 来表示。对目录而言,各种权限的含义稍有不同。

例 27.2. 显示目录权限的示例输出

drwxrwxr-x 1 tux project3 35 Jun 21 15:15  ProjectData

例 27.2 “显示目录权限的示例输出” 中,很容易识别出目录 ProjectData 的拥有者 (tux) 和所属组 (project3)。与 文件访问 中的文件访问权限相比,设置读权限 (r) 表示可以显示该目录的内容。写权限 (w) 表示可以创建新文件。执行权限 (x) 表示用户可以转到此目录。上例中,用户 tux 及组 project3 中的成员可以转到 ProjectData 目录 (x)、查看其中的内容 (r) 并添加或删除文件 (w)。其他用户的权限则受到限制。他们可以进入目录 (x) 并浏览其中的内容 (r),但不能插入任何新文件 (w)。

27.2.2. 修改文件权限

更改访问权限

文件或目录的访问权限可以由拥有者更改,当然也可以由根用户更改;更改时要使用命令 chmod,后接更改权限的参数及一个或多个文件名。参数可归为四类:

  1. 用户相关参数

    • u用户)- 文件的拥有者

    • g)- 文件所属的组

    • o其它)- 其它用户(如果未指定参数,更改将应用到所有类别)

  2. 用于删除 (-)、设置 (=) 或插入 (+) 的字符

  3. 缩写

    • r读取

    • w写入

    • x执行

  4. 一个文件名或由空格分隔的多个文件名

例如,在 例 27.2 “显示目录权限的示例输出” 中,如果用户 tux 还想授予其它用户写入 (w) 目录 ProjectData 的权限,则可以使用命令 chmod o+w ProjectData 执行该操作。

不过,如果该用户不希望任何用户具有写权限(本人除外),则可以输入命令 chmod go-w ProjectData 执行该操作。要防止所有用户向 ProjectData 添加新文件,请输入 chmod -w ProjectData。此时,如果不重新建立写权限,即使是拥有者也无法再写入该文件。

更改所有权

另有一些重要的命令可用来控制文件系统组件的所有权和权限,这些命令包括 chown (更改拥有者)和 chgrp(更改组)。使用命令 chown 可将文件所有权转让给另一用户。不过,只有根用户才有权执行该操作。

假定 例 27.2 “显示目录权限的示例输出” 中的文件 Roadmap 不应再属于 tux,而应属于用户 geeko,则根用户应该输入 chown geeko Roadmap

chgrp 用于更改文件的组所有权。不过,文件的拥有者必须是新组的成员。这样,使用命令 chgrp project4 ProjectData例 27.1 “显示文件权限的示例输出” 中的用户 tux 即可将文件 ProjectData 所属的组改换为 project4,只要该用户是这个新组的成员。

27.2.3. setuid 位

在某些情况下,访问权限可能过于严格。因此,Linux 另有一些设置,允许为执行特定操作临时更改当前用户和组标识。例如,passwd 程序通常要求拥有根权限才能访问 /etc/passwd。此文件包含一些重要信息,如用户主目录及用户和组 ID。因此,普通用户将无法更改 passwd,因为授予所有用户直接访问此文件的权限太过危险。解决该问题的一种可行方案就是 setuid 机制。setuid(设置用户 ID)是一个特殊的文件特性,它指示系统使用特定用户 ID 执行已相应标记的程序。以 passwd 命令为例:

-rwsr-xr-x  1 root shadow 80036 2004-10-02 11:08 /usr/bin/passwd

您可以看见 s,它表示为用户许可设置了 setuid 位。通过设置 setuid 位,启动 passwd 命令的所有用户都以根用户身份执行该命令。

27.2.4. setgid 位

setuid 位适用于用户。而对组而言也有一个等价的属性:setgid 位。设置了此位的程序基于保存该程序的组 ID 运行,而不论是哪个用户启动了该程序。因此,在设置了 setgid 位的目录中,所有新建文件和子目录都被指派到该目录所属的组。请考虑下面的示例目录:

drwxrws--- 2 tux archive 48 Nov 19 17:12 
   backup

您可以看见 s,它表示为组许可设置了 setgid 位。目录的拥有者和组 archive 的成员可以访问此目录。不是该组成员的用户会“映射”到各自的组中。 所有写入文件的有效组 ID 为 archive。例如,以组 ID archive 运行的备份程序即便没有根特权也能访问此目录。

27.2.5. 粘滞位

另外还可以设置粘滞位。属于可执行程序的粘滞位和属于目录的粘滞位在作用上有所不同。如果属于某个程序,以这种方式标记的文件将被装入 RAM,而不必在每次使用时从硬盘读取。由于目前硬盘的速度已经足够快,此特性已经很少使用。如果为目录指派了此位,则可以防止用户删除彼此的文件。典型示例如 /tmp 目录和 /var/tmp 目录:

drwxrwxrwt   2 root  root   1160 2002-11-19 17:15 /tmp 

27.2.6. 访问控制列表

Linux 系统文件对象(如文件或目录)的传统权限概念通过 ACL(访问控制列表)得到了进一步扩展。通过访问控制列表可以将权限指派给文件系统对象的各个用户或组,而不再局限于最初的拥有者或所属组。

使用一个简单的 ls -l 命令即可检测到拥有扩展访问权限的文件或目录:

-rw-r--r--+ 1 tux project3 14197 Jun 21  15:03 Roadmap

Roadmap 由属于组 project3tux 所有。tux 有对此文件的读写权。组及所有其它用户有读权限。带 ACL 和不带 ACL 的文件之间的唯一区别即在于:前者的列内多了一个用来包含权限位的 +

通过执行 getfacl Roadmap 来获取 ACL 的详细信息:

# file:Roadmap 
# owner:tux 
# group:project3 
user::rw- 
user:jane:rw-       effective:r-- 
group::r-- 
group:djungle:rw-   effective:r-- 
mask::r-- 
other::---

输出中的前三行不包含 ls -l 中没有的信息。这些行只用来表明文件名、拥有者和所属组。第 4 到 9 行包含 ACL 条目。传统访问权限只是使用 ACL 可以授予的权限的一部分。本例中的 ACL 为该文件的拥有者以及用户 jane 授予了读写权限(第 4 到 5 行)。通过为其他用户授权,传统概念得到了扩展。这种权限的扩展也同样适用于组权限的处理。所属组拥有读权限(第 6 行),且 djungle 组拥有读写权限。第 8 行中的 mask 条目将用户 jane 和组 djungle 的有效许可权限限制为只能读取。其他用户和组对该文件不具备任何类型的权限(第 9 行)。

这里只提供了最基本的信息。有关 ACL 的更多详细信息,请参见 第 24 章 Linux 中的访问控制列表