![对“群组”和 Linux“权限模型”感到困惑](https://linux22.com/image/1616792/%E5%AF%B9%E2%80%9C%E7%BE%A4%E7%BB%84%E2%80%9D%E5%92%8C%20Linux%E2%80%9C%E6%9D%83%E9%99%90%E6%A8%A1%E5%9E%8B%E2%80%9D%E6%84%9F%E5%88%B0%E5%9B%B0%E6%83%91.png)
因此,我试图理解 Linux 中的组和权限概念,但完全搞糊涂了。在我的笔记本电脑上,我是唯一的用户,因此也是超级用户,我理解更改文本文件的文件权限(chmod +x)使其可执行,或更改读写权限(chmod +/- rw)的含义
但我真的不明白组的概念。据我所知,组就是一群用户。(但这是否意味着一个用户可以属于多个组?)据我了解,组基本上是为了更容易为一群用户rwx
(即组)批量设置/取消权限。
但现在网站作者说:
Linux 中有三个权限级别:所有者、组和其他。所有者是拥有文件/文件夹的用户,组包括文件组中的其他用户,而其他仅代表不是所有者或组内的所有其他用户。
这是否意味着除了文件有所有者(即创建该文件的人的用户 ID)之外,该文件还有一个“组所有者”?这个组通常是文件所有者所属的组之一吗?
如果我的系统上有三个组 A、B、C,并且我想要 分别在系统上设置权限rw-
,该怎么办?-wx
r-x
提出上述问题很可能表明我对 Unix 中的“组”和“组权限”的思维模型存在缺陷。
我尝试阅读了很多文章,但似乎缺少一些理解群组和群组权限概念的基本知识。有人能给我一个简洁的解释或给我推荐一些关于这个主题的更清晰的文章吗?
答案1
但我真的不明白群组的概念。据我所知,群组就是一群用户。(但这是否意味着一个用户可以属于多个群组?)
是的,是的。
据我了解,组基本上是为了更容易地为多个用户(即组)批量设置/取消设置 rwx 权限。
设置权限的一种方式很多当组需要访问分散在系统各处的许多文件或文件夹时,情况就更容易了。
例如,每当有新用户加入时,您都需要逐个查找所有这些文件,并尝试猜测诸如“如果用户 A、B、C 有权访问,则应添加用户 D”之类的内容。但是,如果这些权限仅列出组名,则您根本不需要更新它们 - 而只需将用户添加到组中即可。
(它不仅限于文件权限——某些系统服务也可以配置为授予组而不是单个用户的访问权限,具有与此处相同的优势。)
这是否意味着除了文件有所有者(即创建该文件的人的用户 ID)之外,该文件还有一个“组所有者”?这个组通常是文件所有者所属的组之一吗?
是的。每个用户都有一个“主要组”,新创建的文件属于该组。但是,即使是非 root 用户也可以使用 chown/chgrp 将自己的文件重新分配给他们当前所属的任何组。
(有一个例外:如果目录设置了“setgid”位,则其中新创建的文件将继承目錄的组,而不是创建者的组。这更接近于 Windows NTFS 的默认工作方式。
当然,当文件一次只能属于一个组时,此“组所有者”系统会受到一些限制。请参阅下一节。
如果我的系统上有三个组 A、B、C,并且想要在系统上分别设置权限 rw-、-wx、rx,该怎么办?
然后,您使用另一个称为“ACL”(访问控制列表)的功能,顾名思义,该功能允许您指定要授予访问权限的任意用户和组列表。
Linux 支持 POSIX ACL 格式,这主要是现有模型的直接扩展。也就是说,如果您首先将现有权限重写为:
user::rwx, group::r-x, other::---
现在你可以使用setfacl
或chacl
添加你的三个额外的分组为:
group:Family:rw-, group:Friends:-wx, group:Coworkers:r-x
为避免混淆请注意:POSIX ACL 试图尽可能地与传统的 chmod 保持兼容,但这会导致一个令人惊讶的功能。一旦你将 ACL 添加到文件,中的“组”字段ls -l
将开始显示称为“掩码”的内容,并且类似这样的命令chmod g-w
将拒绝对所有 ACL 条目,而不只是针对“业主群体”。
如果可以使用 ACL,那么为什么 Linux 甚至 Unix 会使用“所有者/组/其他”分类?因为这种简单的分类比 ACL 支持早了几十年。
Unix 最初采用了简单的方法,就像当时大多数其他操作系统一样 - 要么是由于磁盘空间限制(权限位只能容纳两个字节),要么是经过深思熟虑的设计决策(Multics 当时可能有复杂的 ACL,但 Unix 中的许多东西都是故意简化的)。
最终,API 变得固定不变——可以添加新的 API,但现有的“chmod”无法更改,因为程序已经期望它以某种方式工作。(即使在添加 ACL 后,OpenVMS 也必须保留其类似的权限位系统。)
除此之外,不幸的是,它是唯一一款在所有类 Unix 操作系统之间交叉兼容的系统。其他一些 Unix(例如 FreeBSD、Solaris)可能使用完全不同的 ACL 格式,而其他一些(OpenBSD)则根本不支持 ACL。与 Windows 相比,全部文件保护基于 ACL。
答案2
Linux/Unix 组的概念能令人困惑。但让我们试着解开这个谜团。
文件和目录都有所有者和组(或者您可以称之为“组所有者”)。它们还有三组rwx
权限位,一组用于用户,一组用于组,一组用于其他。此外,它们还有另外三个权限位:setuid、setgid 和 sticky。文件或目录的用户和组在内部存储为 UID 和 GID,它们是无符号整数,用作用户和组的内部标识符。
系统中的用户具有 UID 和 GID(通常在文件中设置/etc/passwd
),该文件中的 GID 设置用于指示初级组用户的权限。此外,用户可能属于多个组(通常在/etc/group
文件中配置,该文件列出了系统中每个组的其他用户。)
您可以使用该命令检查用户的 UID、GID、主要组和附加组id
,该命令将列出运行该命令的用户的所有这些信息。
当您尝试访问文件或目录时,系统将尝试根据权限位验证您的访问权限。具体来说,系统将首先查看是否使用用户、组或其他位。如果您的 UID 与访问该文件的用户的 UID 完全匹配,则将使用“用户”位。对于组,如果您的基本的group 与文件所属的组匹配,或者如果任何其他组(由 报告id
)与该组匹配,则将使用“group”位。否则,如果这些都不匹配,则将使用“other”位。
文件权限的含义相当简单,r
意味着您可以打开文件进行读取,w
意味着您可以打开该文件进行写入(从而修改其内容)并且x
意味着您可以将该文件作为可执行文件运行(无论它是二进制文件还是脚本)。
对于目录来说,这有点微妙。r
意味着你可以列表该目录中的文件(例如,使用ls /path/to/dir
),w
意味着您可以在该目录中创建新文件(或从该目录中删除现有文件。)但您需要x
能够访问该目录中的任何文件,如果您没有x
目录,您就无法cd
访问该目录,也无法真正打开该目录内的文件,即使您知道它们存在。(这允许奇怪的设置,其中有r
但没有x
,您可以列出文件名但不能打开任何文件,而有x
但没有r
您只能在已经知道其名称的情况下打开目录中的文件,因为您无法列出目录中的文件名。)
假设您有权限在目录中创建新文件,则您创建的新文件将以您的用户为所有者,默认情况下,您的主要组将作为其“组所有者”。但情况并非总是如此!
还记得我之前提到过 setgid 位吗?好吧,如果目录已设置 setgid 位(可以使用 进行设置chmod g+s /path/to/dir
),则在该目录中创建的新文件将继承目录本身的组,而不是创建该目录的用户的主组。此外,如果您在启用 setgid 的目录下创建新的子目录,则该子目录也将启用 setgid 位。(这对于保留整个子树的组继承属性是必要的。)
这个目录上的 setgid 位技术对于实现共享目录非常有用。我们很快就会讲到这一点。
值得关注的一点是,BSD 家族中的 Unix 系统(例如 FreeBSD、NetBSD、OpenBSD) 总是表现得像在目录中设置 setgid 位一样。这样,用户的主要组就没那么有意义了,因为在文件创建期间成为组通常是该组最明显的特征。
另一个有趣的概念是“umask”,它是一组在创建新文件或目录时被“屏蔽”的位。您可以使用命令在 shell 中检查您的 umask umask
,也可以使用该命令和参数来修改当前的 umask。典型值为umask 002
、umask 022
、umask 027
等。
umask 中的位指的是rwx
位,三个八进制数字以权限模式映射到用户、组和其他位。因此,umask 002
将保留用户和组的所有位(0 表示不屏蔽),同时阻止w
其他位(2 表示w
.)。它们将使文件保持用户和组可写,但只有其他人可读。umask 027
另一方面,只有用户可写,只有组可读/可执行但不能写,其他人无权访问(7 表示屏蔽所有rwx
.)
每次创建新文件时都会umask
使用。应用程序通常会指定所需的权限,通常在最自由这样,umask 就可以将其限制为更实际的权限。例如,普通应用程序将要求使用 0666 ( rw-rw-rw-
) 权限创建文件,并期望 umask 至少会删除全球可写位。目录通常将使用 0777 ( rwxrwxrwx
) 创建,假设情况相同。
那么我们怎样才能把这一切整合在一起呢?
基于 Red Hat 的 Linux 发行版(例如 RHEL、CentOS 和 Fedora)通常使用的设置非常灵活,值得研究。
对于每个创建的用户,也会创建一个同名的组(通常具有与用户的 UID 匹配的 GID),并将该组设置为该用户的主要组。该组旨在包含仅有的用户使用相同的名称。因此,我的用户的文件通常被创建为filbranden:filbranden
,我自己的主要组控制组权限位。
由于组本质上与用户本身相同,因此umask
设置为 002,这意味着所有文件和目录都将群组可写默认情况下。
那么如何锁定目录以使其私有化?很简单,只需从顶级目录中删除“其他”的权限位即可。例如,如果我使用chmod 770 ~
(或者700
也可以,770
因为主要组是我自己,所以可以工作),其他用户将无法访问任何我主目录下的文件。里面的文件有“其他”的读取或执行位,但这并不重要,因为缺少x
顶级目录本身的位意味着它们永远无法遍历该目录。
那么如何实现共享目录呢?很简单。首先创建一个组,并将所有要协作处理该项目的用户添加到该组。接下来,为该项目创建一个(或多个)目录。将目录的“组所有者”设置为您刚刚创建的组。最后,在这些目录上启用 setgid 位。该组的所有成员都将能够在这些目录中创建文件。由于他们都有umask 002
,因此他们创建的文件将是组可写的。并且由于顶级目录中的 setgid 位,所有文件都将归共享组(而不是每个用户的主要组)所有。这意味着组中的用户将能够修改由其他成员因为他们对这些文件有写权限。
这些共享目录可以是全世界可读的(通过保留顶级目录中“其他”的r
和x
权限),也可以是组私有的(通过删除这些权限)。
这就是要点。Unix/Linux 权限通常如何工作以及它们以这种方式工作的理由。
当然,还有很多注意事项。许多这些设置(例如umask
)存在于不同的会话中,并且它们可能不同步。将用户添加到组意味着他们通常需要再次登录才能使更改生效。虽然在启用 setgid-bit 的目录中创建文件会导致目录的组被继承,移动该目录中的现有文件通常不会改变所有权(因此,您最终可能会得到组共享中的文件,这些文件不是可由组内的其他成员修改。)删除文件的语义也可能有些棘手。
现代 Unix/Linux 系统保留了用户、组、文件所有权背后的所有逻辑。但它们通常还包括其他机制来强制执行权限,例如扩展文件 ACL,这些机制可以更精细地允许对目录树进行读/写访问,并且不会受到上面列出的基本权限的许多问题的影响。
答案3
是的。每个文件和目录都有所有者和组。如果您输入该命令,ll
它会为您提供当前目录中的文件列表,其中列出了所有者和组。
为了保持简单,不让您陷入复杂的困境:
如果这样做,chown root:www <FILEPATH>
您将所有者设置为 root,将组设置为 www。
如果这样做,chmod 750 <FILEPATH>
您将所有者权限设置为读/写/执行,将组权限设置为读/执行,并将其他(所有人)权限设置为无。
这意味着 root 将拥有完全访问权限,而 www 组中的任何人都可以读取/执行该文件。因此,如果您将用户“sarah”和用户“bill”添加到 www 组,那么他们也将拥有该文件的读取/执行权限。
如果我的系统上有三个组 A、B、C,并且想要在系统上分别设置权限 rw-、-wx、rx,该怎么办?
您无需为组设置权限。您可以为每个文件/目录设置权限,然后为每个文件/目录分配所有者和组。当您将用户放入组中时,他们就可以访问该组有权访问的每个文件/目录。
假设系统上有三个具有 750 权限的文件:
index.html(根:A)
index.txt (根:B)
index.php (根目录:C)
所有者 (root) 对所有文件具有完全访问权限 (读取/写入/执行)。A
组中的任何人都可以读取/执行 index.html(但不能读取/执行 index.txt 或 index.php)。B 组中的任何
人都可以读取/执行 index.txt(但不能读取/执行 index.html 或 index.php)。C
组中的任何人都可以读取/执行 index.php(但不能读取/执行 index.html 或 index.txt)。
用户“sarah”无法访问任何文件,因为她不是所有者(root)也不属于任何组 A、B 或 C。但是,如果您将用户“sarah”添加到组 A 和 B,那么她将拥有对 index.html 和 index.txt 的读取/执行权限(但没有对 index.php 的权限)。如果您将用户“bill”添加到组 B 和 C,那么他将拥有对 index.txt 和 index.php 的读取/执行权限(但没有对 index.html 的权限)。
https://linux.die.net/man/1/chown
https://linux.die.net/man/1/chmod