所以我试图理解 Linux 中组和权限的概念,并且非常困惑。在我的笔记本电脑上,我是唯一用户,因此是超级用户,我了解更改文本文件的文件权限(chmod +x)以使其可执行或更改读写权限(chmod + /- rw)
但是我并没有真正理解组的概念。从我收集到的一组只是一群用户。(但这是否意味着一个用户可以属于多个组?)据我所知,一个组基本上是为了更容易rwx
为一群用户(即组)设置/取消设置权限。
但现在在这个网站上,作者说:
Linux 中的权限分为三个级别:所有者、组和其他。所有者是拥有文件/文件夹的用户,该组包括文件组中的其他用户,而其他仅代表不是所有者或组中的所有其他用户。
这是否意味着除了具有所有者(即创建文件的人的用户标识)的文件之外,该文件还有一个“组所有者”?这个组通常是文件所有者所属的组之一吗?
如果我的系统上有三个组 A、B、C 并想分别在系统上设置权限 ,怎么办rw-
?-wx
r-x
提出上述问题很可能表明我对 Unix 中“组”和“组权限”的心理模型是有缺陷的。
我试过阅读一堆文章,但我似乎缺少理解组和组许可概念的基本内容。有人可以给我一个简洁的解释或向我推荐一些关于这个主题的更清晰的文章吗?
是的,是的。
使设置权限变得更加容易的一种方法是,当组需要访问分散在系统中的许多文件或文件夹时。
例如,每当有新用户加入时,否则您将需要逐个查找所有这些文件并尝试猜测诸如“如果用户 A、B、C 有权访问,则应添加用户 D”之类的内容。但是,如果这些权限只是列出了一个组名,那么您根本不需要更新它们——您只需将用户添加到一个组中,就可以了。
(不仅限于文件权限——一些系统服务也可以配置为授予组而不是单个用户的访问权限,具有与此处相同的优点。)
是的。每个用户都有一个“主组”,新创建的文件属于该组。但是,即使是非 root 用户也可以使用 chown/chgrp 将他们自己的文件重新分配给他们当前所属的任何组。
(有一个例外:如果目录设置了 'setgid' 位,则其中新创建的文件继承目录的组,而不是创建者的组。这更接近 Windows NTFS 默认的工作方式。)
当然,当文件一次只能有一个组时,这种“组所有者”系统有点限制。请参阅下一节。
然后,您使用另一个称为“ACL”(访问控制列表)的功能,顾名思义,它允许您指定要授予访问权限的用户和组的任意列表。
Linux 支持 POSIX ACL 格式,它主要是现有模型的直接扩展。也就是说,如果您首先将现有权限重写为:
现在您可以使用
setfacl
或chacl
添加三个附加组:注意避免混淆: POSIX ACL 尝试尽可能地与传统的 chmod 保持兼容,但这会导致一个令人惊讶的特性。一旦您将 ACL 添加到文件中,其中的“组”字段
ls -l
将开始显示称为“掩码”的内容,并且类似的命令chmod g-w
将拒绝对所有 ACL 条目的写访问,而不仅仅是对“所有者组”。如果 Linux 甚至 Unix 可以只使用 ACL,为什么还要使用“所有者/组/其他”分类?之所以如此,是因为这种简单的分类比 ACL 支持早了几十年。
Unix 最初采用简单的方法,就像当时大多数其他操作系统所做的那样——要么是由于磁盘空间限制(权限位只适合两个字节),要么是经过深思熟虑的设计决策(当时 Multics 可能有精心设计的 ACL ,但 Unix 中的很多东西都被有意简化了)。
最终,API 变得一成不变——可以添加新的,但无法更改现有的“chmod”,因为程序已经期望它以某种方式工作。(即使在添加 ACL 之后,OpenVMS 也必须保持其类似的权限位系统。)
除此之外,不幸的是,它是唯一在所有类 Unix 操作系统之间交叉兼容的系统。其他一些 Unix(例如 FreeBSD、Solaris)可能使用完全不同的 ACL 格式,而其他一些(OpenBSD)则根本不支持 ACL。还可以与 Windows 进行比较,Windows 中的所有文件保护都是基于 ACL 的。
Linux/Unix 组的概念可能令人困惑。但让我们试着解开它。
文件和目录同时具有所有者和组(或您所说的“组所有者”。)它们还具有三组
rwx
权限位,一组用于用户,一组用于组,一组用于其他。此外,它们还有另外三个权限:setuid、setgid 和sticky。文件或目录的用户和组在内部存储为 UID 和 GID,它们是无符号整数,用作用户和组的内部标识符。系统中的用户有一个 UID 和一个 GID(通常在
/etc/passwd
文件中设置),该文件中的 GID 设置用于指示用户的主要组。此外,一个用户可能属于更多组(通常在文件中配置,该/etc/group
文件列出了系统中每个组的其他用户。)您可以使用该命令检查用户的 UID、GID、主要组和其他组,该
id
命令将为运行该命令的用户列出所有这些信息。当您尝试访问文件或目录时,系统将尝试根据权限位验证您的访问权限。特别是,它将首先查看是否使用用户、组或其他位。如果您的 UID 与访问文件的用户的 UID 完全匹配,则将使用“用户”位。对于组,如果您的主要组与文件的组匹配,或者如果任何其他组(由 报告
id
)与该组匹配,则将使用“组”位。否则,如果这些都不匹配,则将使用“其他”位。文件权限的含义相当简单,
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 位的目录中创建文件会导致目录组被继承,但将现有文件移动到该目录通常不会更改所有权(因此您最终可能会在组共享中得到不可修改的文件由该组的其他成员。)删除文件的语义也可能有些棘手。现代 Unix/Linux 系统保留了用户、组、文件所有权背后的所有逻辑。但它们通常还包括强制执行权限的额外机制,例如扩展文件 ACL,它可以更细化地允许对目录树进行读/写访问,并且不会遇到上面列出的许多基本权限问题。
是的。每个文件和目录都有一个所有者和一个组。如果您键入命令
ll
,它会为您提供当前目录中的文件列表,其中列出了所有者和组。试图保持简单,而不是用复杂性来轰炸你:
如果您这样做
chown root:www <FILEPATH>
,则将所有者设置为 root,将组设置为 www。如果您这样做
chmod 750 <FILEPATH>
,则将所有者权限设置为读/写/执行,将组权限设置为读/执行,将其他(每个人)权限设置为无。这意味着 root 将拥有完全访问权限,并且 www 组中的任何人都可以读取/执行该文件。因此,如果您将用户 'sarah' 和用户 'bill' 添加到 www 组,那么他们也将拥有文件的读取/执行权限。
您没有对组设置权限。您为每个文件/目录设置权限,然后为每个文件/目录分配所有者和组。当您将用户放在组中时,它使他们可以访问该组有权访问的每个文件/目录。
假设您在系统上有三个具有 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