3.4.权限 ======== 在 FreeBSD 中,每个文件和目录都有一组相关的权限,有几个工具可以用来查看和修改这些权限。为了确保用户能够访问他们需要的文件,并且不能非法访问操作系统使用的或其他用户拥有的文件,了解权限的工作方式是必要的。 这一节讨论了 FreeBSD 中使用的传统 UNIX® 权限。对于细粒度的文件系统访问控制,请参考\ `“访问控制列表” `__\ 。 在 UNIX® 中,基本权限由三种访问类型进行分配:读、写和执行。这些访问类型用于确定文件所有者、组和其他人(其他所有人)对文件的访问。读、写和执行权限可以分别用字母\ ``r``\ 、\ ``w`` 和 ``x`` 表示,也可以用二进制数字表示,因为每个权限都是开或关(\ ``0``\ )。当用数字表示时,阅读顺序为 ``rwx``\ ,其中 ``r`` 的开启值为 ``4``\ ,\ ``w`` 的开启值为\ ``2``\ ,\ ``x`` 的开启值为 ``1``\ 。 表 4.1 总结了可能的数字和字母的可能性。在阅读“参数”一栏时,\ ``-`` 被用来代表一个被设置为关闭的权限。 **表 2. UNIX® 权限** == ======================== ==== 值 权限 参数 == ======================== ==== 0 不可读,不可写,不可执行 — 1 不可读,不可写,可执行 –x 2 不可读、可写、不可执行 -w- 3 不可读、可写、可执行 -wx 4 可读,不可写,不可执行 r– 5 可读,不可写,可执行 r-x 6 可读、可写,不可执行 rw- 7 可读、可写、可执行 rwx == ======================== ==== 使用 `ls(1) `__ 的参数 ``-l`` 可以查看详细的目录列表,其中包括一列关于文件的所有者、组和其他人的权限的信息。例如,在一个任意的目录中,\ ``ls -l``\ 可能显示: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session % ls -l 输出结果应类似于下面的内容: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session total 530 -rw-r--r-- 1 root wheel 512 Sep 5 12:31 myfile -rw-r--r-- 1 root wheel 512 Sep 5 12:31 otherfile -rw-r--r-- 1 root wheel 7680 Sep 5 12:31 email.txt 请看 ``myfile`` 这一行,第一个“(最左边)”字符表示这个文件是一个普通文件、一个目录、一个特殊字符设备、一个套接字或任何其他特殊的伪文件设备。在这个例子中,\ ``-`` 表示一个普通文件。接下来的三个字符,即本例中的 ``rw-``\ ,给出了文件所有者的权限。再接下来的三个字符,\ ``r--``\ ,给出了文件所属组的权限。最后三个字符,\ ``r--``\ ,代表其他人的权限。一个破折号意味着该权限被关闭。在这个例子中,权限被设置为所有者可以读写文件,组可以读取文件,而其他人只能读取文件。根据上表,这个文件的权限是 ``644``\ ,其中每个数字代表文件权限的三个部分。 系统是如何控制设备的权限的?FreeBSD 将大多数硬件设备视为是一个程序可以打开、读取并写入数据的文件。这些特殊的设备文件被存放在 ``/dev/``\ 。 目录也被视为文件。它们有读、写和执行的权限。目录的可执行位与文件的意义略有不同。当一个目录被标记为可执行时,它意味着可以使用 `cd(1) `__ 切换到该目录。这也意味着可以访问该目录中的文件,但要取决于文件本身的权限。 为了列出目录内容,必须在目录上设置读取权限。为了删除一个知道名字的文件,必须对包含该文件的目录有写和执行的权限。 还有更多的权限位,但它们主要是在特殊情况下使用,如 ``setuid`` 二进制文件和粘滞位目录。关于文件权限的更多信息以及如何设置它们,请参考 `chmod(1) `__\ 。 3.4.1.权限符号 -------------- 符号权限使用字符而非八进制值来给文件或目录分配权限。符号权限使用的语法是(用户)(动作)(权限),其中有下列参数: ======== ===== =============== 选项 参数 意义 ======== ===== =============== (用户) ``u`` 用户 (用户) ``g`` 组 (用户) ``o`` 其他 (用户) ``a`` All (“全部”) (动作) ``+`` 增加权限 (动作) ``-`` 移除权限 (动作) ``=`` 指定权限 (权限) ``r`` 读 (权限) ``w`` 写 (权限) ``x`` 执行 (权限) ``t`` 粘滞位 (权限) ``s`` 设置 UID 或 GID ======== ===== =============== 这些值与 `chmod(1) `__ 一起使用,但用字母而非数字。例如,下面的命令会阻止与 *FILE* 相关的组的成员和所有其他用户访问 *FILE*\ 。 .. raw:: latex \diilbookstyleinputcell .. code:: shell-session % chmod go= FILE 当必须对一个文件进行多组修改时,可以提供一个逗号分隔的列表。例如,下面的命令移除了组和所有人对 *FILE* 的写入权限,并为每个人增加了执行权限: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session % chmod go-w,a+x FILE 3.4.2.FreeBSD 的文件标志 ------------------------ 除了文件权限之外,FreeBSD 还支持使用“文件标志”。这些标志为文件(不含目录),增加了额外的安全和控制能力。通过文件标志,甚至可以阻止 ``root`` 删除或更改文件。 文件标志是用 `chflags(1) `__ 修改的。例如,要在文件 ``file1`` 上启用系统禁止删除的标志,执行以下命令: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chflags sunlink file1 要移除系统禁止删除标志,请在 ``sunlink`` 前面加一个“no”: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chflags nosunlink file1 要查看文件的标志,可以使用 `ls(1) `__\ 中 ``-l`` 参数: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # ls -lo file1 .. raw:: latex \diilbookstyleinputcell .. code:: shell-session -rw-r-r-- 1 trhodes trhodes sunlnk 0 Mar 1 05:54 file1 一些文件标志只能由 ``root`` 用户添加或移除。在其他情况下,文件所有者可以设置其文件标志。更多信息请参考 `chflags(1) `__ 和 `chflags(2) `__\ 。 3.4.3.setuid、setgid 和 sticky 权限 ----------------------------------- 除了已经讨论过的权限之外,所有管理员都应该知道还有三个特定的设置:它们是 ``setuid``\ 、\ ``setgid`` 和 ``sticky`` 权限。 这些设置对某些 UNIX® 操作很重要,因为它们提供了通常不授予普通用户的功能。为了理解它们,必须注意真实用户 ID 和有效用户 ID 之间的区别。 真实用户 ID 是拥有或启动该进程的 UID。有效 UID 是进程运行的用户 ID。举个例子,当用户修改密码时,\ `passwd(1) `__ 以真实用户 ID 运行。然而,为了更新密码数据库,该命令以 ``root`` 用户的有效 ID 运行。这使得用户在修改密码时不会看到 ``Permission Denied`` 的错误。 setuid 权限可以通过为用户添加符号 ``s`` 权限来添加,如下所示: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chmod u+s suidexample.sh setuid 权限可以通过在权限集前加上数字四(4)来设置,如下例所示: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chmod 4755 suidexample.sh ``suidexample.sh`` 的权限现在显示如下: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session -rwsr-xr-x 1 trhodes trhodes 63 Aug 29 06:36 suidexample.sh 请注意,\ ``s`` 现在是为文件所有者指定的权限集的一部分,取代了可执行位。他允许提高软件的权限,如 `passwd(1) `__\ 。 **注意** ``nosuid`` `mount(8) `__ 选项将导致这种二进制文件执行失败而不警告用户。这个选项并不完全可靠,因为 ``nosuid`` wrapper 可能会绕过它。 要实时查看这个,请打开两个终端。在其中一个终端上,以普通用户的身份输入 ``passwd``\ 。在它等待新密码的时候,检查进程表并查看 `passwd(1) `__ 的用户信息。 在终端 A: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session Changing local password for trhodes Old Password: 在终端 B: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # ps aux | grep passwd .. raw:: latex \diilbookstyleinputcell .. code:: shell-session trhodes 5232 0.0 0.2 3420 1608 0 R+ 2:10AM 0:00.00 grep passwd root 5211 0.0 0.2 3620 1724 2 I+ 2:09AM 0:00.01 passwd 尽管 `passwd(1) `__ 是以普通用户的身份运行的,但它使用的是有效 UID,即 ``root``\ 。 ``setgid`` 权限的功能与 ``setuid`` 权限的功能相同;只是它改变了组的设置。当一个应用程序或实用程序以这种设置执行时,它将被授予基于拥有文件的组的权限,而不是启动该进程的用户。 要在文件上地设置 ``setgid`` 权限标志,用 `chmod[1] `__ 来为该组添加 ``s`` 权限: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chmod g+s sgidexample.sh 或者,提供 `chmod[1] `__\ ,前面加个二(2): .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chmod 2755 sgidexample.sh 注意在下面的列表中,\ ``s`` 现在位于指定组权限设置的字段: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session -rwxr-sr-x 1 trhodes trhodes 44 Aug 31 01:49 sgidexample.sh .. **注意** 在这些例子中,即使有关的 shell 脚本是一个可执行文件,它也不会以不同的 EUID 或有效用户 ID 运行。这是因为 shell 脚本不能使用 `setuid(2) `__ 系统调用。 ``setuid`` 和 ``setgid`` 权限位可能会因为允许提升权限而降低系统的安全性。第三个特殊权限,粘滞位,可以加强系统的安全性。 当一个目录上的粘滞位被设置时,它只允许文件所有者删除文件。这对于防止不拥有文件的用户在公共目录(如 ``/tmp``\ )中删除文件很有用。要利用这个权限,在文件中添加\ ``t`` 权限: .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chmod +t /tmp 或者,在权限集前加一个一(1): .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # chmod 1777 /tmp 粘滞位权限将在权限集的最末端显示为 ``t``\ : .. raw:: latex \diilbookstyleinputcell .. code:: shell-session # ls -al / | grep tmp .. raw:: latex \diilbookstyleinputcell .. code:: shell-session drwxrwxrwt 10 root wheel 512 Aug 31 01:49 tmp