Skip to content

Latest commit

 

History

History
1500 lines (902 loc) · 63 KB

File metadata and controls

1500 lines (902 loc) · 63 KB

四、管理用户和组

Linux 是一个多用户、多任务操作系统,这意味着多个用户可以在共享平台资源的同时访问操作系统,内核同时独立地为每个用户执行任务。 Linux 提供了必要的隔离和安全机制,以避免多个用户访问或删除彼此的文件。

当多个用户访问系统时,权限就起作用了。 我们将了解权限如何在 Linux 中工作,以及它们的基本读、写和执行原则。 我们将向您介绍具有完全访问操作系统资源权限的超级用户(root)帐户的概念。

在此过程中,我们将对所学的主题采取动手实践的方法,通过实际例子进一步加深对关键概念的吸收。 本章涵盖以下主题:

  • 管理用户
  • 管理组
  • 管理权限

我们希望在本章结束时,您将熟悉用于创建、修改和删除用户和组的命令行实用程序,同时熟练地处理文件和目录权限。

让我们快速看一下学习本章所必需的技术要求。

技术要求

我们需要一个可以工作的 Linux 发行版安装在虚拟机(VM)或桌面平台上。 如果你还没有一个,第 1 章*安装 Linux,*将带你完成相关的过程。 在本章中,我们将使用 Ubuntu 或 CentOS,但使用的大多数命令和示例都适用于任何其他 Linux 平台。

管理用户

在这个上下文中,用户是使用计算机或系统资源的任何人。 在最简单的形式中,Linux 用户用户帐户是被一个名称和一个惟一标识符,被称为【显示】UID。**

*从纯技术角度来看,在 Linux 中我们有以下几种类型的用户:

  • 普通(或普通)用户—通用的日常用户帐户,主要适用于个人使用和常见的应用和文件管理任务,对系统范围内的资源具有有限的访问权限。 一个普通用户帐户通常有一个登录shell 和一个home目录。
  • 系统用户——这些用户与普通用户帐户相似,除了他们可能没有登录 shell 或主目录。 系统帐户通常分配给后台应用服务,主要是出于安全原因和限制与相关资源关联的攻击表面——例如,处理公共请求的 web 服务器守护进程应该作为系统帐户运行,理想情况下不需要登录或root特权。 因此,通过 web 服务器暴露的可能的漏洞将严格隔离于关联系统帐户的有限操作领域。
  • 超级用户-这些是特权用户帐户,具有对系统资源的完全访问权限,包括创建、修改和删除用户帐户的权限。 root用户是超级用户的一个例子。

在 Linux 操作系统中,只有具有sudo权限的root用户或用户(sudoers)才能创建、修改或删除用户帐户。

理解 sudo

在 Linux 中,root用户是默认的超级用户帐户,它可以在系统上执行任何操作。 理想情况下,出于安全和安全方面的原因,通常应该避免在系统上充当root。 在sudo中,Linux 提供了一种机制的普通用户帐户提升为超级用户特权,并使用了额外的安全层。 这样,通常使用sudo用户而不是root用户。

sudo是一个命令行实用程序,允许被允许的用户使用超级用户或其他用户的安全特权执行命令(取决于本地系统的安全策略)。 sudo最初代表超级用户做,因为它最初实现了只作为超级用户,但后来扩展到不仅支持超级用户,还支持其他(受限的)用户模拟。 因此,它也被称为替代用户做。 然而,由于在 Linux 管理任务中经常使用,它被认为是超级用户执行

Linux 中大多数用于管理用户的命令行工具都需要sudo特权,除非相关任务由root用户执行。 如果我们想避免使用根上下文,那么在我们拥有一个具有超级用户特权的用户帐户之前,我们不能真正地继续本章的其余部分——特别是创建一个用户。 所以,让我们先来看看这个“先有鸡还是先有蛋”的情况。

大多数 Linux 发行版在安装期间除了root之外,还创建了一个具有超级用户特权的额外用户帐户。 如前所述,其原因是为高架操作提供额外的安全层。 检查用户帐户是否具有sudo权限的最简单方法是在终端中运行以下命令,同时使用相关用户帐户登录:

sudo -v

根据sudo手册(man sudo),-v选项将导致sudo更新用户的缓存凭证,并在缓存凭证过期时对用户进行身份验证。

如果用户(例如julian)在本地机器上没有超级用户特权(例如neptune),上述命令将产生以下(或类似)错误:

Sorry, user julian may not run sudo on neptune.

在最近的 Linux 发行版中,sudo命令的执行通常会在有限的时间内授予更高的权限。 例如,Ubuntu 有 15 分钟的sudo提升跨度,在此之后,sudo用户将需要再次认证。 如果在sudo缓存凭据超时期间执行sudo的后续调用,可能不会提示输入密码。

如果我们没有默认的超级用户帐户,我们总是可以使用根上下文来创建新用户(参见下一章)并将其提升为sudoer特权。 我们将在本章后面的创建超级用户部分了解更多。

现在,让我们看看如何创建、修改和删除用户。

创建、修改、删除用户

在本节中,我们将探索一些命令行工具和一些用于管理用户的常见任务。 在 Ubuntu 和 CentOS 中显示了示例命令和过程,但同样的原则适用于任何其他 Linux 发行版。 一些用户管理命令行界面(【显示】CLI)工具可能不同或可能不是在特定的 Linux 平台上(例如,useradd是不可以在高山应该使用 Linux 和adduser相反)。 请查看您选择的 Linux 发行版的文档中对应的命令。

创建用户

要创建用户,我们可以使用useraddadduser命令,尽管在某些 Linux 发行版(例如 Debian 或 Ubuntu)上,推荐的方法是使用adduser命令而不是低级的useradd实用程序。 我们将在本节中介绍这两种方法。

adduser是一个使用useradd的 Perl 脚本—基本上是useradd命令的一个扩展—具有用户友好的引导配置。 这两个命令行工具在 Ubuntu 和 CentOS 中都是默认安装的。 让我们简要地看一下这些命令。

使用 useradd 创建用户

useradd命令的语法为,如下所示:

useradd [OPTIONS] USER

在最简单的调用中,以下命令创建一个用户帐户(julian):

sudo useradd julian

用户信息存储在/etc/passwd文件中。 以下是julian的相关用户数据:

cat /etc/passwd | grep julian

在我们的例子中,输出如下:

Figure 4.1 – The user record created with useradd

图 4.1 -使用 useradd 创建的用户记录

让我们分析一下相关的用户记录。 每个条目由冒号(:)分隔,列在这里:

  • julian:用户名

  • x:加密的密码(密码散列存储在/etc/shadow中)

  • 1001:UID

  • 1001:用户组 ID(组 ID)

  • (在本例中,为空)General Electric Comprehensive Operating Supervisor(GECOS)字段(例如,显示名称)将在下面解释

  • /home/julian:用户主文件夹

  • /bin/sh: The default login shell for user

    重要提示

    GECOS 字段是一个以逗号分隔的属性字符串,反映关于用户帐户的一般信息(例如,真实姓名; 公司; 电话号码)。 在 Linux 操作系统中,GECOS 字段是用户记录中的第五个字段。 更多信息见https://en.wikipedia.org/wiki/Gecos_field

我们也可以使用getent命令来检索上述用户信息,如下所示:

getent passwd julian

要查看与用户关联的 UID(uid)、GID(gid)和组成员关系,可以使用id命令,如下所示:

id julian

这个命令给我们以下输出:

Figure 4.2 – The UID information

图 4.2 - UID 信息

通过简单调用useradd,该命令使用一些直接默认值(如枚举值)创建用户(julian),而其他与用户相关的数据为空—例如,我们还没有为用户指定全名或密码。 另外,虽然主目录有一个默认值(例如,/home/julian),但除非使用-m--create-home选项调用useradd命令,否则不会创建实际的文件系统文件夹,如下所示:

sudo useradd -m julian

如果没有主目录,常规的用户将无法将其文件保存在系统的私有位置。 另一方面,有些系统帐户可能不需要主目录,因为它们没有登录 shell。 例如,数据库服务器(例如,PostgreSQL)可能会与非根系统帐户(例如,postgres),只需要访问数据库资源在特定位置(例如,/var/lib/pgsql),通过控制其他许可机制(例如,安全增强型 Linux(SELinux)。

对于我们的普通用户,如果我们还想指定一个全名(display name),命令会变成这样:

sudo useradd -m -c "Julian" julian

useradd-c, --comment选项参数需要一个注释,也称为GECOS字段(我们的用户记录中的第五个字段),有多个逗号分隔的值。 在本例中,我们指定全名(例如Julian)。 有关更多信息,请查看useradd手册(man useradd)或useradd --help

用户仍不会有密码,因此,就没有办法为用户登录(例如,通过一个图形用户界面(GUI)或**【显示】Secure Shell (SSH****)。 要为julian创建密码,我们调用passwd命令,如下所示:******

sudo passwd julian

你应该看到如下的输出:

Figure 4.3 – Creating or changing the user password

图 4.3 -创建或更改用户密码

passwd命令将提示输入新用户的密码。 设置了密码后,将有一个新条目添加到/etc/shadow文件中。 该文件存储每个用户的安全密码散列(不是密码!)。 只有超级用户可以访问该文件的内容。 以下是为用户julian检索相关信息的命令:

sudo getent shadow julian

还可以使用以下命令:

sudo cat /etc/shadow | grep julian

设置好密码后,一般情况下用户可以登录系统(通过 SSH 或 GUI)。 如果 Linux 发行版有 GUI,新用户将显示在登录屏幕上。 下面是 Ubuntu 的截图:

Figure 4.4 – The new user login in Ubuntu

图 4.4 -新用户登录 Ubuntu

如前所述,通过useradd命令,我们可以对创建用户帐户的方式进行低级粒度控制,但有时我们可能更喜欢用户友好的方法。 输入adduser命令。

使用 adduser 创建用户

adduser命令是useradd的 Perl 包装器。 adduser命令的语法如下所示:

adduser [OPTIONS] USER

sudo可能提示输入超级用户密码。 adduser将提示输入新用户的密码和其他用户相关信息(如图图 4.5所示)。

我们用adduser创建一个新用户账号julian,如下:

sudo adduser julian

上面的命令输出如下:

Figure 4.5 – The adduser command

图 4.5 - adduser 命令

在 CentOS 中,前面对adduser命令的调用将简单地运行,而不提示用户输入密码或任何其他信息。

我们可以看到/etc/passwd中与getent相关的用户条目如下:

getent passwd julian

下面是输出:

Figure 4.6 – Viewing user information with getent

图 4.6 -使用 getent 查看用户信息

在前面的示例中,我们创建了一个普通用户帐户。 管理员或超级用户也可以将普通用户的权限提升为超级用户。 让我们来看看。

创建一个超级用户

当一个普通用户被赋予运行sudo的能力时,他们就成为超级用户。 让我们假设通过创建用户一节中所示的任何示例创建了一个常规用户。

将用户提升为超级用户(或sudoer)需要一个sudo组成员。 在 Linux 中,sudo组是为具有更高权限或root权限的用户保留的系统组。 要使用户julian成为 sudoer,只需将用户添加到sudo组,如下所示:

sudo usermod -aG sudo julian

usermod-aG选项指示命令将用户(-a, --append)附加到指定的组(-G, --group中——在本例中是sudo

要验证我们的用户现在是 sudoer,首先通过运行以下命令确保相关的用户信息反映了sudo成员资格:

id julian

这给了我们以下输出:

Figure 4.7 – Looking for the sudo membership of a user

图 4.7 -查找用户的 sudo 成员

输出显示groups标记中的sudo组成员身份(GID)为27(sudo)

验证用户juliansudo访问权限,运行如下命令:

su - julian

上面的命令提示输入用户julian的密码。 成功的登录通常会验证超级用户上下文。 或者,用户(julian)可以在其终端会话中运行sudo -v命令来验证sudo特权。 有关超级用户特权的更多信息,请参见本章前面的理解 sudo一节。

由于创建了多个用户,系统管理员可能希望查看或列出系统中的所有用户。 在下一节中,我们将提供一些完成此任务的方法。

查看用户

超级用户有几种方法可以查看系统中配置的所有用户。 如前所述,用户信息存储在/etc/passwd/etc/shadow文件中。 除了简单地查看这些文件外,我们还可以解析它们并使用下面的命令只提取用户名:

cat /etc/passwd | cut -d: -f1 | less

或者,我们可以解析/etc/shadow文件,如下所示:

sudo cat /etc/shadow | cut -d: -f1 | less

在前面的命令中,我们从相关文件中读取内容(使用cat)。 接下来,我们将结果管道到基于分隔符的解析(在:分隔符上使用cut),并选择第一个字段(-f1。 最后,我们使用less命令选择结果的分页显示。

注意对shadow文件使用sudo,因为只有超级用户才能访问,这是由于密码散列数据的敏感性。 或者,我们可以使用getent命令来检索用户信息。

下面的命令列出了系统中配置的所有用户:

getent passwd

上述命令读取的是/etc/passwd文件。 或者,我们可以从/etc/shadow中检索相同的信息,如下所示:

sudo getent shadow

对于这两个命令,我们可以进一步将getent输出管道到| cut -d: -f1,只列出用户名,如下所示:

sudo getent shadow | cut -d: -f1 | less | column

输出类似如下(摘录):

Figure 4.8 – Viewing usernames

图 4.8 -查看用户名

创建新用户后,管理员或超级用户可能需要更改某些与用户相关的信息,例如密码、密码过期、全名或登录 shell。 接下来,我们来看一下完成这项任务的一些最常见的方法。

修改用户

超级用户可以通过usermod命令修改用户设置,语法如下:

usermod [OPTIONS] USER

本节中的示例适用于我们之前使用useradd命令的最简单调用创建的用户(julian)。 如前一节所述,/etc/passwd中的相关用户记录没有用户的全名,用户也没有密码。

让我们为我们的用户(julian)更改以下设置:

  • 全名:到Julian(最初为空)。
  • 主文件夹:移动到/local/julian(从默认的/home/julian)。
  • 登录 shell:/bin/bash(从默认/bin/sh开始)。

下面显示了更改所有上述信息的命令行实用程序:

sudo usermod -c "Julian" -d /local/julian -m -s /bin/bash julian

下面是命令选项,简要说明:

  • -c, --comment "Julian":完整用户名。
  • -d, --home local/julian:用户的新主目录。
  • -m, --move:将当前主目录的内容移动到新位置。
  • -s, --shell /bin/sh:用户登录 shell。

使用getent命令检索的相关更改如下所示:

getent passwd julian

我们得到以下输出:

Figure 4.9 – The user changes reflected with getent

图 4.9 - getent 反映了用户的变化

下面是使用usermod命令行实用程序更改用户设置的更多示例。

更改用户名

usermod-l, --login选项参数指定一个新的登录用户名。 下面的命令将用户名从julian更改为balog(即从名改为姓),如下所示:

sudo usermod -l "balog" julian

在生产环境中,前面的命令可能更复杂,因为我们可能还希望更改用户的显示名称和主目录(出于一致性原因)。 在前面的使用 useradd部分创建用户的示例中,我们展示了-d, --home-m, --move选项参数,它们将适应这些更改。

锁定或解锁用户

超级用户或管理员可以通过usermod-L, --lock选项选择暂时或永久锁定某个用户,如下所示:

sudo usermod -L julian

由于上面的命令,用户julian的登录尝试将被拒绝。 如果用户尝试以 SSH 方式进入 Linux 机器,他们将得到一个Permission denied, please try again错误消息。 此外,如果 Linux 平台有 GUI,那么相关的用户名将从登录屏幕上删除。

为了解锁用户,我们调用-U, --unlock选项参数,如下所示:

sudo usermod -U julian

该命令恢复了该用户的系统访问权限。

有关usermod实用程序的更多信息,请查看相关文档(man usermod)或命令行帮助(usermod --help)。

虽然推荐的修改用户设置的方法是通过usermod命令行实用程序,但一些用户可能会发现手动编辑/etc/passwd文件更容易。 下面一节将展示如何做到这一点。

通过/etc/passwd 修改用户

超级用户也可以手动编辑/etc/passwd文件,通过更新相关行来修改用户数据。 尽管可以使用您选择的文本编辑器(例如nano)进行编辑,但我们建议使用vipw命令行实用程序以获得更安全的方法。 vipw启用所需的锁以防止可能的数据损坏——例如,如果超级用户在普通用户更改密码的同时执行更改操作。

下面的命令通过提示首选的文本编辑器(例如nanovim)来启动/etc/passwd文件的编辑:

sudo vipw

例如,我们可以通过编辑以下行来更改用户julian的设置:

julian:x:1001:1001:Julian,,,:/home/julian:/bin/bash

冒号(:)分隔字段的含义已经在前面的使用 useradd部分中描述过。 这些字段都可以在/etc/passwd文件中手工更改,导致更改等同于相应的usermod调用。

有关vipw命令行实用程序的更多信息,您可以参考相关的系统手册(man vipw)。

用户帐户的另一项相对常见的管理任务是更改密码或设置密码过期时间。 虽然usermod可以通过-p--password选项更改用户密码,但它需要加密的散列字符串(而不是明文密码)。 生成加密的密码哈希值将是一个额外的步骤。 一种更简单的方法是使用passwd实用程序。

超级用户(管理员)可以修改用户(例如julian)的密码,命令如下:

sudo passwd julian

有时,管理员需要从系统中删除特定的用户。 下一节将展示完成此任务的两种方法。

删除用户

将用户从系统中删除的最常见方法是使用userdel命令行工具。 userdel命令的一般语法如下所示:

userdel [OPTIONS] USER

例如,要删除用户julian,超级用户将运行以下命令:

sudo userdel -f -r julian

下面是命令选项,简要说明:

  • -f, --force:删除用户主目录中的所有文件,即使不属于该用户
  • -r, --remove:删除用户的主目录和邮件假脱机

userdel命令从系统中删除相关的用户数据,包括用户的主目录(在使用-f--force选项调用时)以及/etc/passwd/etc/shadow文件中的相关条目。

还有另一种方法,它在一些奇怪的清理场景中可能很方便。 下一节将展示如何做到这一点。

通过/etc/passwd 和/etc/shadow 删除用户

超级用户可以编辑/etc/passwd/etc/shadow文件,并为用户手动删除相应的行(例如julian)。 请注意,这两个文件必须被编辑一致和完整删除相关用户帐户。

使用vipw命令行实用程序编辑/etc/passwd文件,如下所示:

sudo vipw

删除以下行(针对用户julian):

julian:x:1001:1001:Julian,,,:/home/julian:/bin/bash

接下来,在vipw中使用-s--shadow选项编辑/etc/shadow文件,如下:

sudo vipw -s

删除以下行(针对用户julian):

julian:$6$xDdd7Eay/RKYjeTm$Sf.../:18519:0:99999:7:::

在编辑完上述文件后,超级用户可能还需要删除被删除用户的主目录,如下所示:

sudo rm -rf /home/julian

有关userdel实用程序的更多信息,请查看相关文档(man userdel)或命令行帮助(userdel --help)。

到目前为止所学的用户管理概念和命令只适用于系统中的单个用户。 当系统中的多个用户具有相同的访问级别或权限属性时,它们被统称为一个组。 可以将组视为独立的组织单元,我们可以创建、修改或删除。 我们还可以定义和修改与组关联的用户成员关系。 下一节重点讨论组管理内部。

群组管理

Linux 使用组来组织用户。 简单地说,组是共享一个公共属性的用户集合。 这些群体的例子可以是员工开发人员管理人员,等等。 在 Linux 中,组由 GID 唯一标识。 同一组内的用户使用相同的 GID。

从用户的角度来看,这里概述了两种类型的组:

  • 主组—用户的初始(默认)登录组
  • 补充组—用户也是成员的组列表; 又称次级组

每个 Linux 用户都是主组的成员。 一个用户可以属于多个补充组,也可以不属于任何补充组。 换句话说,每个 Linux 用户都有一个强制性的主组,一个用户可以有多个或没有补充的组成员关系。

从实际的角度来看,我们可以将组看作是对一定数量的用户进行协作的宽松上下文。 设想一个拥有特定于开发人员的资源的开发人员组。 这个组中的每个用户都可以访问这些资源。 开发人员组以外的用户可能没有访问权限,除非他们使用组密码进行身份验证(如果组有组密码的话)。

在下一节中,我们将提供如何管理组和设置用户组成员关系的详细示例。 大多数相关命令需要超级用户或sudo权限。

组的创建、修改、删除

虽然我们的主要焦点仍然是组管理任务,但一些相关操作仍然涉及到用户相关的命令。 groupaddgroupmodgroupdel等命令行实用程序的目标分别是创建、修改和删除组。 另一方面,useraddusermod命令在将用户与组关联时带有特定于组的选项。 我们还将向您介绍gpasswd,这是一个专门用于组管理的命令行工具,它结合了与用户和组相关的操作。

记住这一点后,让我们看看如何创建、修改和删除组,以及如何为用户操作组成员关系。

创建组

要创建一个新组,超级用户调用groupadd命令行实用程序。 下面是相关命令的基本语法:

groupadd [OPTIONS] GROUP

让我们创建一个新组(developers),默认设置如下:

sudo groupadd developers

组信息存储在/etc/group文件中。 以下是developers组的相关数据:

cat /etc/group | grep developers

该命令输出如下:

Figure 4.10 – The group with default attributes

图 4.10 -具有默认属性的组

让我们分析一下相关的小组记录。 每个条目由冒号(:)分隔,列在这里:

  • developers:组名
  • x:加密密码(密码散列存储在/etc/gshadow中)
  • 1002:gid

我们也可以使用getent命令检索前面的组信息,如下所示:

getent group developers

超级用户可以使用groupadd-g, --gid选项参数创建具有特定 GID 的组。 例如,下面的命令创建 GID 为1200developers组:

sudo groupadd -g 1200 developers

有关groupadd命令行实用程序的更多信息,请参阅相关文档(man groupadd)。

组相关数据存储在/etc/group/etc/gshadow文件中。 /etc/group文件包含通用组成员信息,而/etc/gshadow文件存储每个组的加密密码散列。

让我们简单看一下组密码。

理解组密码

默认情况下,在使用groupadd命令(例如groupadd developers)的最简单调用创建组时,组没有密码。 尽管groupadd支持加密的密码(通过-p, --password选项参数),但这需要一个额外的步骤来生成安全的密码散列。 有一种创建组密码的更好、更简单的方法:使用gpasswd命令行实用工具。

下面的命令为developers组创建密码:

sudo gpasswd developers

我们会被提示输入并重新输入密码。

gpasswd是一个命令行工具,用于帮助完成日常的组管理任务。

组密码的目的是保护对组资源的访问。 当组成员之间共享组密码时,组密码本质上是不安全的,但是 Linux 管理员可以选择保持组密码私有,而组成员在组的安全上下文中不受阻碍地协作。

这里快速解释一下它是如何工作的。 当特定组(例如developers)的成员登录到该组时(使用newgrp命令),不会提示用户输入组密码。 当不属于该组的用户试图登录时,将提示他们输入组密码。

一般情况下,一个组可以有管理员、成员和密码。 作为组管理员的组的成员可以使用gpasswd而不需要提示输入密码,只要他们已经登录到组。 另外,组管理员不需要超级用户权限来为其所属的组执行组管理任务。

在下一节中,我们将进一步研究gpasswd,进一步关注组管理任务,以及将用户添加到组和从组中删除用户。 但是现在,让我们将注意力严格地放在组级别上,看看如何修改用户组。

修改组

修改组的定义的最常见方法是通过groupmod命令行实用程序。 下面是该命令的基本语法:

groupmod [OPTIONS] GROUP

更改组定义时最常见的操作与 GID、组名和组密码有关。 让我们来看看这些变化。 假设前面创建的组名为developers,GID 为1200。要将 GID 更改为1002,超级用户调用带有-g, --gid选项参数的groupmod命令,如下所示:

sudo groupmod -g 1002 developers

要将组名从developers更改为devops,我们调用-n, --new-name选项,如下所示:

sudo groupmod -n devops developers

我们可以使用以下命令验证对devops组的上述更改:

getent group devops

该命令产生以下结果:

Figure 4.11 – Verifying the group changes

图 4.11 -验证组的更改

要修改devops的组密码,最简单的方法是使用gpasswd,如下所示:

sudo gpasswd devops

提示输入并重新输入密码:

要删除devops的组密码,我们使用-r, --remove-password选项调用gpasswd命令,如下所示:

sudo gpasswd -r devops

有关groupmodgpasswd的更多信息,请参阅这些实用程序(man groupmodman gpasswd)的系统手册,或者只需为每个实用程序调用-h, --help选项。

接下来,我们来看一下如何删除组。

删除组

要删除组,我们使用命令行实用程序groupdel。 相关语法显示在这里:

groupdel [OPTIONS] GROUP

默认情况下,Linux 强制主组和与该主组关联的用户之间的引用完整性。 在删除主组的用户之前,不能删除已分配为某些用户的主组的组。 换句话说,在默认情况下,Linux 不希望留给用户一个悬空的主 gid。

例如,假设用户julian将主组设置为devops,尝试删除devops组将导致错误,如下所示:

Figure 4.12 – Attempting to delete a primary group

图 4.12 -试图删除一个主组

超级用户可以选择强制删除一个主组,通过-f, --force选项调用groupdel,但这是不明智的。 该命令将导致主 gid 孤立的用户,并可能在系统中出现安全漏洞。 对这些用户的维护和删除也会成为问题。

超级用户可以运行带有-g, --gid选项参数的usermod命令,以更改用户的主组。 应该为每个用户调用该命令。 下面是从devops主组中删除用户julian的示例。 首先,让我们为用户获取当前数据,如下所示:

id julian

下面是输出:

Figure 4.13 – Retrieving the current primary group for the user

图 4.13 -检索用户的当前主组

usermod命令的-g, --gid选项参数同时接受GID和组名称。 指定的组必须已经存在于系统中,否则命令将失败。 如果要更改主要组(例如,改为developers),只需在-g, --gid选项参数中指定组名,如下所示:

sudo usermod -g developers julian

但是,让我们假设我们不希望将用户julian与一个特定的主组关联,但是我们需要为usermod -g指定一个主组。 解决这个难题的最简单方法是创建一个名为julian的组,其 GID 与 UID 匹配(在本例中为1001),如下所示:

sudo groupadd -g 1001 julian

现在我们已经定义了julian,我们可以安全地修改julian用户,使其拥有专属的主组,如下所示:

sudo usermod -g julian

我们可以通过以下命令验证主要组是否反映了更改:

id julian

现在输出显示julianUIDGID,如下所示:

Figure 4.14 – Changing the primary group of the user

图 4.14 -更改用户的主组

此时,可以安全删除组devops,如下所示:

sudo groupdel devops

有关groupdel命令行实用程序的更多信息,请查看相关的系统手册(man groupdel),或者简单地调用groupdel --help

通过/etc/group 修改组

管理员也可以通过手动编辑/etc/group文件,通过更新相关行来修改组数据。 尽管可以使用您选择的文本编辑器(例如nano)进行编辑,但为了更安全,我们建议使用vigr命令行实用工具。 vigr类似于vipr(用于修改/etc/passwd),并设置安全锁以防止在组数据的并发更改期间可能发生的数据损坏。

下面的命令通过提示首选文本编辑器(例如nanovim)来打开/etc/group文件进行编辑:

sudo vigr

例如,我们可以通过编辑以下行来更改developers组的设置:

developers:x:1200:julian,alex

当使用vigr命令删除组时,还会提示我们删除组阴影文件(/etc/gshadow)中的相应条目。 相关命令调用-s--shadow选项,如下所示:

sudo vigr -s

有关vigr实用程序的更多信息,请参阅相关的系统手册(man vigr)。

与大多数 Linux 任务一样,前面的所有任务都可以通过不同的方式来完成。 所选择的命令是最常见的,但在某些情况下,可能会有更合适的不同方法。

在下一节中,我们将了解如何将用户添加到主组和辅助组,以及如何从这些组中删除用户。

用户和组

到目前为止,我们只创建了没有关联用户的组。 空用户组没有多大用处,所以让我们向它们添加一些用户。

向组中添加用户

在开始将用户添加到组之前,我们先创建几个组。 在下面的示例中,我们通过指定组的 GID(通过groupadd命令的-g, --gid选项参数)来创建组:

sudo groupadd -g 1100 admin
sudo groupadd -g 1200 developers
sudo groupadd -g 1300 devops

接下来,我们创建两个用户(alexjulian),并将它们添加到刚刚创建的一些组中。 我们会有admin组设置为主组为用户,而developersdevops组被定义为二次【显示】(补充)【病人】。 代码可以在这里看到:**

sudo useradd -g admin -G developers,devops alex
sudo useradd -g admin -G developers,devops julian

useradd命令的-g, --gid选项参数指定(唯一的)主组(admin)。 -G, --groups选项参数提供次要组名(developersdevops)的逗号分隔列表(中间不包含空格)。

我们可以使用下面的命令验证两个用户的组成员资格:

id alex
id julian

上述命令输出如下:

Figure 4.15 – Verifying the group membership for users

图 4.15 -验证用户的组成员身份

可以看到,gid属性显示了主要的组成员:gid=100(admin)groups属性表示补充(次要)组:groups=1100(admin),1200(developers),1300(devops)

由于用户分散在多个组中,管理员有时会面临在组之间移动用户的任务。 下面的部分将展示如何进行此操作。

跨组移动和删除用户

在前面的示例的基础上构建,让假设管理员希望将用户alex移动(或添加)到名为managers的新辅助组。 请注意,根据前面的示例,用户alexadmin作为主要组,而developers/devops作为次要组(参见图 4.17id alex命令的输出)。

让我们先用 GID1400创建managers组。 代码可以在这里看到:

sudo groupadd -g 1400 managers

接下来,将现有用户alex添加到managers组。 我们使用带有-G, --groups选项参数的usermod命令来指定用户与相关联的辅助组。

附加辅助组给用户的最简单方法是调用usermod命令的-a, --append选项,如下所示:

sudo usermod -a -G managers alex

前面的命令将为用户alex保留现有的辅助组,同时添加新的managers组。 或者,我们可以运行以下命令:

sudo usermod -G developers,devops,managers alex

在前面的命令中,我们指定了多个组(中间没有空格!)

重要提示

我们保留了现有的次级组(developers/devops),附加到以逗号分隔的次级组managers。 如果我们只指定了managers组,用户alex将从developersdevops次要组中删除*。*

*要验证用户alex现在是managers组的一部分,运行以下命令:

id alex

下面是命令的输出:

Figure 4.16 – Verifying that the user is associated with the managers group

图 4.16 -验证用户与 managers 组相关联

我们可以看到,groups属性(高亮显示)包括managers组:1400(managers)的相关条目。

类似地,如果我们想要developersdevops次要组中删除用户alex,使只与managers次要组相关联,我们将运行以下命令:

sudo usermod -G managers alex

下面是输出:

Figure 4.17 – Verifying the secondary groups for the user

图 4.17 -验证用户的辅助组

groups标记现在显示主要组admin(默认情况下)和managers次要组。

从所有次要组中删除用户alex的命令如下所示:

sudo usermod -G '' alex

usermod命令有一个空字符串('')作为-G, --groups选项参数,以确保没有与用户关联的辅助组。 我们可以使用以下命令验证用户alex没有更多的从属组成员身份:

id alex

下面是输出:

Figure 4.18 – Verifying the user has no secondary groups

图 4.18 -验证用户没有辅助组

正如我们所看到的,groups标记只包含1100(admin)主 GID,默认情况下它总是为用户显示。

如果管理员选择从主组中删除用户alex或将其分配给其他主组,则必须运行带-g, --gid选项参数的usermod命令并指定主组名。 对于用户来说,主组总是必须存在的。

例如,要将用户alex移动到managers主组,管理员将运行以下命令:

sudo usermod -g managers alex

相关的用户数据变成这样:

id alex

该命令输出如下:

Figure 4.19 – Verifying the user has been assigned the new primary group

图 4.19 -验证用户已经被分配了新的主组

图 4.21中用户记录的gid属性反映了新的主组gid=1400(managers)

如果管理员选择配置用户alex没有一个特定的主要群体,他们必须首先创建一个独家*【T7 组】(命名为alex,为了方便)的 UID 和 GID 的匹配用户alex(1002),如下:*

sudo groupadd -g 1002 alex

现在,通过指定刚刚创建的独占主组(alex),可以将用户alex从当前主组(managers)中删除,如下所示:

sudo usermod -g alex

相关的用户记录变成这样:

id alex

下面是输出:

Figure 4.20 – Verifying the user has been removed from primary groups

图 4.20 -验证用户已从主要组中删除

用户记录的gid属性反映独占的主组(与用户匹配):gid=1002(alex)。 我们的用户不再属于任何其他主组。

对于 Linux 管理员来说,跨组添加、移动和删除用户可能成为越来越艰巨的任务。 随时知道哪些用户属于哪些组是有价值的信息,对于报告目的和用户自动化工作流都是如此。 下面的部分提供了一些用于查看用户和组数据的命令。

查看用户和组

在本节中,我们提供了一些可能有用的命令来检索组和组成员信息。 在我们进入任何命令之前,我们应该记住组信息存储在/etc/group/etc/gshadow文件中。 其中,前者拥有我们最感兴趣的信息。

我们可以解析/etc/group文件来检索所有组,如下所示:

cat /etc/group | cut -d: -f1 | column | less

该命令产生以下输出(摘录):

Figure 4.21 – Retrieving all group names

图 4.21 -检索所有组名

类似的命令可以使用getent,如下所示:

getent group | cut -d: -f1 | column | less

我们可以通过以下命令检索单个组(例如developers)的信息:

getent group developers

下面是输出:

Figure 4.22 – Retrieving information for a single group

图 4.22 -检索单个组的信息

前一个命令的输出还显示了developers组(julianalex)的成员。

要列出特定用户所属的所有组,可以使用groups命令。 例如,下面的命令列出了用户alex所属的所有组:

groups alex

下面是命令的输出:

Figure 4.23 – Retrieving group membership information of the user

图 4.23 -检索用户的组成员信息

上一个命令的输出显示用户alex的组,从主组(admin)开始。

用户可以使用groups命令行实用工具检索自己的组成员身份,而不需要指定组名。 在管理员(超级用户)用户packt的终端会话中执行如下命令:

groups

该命令会得到以下结果:

Figure 4.24 – The current user's groups

图 4.24 -当前用户的组

还有许多其他方法和命令来检索与用户和组相关的信息。 我们希望前面的示例提供了关于在哪里以及如何查找这些信息的基本概念。

接下来,让我们看看用户如何切换或登录到特定的组。

登录会话组

当用户登录系统时,组成员上下文自动设置为用户的主组。 一旦用户登录,任何用户发起的任务(如创建文件或运行程序)都与用户的主要组成员权限相关联。 用户还可以选择访问其他组中的资源,这些组也是用户的成员(即补充组或辅助组)。 要切换组上下文或使用新的组成员身份登录,用户调用newgrp命令行实用工具。

newgrp命令的基本语法是:

newgrp GROUP

在下面的示例中,我们假设一个用户(julian)是多个组的成员——admin作为主要组,developers/devops作为次要组:

id julian

下面是输出:

Figure 4.25 – A user with multiple group memberships

图 4.25 -拥有多个组成员的用户

让我们暂时模拟用户julian。 当以julian登录时,默认的登录会话具有以下用户和组上下文:

whoami

在我们的例子中,输出如下:

Figure 4.26 – Getting the current user

图 4.26 -获取当前用户

whoami命令提供当前 UID(请参阅man whoamiwhoami --help命令的详细信息),如下所示:

groups

下面是输出:

Figure 4.27 – Getting the current user's groups

图 4.27 -获取当前用户的组

groups命令显示当前用户所属的所有组(请参阅man groupsgroups --help命令的详细信息)。

用户还可以通过调用id命令查看自己的 id (user 和 gid),如下所示:

id

下面是输出:

Figure 4.28 – Viewing the current user and GID information

图 4.28 -查看当前用户和 GID 信息

id命令的各种调用提供了有关当前用户和组会话的信息。 下面的命令(带有-g, --group选项)检索用户当前组会话的 ID:

id -g
1100

在我们的示例中,前面的命令显示了1100—用户的主组对应的 GID,即admin(参见图 4.30中的gid属性)。 登录时,默认的组会话始终是用户对应的主组。 例如,如果用户要创建一个文件,文件权限属性将反映主组的 ID。 我们将在管理权限一节中更详细地了解文件权限。

现在,我们将当前用户的组会话切换到developers,如下所示:

newgrp developers

当前组会话产生如下结果:

id -g
1200

GID 对应于developers辅助 GID,如图 4.30:1200(developers)中的groups标签所示。 如果用户现在创建了任何文件,那么相关的文件权限属性将具有developersGID。

如果用户试图登录到他们不是其中一员的组(例如,managers),newgrp命令提示输入managers组的密码,如下所示:

newgrp managers

上面的命令提示输入超级用户密码。

如果我们的用户拥有managers组密码,或者如果他们是超级用户,那么组登录尝试将会成功。 否则,用户将被拒绝访问managers组的资源。

我们在此结束管理用户和组的主题。 本节中使用的相关管理任务的示例当然包罗万象。 在这些情况中,有多种方法可以使用不同的命令或方法来实现相同的结果。

到目前为止,您应该相对熟练地管理用户和组,并且熟悉使用各种命令行实用程序来操作相关的更改。 用户和组以关系方式管理,其中用户属于一个组,或者组与用户关联。 我们还了解到创建和管理用户和组需要超级用户特权。 在 Linux 中,用户数据存储在/etc/passwd/etc/shadow文件中,而组信息存储在/etc/group/etc/gshadow文件中。 除了使用专用的命令行实用程序外,还可以通过手动编辑上述文件来修改用户和组。

接下来,我们将转向多用户组环境的安全性和隔离上下文。 在 Linux 中,相关的功能是由系统级访问层完成的,该访问层控制特定用户和组对文件和目录的读、写和执行权限。

下一节将探讨与这些权限相关的管理和管理任务。

权限管理

Linux 的一个关键原则是能够允许多个用户访问系统,同时执行独立的任务。 这个多用户、多任务环境的平稳运行是通过权限控制的。 Linux 内核为底层安全性和隔离模型提供了一个健壮的框架。 在用户级别,专用工具和命令行实用程序帮助 Linux 用户和系统管理员完成相关的权限管理任务。

对于一些 Linux 用户,尤其是初学者,Linux 权限有时可能会令人困惑。 本节试图阐明 Linux 中关于文件和目录权限的一些关键概念。 您将了解访问文件和目录的基本权限权限执行权限。 我们将使用系统级命令行实用程序,探讨一些查看和更改权限的基本管理任务。

本节中讨论的大多数主题应该与用户和组密切相关。 相关习语可以很简单,比如用户可以读取或更新一个文件,一组能够访问这些文件和目录用户可以执行这个计划。

*让我们从基础开始,介绍文件和目录权限。

文件和目录权限

在 Linux 中,权限可以视为对一个文件或目录进行操作的权限权限。 基本权限,或权限属性概述如下:

  • Read-AReadpermissionon a file 允许用户查看文件内容。 在目录上,read 权限允许用户列出目录的内容。
  • Write-AWritepermissionon a file 允许用户修改文件的内容。 对于目录,写权限允许用户通过增加、删除、重命名文件等方式修改目录内容。
  • Execute-Execute可执行权限允许用户运行该文件指定的相关脚本、应用或服务。 对于目录,执行权限允许用户进入该目录并将其设置为当前工作目录(使用cd命令)。

首先,让我们看看如何显示文件和目录的权限。

查看权限

查看文件或目录权限的最常见的方式是使用ls命令行实用程序。 这个命令的基本语法是:

ls [OPTIONS] FILE|DIRECTORY

下面是使用ls命令查看/etc/passwd文件权限的示例:

ls -l /etc/passwd

该命令输出如下:

Figure 4.29 – Viewing the permissions of /etc/passwd file

图 4.29 -查看/etc/passwd 文件的权限

根据ls文档(man ls),ls命令的-l选项使用长列表格式提供详细的输出。

让我们分析一下输出,如下所示:

-rw-r--r-- 1 root 3056 Sep 17 07:57 /etc/passwd

我们有 9 个段,由单个空白字符(分隔符)分隔。 这些是概述在这里:

  • -rw-r--r--:文件访问权限
  • 1:硬链接数
  • root:文件的所有者
  • root:文件所属的组
  • 3056:文件大小
  • Sep:文件创建的月份
  • 17:文件创建的月份
  • 07:57:文件创建的时间
  • /etc/passwd:文件名

让我们检查文件访问权限字段(-rw-r--r--)。 文件访问权限定义为一个 10 个字符的字段,分组如下:

  • 第一个字符(属性)是为文件类型保留的(参见文件类型一节,下一节)。
  • 接下来的九个字符代表一个 9-bit 字段,定义三个属性的有效权限三个序列(比特):用户所有者权限,组所有者权限,和所有其他用户的权限(见【T7 许可属性】部分,下一个)。****

*让我们看一下文件类型。

文件类型

文件类型属性列在这里:

  • d:目录
  • -:普通文件
  • l:符号链接
  • p:命名管道,一种特殊的文件,用于促进程序之间的通信
  • s:一种 socket,类似于管道,但具有双向网络通信
  • b:块设备,即与硬件设备对应的文件
  • c:字符设备,类似于块设备

让我们仔细看看权限属性。

许可属性

如前所述,访问权限由一个 9 位字段表示,该字段由三个序列组成,每个序列有 3 位,定义如下:

  • 位 1-3:用户所有者权限
  • bits 4-6:Group所有者权限
  • bits 7-9:所有其他用户(或world)权限

每个权限属性都是相关三比特序列的二进制表示中的位标志。 它们既可以表示为一个字符,也可以表示为一个等效的数值,也称为八进制值,这取决于它们所代表的位的范围。

下面是权限属性及其各自的八进制值:

  • r:Readpermission; 2 ^ 2 =4(位 2 设置)
  • w:Writepermission: 2 ^ 1 =2(bit 1 set)
  • x:Executepermission: 2 ^ 0 =1(bit 0 set)
  • -:Nopermission:0(No bits set)

最终确认的数字是,也称为文件权限的八进制值(参见文件权限示例节)。 下面是文件权限属性的说明:

Figure 4.30 – The file permission attributes

图 4.30 -文件权限属性

接下来,让我们考虑一些例子。

文件权限的例子

现在,让我们回过头来评估/etc/passwd:-rw-r--r--的文件访问权限,如下所示:

  • -:第一个字符(字节)表示文件类型(在本例中是常规文件)。
  • rw-:接下来的三个字符序列表示用户所有者权限(在本例中为 read(r); 写(w); 八进制值=4(r)+2(w)=6(【显示】))。
  • r--:下一个 3 字节序列定义组所有者权限(在本例中为 read(r); 八进制值=4(r))。
  • r--:最后三个字符表示系统中所有其他用户的权限(在本例中为 read(r); 八进制值=4(r))。

由以上信息可知,/etc/passwd文件访问权限的八进制值为644。 或者,我们可以使用stat命令查询八进制值,如下所示:

stat --format '%a' /etc/passwd

该命令输出如下:

Figure 4.31 – Getting permission attributes using the stat command

图 4.31 -使用 stat 命令获取权限属性

stat命令用来显示文件或文件系统的状态。 选项参数--format以八进制格式('%a')指定输出的访问权限。

下面是一些访问权限的示例,以及它们对应的八进制值和描述。 为了清晰起见,故意用空格分隔三个字符的序列。 前面的文件类型被省略了:

  • rwx(777):读取、写入、执行所有用户,包括所有者、组和世界。
  • rwx r-x(755):对所有用户读取、执行; 文件所有者具有写权限。
  • rwx r-x ---(750):对所有者和组进行读取、执行; 所有者有写权限,而其他人没有访问权限。
  • rwx --- ---(700):对所有者进行读、写、执行; 其他人都没有权限。
  • rw- rw- rw-(666):为所有用户读取、写入; 没有执行权限
  • rw- rw- r--(664):读,写给所有人和组; 为别人阅读。
  • rw- rw- ---(660):读,写给所有人和组; 其他人没有权限。
  • rw- r-- r--(644):读,写; 为小组和其他人阅读。
  • rw- r-- ---(640):读,写; 阅读组; 对其他人没有许可。
  • rw- --- ---(600):读,写; 对组和其他人没有权限。
  • r-- --- ---(400):供业主阅读; 对其他人没有许可。

读、写和执行是最常见的文件访问权限类型。 在某些情况下,特别是在用户模拟情况下,访问权限可能涉及一些特殊的权限属性。 让我们来看看它们。

特殊权限

在 Linux 中,文件和目录的所有权通常由创建它们的用户或组的 UID 和 GID 决定。 同样的原则也适用于应用和进程——它们由启动它们的用户拥有。 特殊权限用于在需要时更改此默认行为。

下面是特殊的权限标志,以及它们各自的八进制值:

  • setuid:2 ^ 2 =4(bit 2 set)
  • setgid:2 ^ 1 =2(位 1 组)
  • sticky:2 ^ 0 =1(位 0 设置)

当设置了这些特殊位的任何一个时,访问权限的总八进制数将有一个额外的数字,前导(高阶)数字对应于特殊的权限的八进制值。

让我们来看看这些特殊的权限标志,并分别提供示例。

setuid 许可

通过设置setuid位,当可执行文件启动时,它将以文件所有者的特权而不是启动它的用户的特权运行。 例如,如果可执行文件归root所有,并由常规用户启动,则它将以root特权运行。 当使用不当或可能利用底层进程的漏洞时,setuid权限可能会带来潜在的安全风险。

在文件访问权限字段中,setuid位可以有以下任一表示:

  • s替换对应的可执行位(x)(当可执行位存在时)
  • S(大写S)表示非可执行文件

setuid权限可以通过以下chmod命令设置(例如,对于myscript可执行文件):

chmod u+s myscript

结果文件权限显示在这里(包括八进制值):-rwsrwxr-x(4775)。 下面是相关的命令行输出:

Figure 4.32 – The setuid permission

图 4.32 - setuid 权限

有关setuid的更多信息,请访问https://en.wikipedia.org/wiki/Setuid或参考chmod命令行实用工具文档(man chmod)。

setgid 许可

虽然setuid控制用户模拟权限,但setgid对组模拟权限具有类似的效果。

位设置为setgid的可执行文件以拥有该文件的组的权限运行,而不是与启动该文件的用户相关联的组。 换句话说,进程的 GID 与文件的 GID 相同。

当在一个目录上使用setgid位时,该位将改变默认的所有权行为,即在目录中创建的文件将拥有父目录的组所有权,而不是与创建它们的用户相关联的组所有权。 当与父目录的所有者组相关联的所有用户都可以更改文件时,这种行为在文件共享的情况下就足够了。

setgid权限可以通过以下chmod命令设置(例如,对于myscript可执行文件):

chmod g+s myscript

结果文件权限显示在这里(包括八进制值):-rwxrwsr-x(2775)。

命令行输出如下所示:

Figure 4.33 – The setgid permission

图 4.33 - setgid 权限

有关setgid的更多信息,请访问https://en.wikipedia.org/wiki/Setuid或参考chmod命令行实用工具文档(man chmod)。

粘性的许可

sticky位对文件没有影响位。 对于具有sticky权限的目录,只有该目录的用户属主或组属主才能删除或重命名该目录下的文件。 对目录具有写访问权限的用户或组,以用户或组的所有权方式,不能删除或修改目录中的文件。 当目录属于特权组,其成员共享对该目录中的文件的写访问权限时,sticky权限非常有用。

sticky权限可以通过以下chmod命令设置(例如,对于mydir目录):

chmod +t mydir

得到的目录权限显示在这里(包括八进制值):drwxrwxr-t(1775)。 命令行输出如下所示:

Figure 4.34 – The sticky permission

图 4.34 - sticky 权限

有关sticky的更多信息,请访问https://en.wikipedia.org/wiki/Setuid或参考chmod命令行实用工具文档(man chmod)。

到目前为止,我们主要关注权限类型及其表示。 在下一节中,我们将探讨用于更改权限的几个命令行工具。

改变权限

修改文件和目录的访问权限是 Linux 系统中常见的管理任务。 在本节中,我们将了解一些命令行实用程序,这些实用程序在更改文件和目录的权限和所有权时非常方便。 这些工具安装在任何现代 Linux 发行版中,它们在大多数 Linux 平台上的使用都是类似的。

使用 chmod

chmod命令是更改模式的缩写,用于设置文件和目录的访问权限。 chmod命令既可以由当前用户(所有者)使用,也可以由超级用户使用。

可以通过两种不同的模式来更改权限:相对模式和绝对模式。 让我们来看看每一个。

以相对模式使用 chmod

在相对模式中更改权限可能是中最容易的。 重要的是要记住以下几点:

  • 对于我们更改权限的用户:u=用户(所有者),g=组,o=其他人
  • 如何更改权限:+=添加,-=删除,==完全相同
  • 更改权限:r= read,w= write,x= execute

让我们来看看在相对模式下使用chmod的几个例子。

在第一个示例中,我们想为所有其他(o)用户(世界)添加写入(w)权限到myfile,如下所示:

chmod o+w myfile

相关的命令行输出如下所示:

Figure 4.35 – Setting write permissions to all other users

图 4.35 -设置所有其他用户的写权限

在下一个示例中,我们删除myfile的当前用户所有者(u)的读(r)和写(w)权限,如下:

chmod u-rw myufile

命令行输出如下所示:

Figure 4.36 – Removing read-write permissions for owner

图 4.36 -删除所有者的读写权限

我们在前面的两个示例中都没有使用sudo,因为我们是以文件的当前所有者(packt)的身份执行操作的。

在下面的示例中,我们假设myfile对每个人都具有读、写和执行权限。 然后,我们进行以下更改:

  • 删除所有者(u)的读(r)权限。
  • 删除所有者(u)和组(g)的写权限(w)。
  • 删除所有其他人(o)的读(r)、写(w)和执行(x)权限。

下面的代码片段说明了这一点:

chmod u-r,ug-w,o-rwx myfile

命令行输出如下所示:

Figure 4.37 – A relatively complex invocation of chmod in relative mode

图 4.37 -相对模式下 chmod 的相对复杂调用

接下来,让我们看看更改权限的第二种方法:在absolute模式下使用chmod命令行实用程序,通过指定与访问权限对应的八进制数。

使用 chmod 的绝对模式

chmodabsolute模式调用使用八进制数一次更改所有权限属性。 此方法的绝对指定是由于更改权限而没有对现有权限的任何引用,只需简单地分配与访问权限对应的八进制值。

下面是有效权限对应的八进制值的快速列表:

  • 7``rwx:读、写、执行
  • 6``rw-:读,写
  • 5``r-w:读,执行
  • 4``r--:读
  • 3``-wx:写,执行
  • 2``-w-:写
  • 1``--x:执行
  • 0``---:无权限

在下面的示例中,我们将myfile的权限更改为对所有人的读(r)、写(w)和执行(x)权限:

chmod 777 myfile

相关的更改通过以下命令行输出说明:

Figure 4.38 – The chmod invocation in absolute mode

图 4.38 -绝对模式下的 chmod 调用

有关chmod命令的更多信息,请参考相关文档(man chmod)。

现在让我们看看下一个命令行实用程序,它专门用于更改文件和目录的所有权。

使用乔恩

chown命令用于设置文件和目录的所有权。 通常,chmod命令只能使用超级用户特权(即通过sudoer)运行。 普通用户只能更改其文件的所有权,且仅当他们是目标组的成员时。

下面显示了chown命令的语法:

chown [OPTIONS] [OWNER][:[GROUP]] FILE

通常,我们使用用户组所有权调用chown命令—例如,如下所示:

sudo chown julian:developers myfile

相关的命令行输出如下所示:

Figure 4.39 – A simple invocation of the chown command

图 4.39 - chown 命令的简单调用

chown最常见的用途之一是通过-R, --recursive选项用于递归模式调用。 下面的示例将mydir(目录)中最初属于 root 的所有文件的所有权权限更改为julian:

sudo chown -R julian:julian mydir/

相关修改如下所示:

Figure 4.40 – Invoking ls and chown in recursive mode

图 4.40 -以递归模式调用 ls 和 chown

有关chown命令的更多信息,请参考相关文档(man chown)。

接下来,让我们简要地看一下一个类似的命令行实用程序,它专门用于更改组所有权。

使用 chgrp

chgrp命令用于更改文件和目录的的所有权。 在 Linux 中,文件和目录通常属于一个用户(所有者)或一个组。 我们可以使用chown命令行实用程序设置用户所有权,而可以使用chgrp设置组所有权。

chgrp的语法如下:

chgrp [OPTIONS] GROUP FILE

下面的示例将myfile的组所有权更改为developers组:

sudo chgrp developers myfile

这些变化如下所示:

Figure 4.41 – Using chgrp to change group ownership

图 4.41 -使用 chgrp 更改组所有权

由于当前用户(packt)不是developers组的管理员,所以使用超级用户权限(sudo)调用了前面的命令。

有关chgrp实用程序的更多信息,请参考该工具的命令行帮助(chgrp --help)。

使用 umask

umask命令用于查看或设置系统默认的文件模式掩码。 文件模式表示用户创建的任何新文件和目录的默认权限。 例如,Ubuntu 中的默认文件模式掩码如下:

  • 0002为普通用户
  • 0022root用户

作为 Linux 中的一般规则,新文件和目录的默认权限用以下公式计算:

  • 0666 – umask:普通用户创建的新文件
  • 0777 – umask:普通用户创建的新目录

根据前面的公式,在 Ubuntu 上我们有以下默认权限:

  • 文件(普通用户):0666 – 0002 = 0664
  • 目录(普通用户):0777 – 0002 = 0775
  • 文件(root):0666 – 0022 = 0644
  • 目录(root):0777 – 0022 = 0755

在下面的例子中,运行在 Ubuntu 上,我们使用一个普通用户(packt)的终端会话创建一个文件(myfile)和一个目录(mydir)。 然后,我们查询每个和的stat命令,验证默认权限与前面为普通用户(文件:664,目录:775)枚举的值匹配。

让我们先从默认文件权限开始,如下所示:

touch myfile
stat --format '%a' myfile

相关输出如下所示:

Figure 4.42 – The default file permissions for regular user (664)

图 4.42 -普通用户的默认文件权限(664)

接下来,让我们验证默认目录权限,如下所示:

mkdir mydir
stat --format '%a' mydir

相关输出如下所示:

Figure 4.43 – The default directory permissions for regular user (775)

图 4.43 -普通用户的默认目录权限(775)

下面是 Linux 系统上最典型的umask值列表:

Figure 4.44 – Typical umask values on Linux

图 4.44 - Linux 上典型的 umask 值

有关umask实用程序的更多信息,请参考该工具的命令行帮助(umask --help)。

文件和目录权限对于安全环境至关重要。 用户和进程应该完全在由权限控制的隔离和安全约束范围内操作,以避免无意或故意干扰系统资源的使用和所有权。

解释权限可能是一项艰巨的任务。 本节的目的是澄清一些相关的复杂之处,我们希望您在日常 Linux 管理任务中处理文件和目录权限时会感到更舒服。

总结

在本章中,我们探讨了 Linux 中与管理用户和组相关的一些基本概念。 我们了解了文件和目录权限以及多用户环境的不同访问级别。 对于每个主要主题,我们关注基本的管理任务,提供各种实际示例,并使用典型的命令行工具进行日常的用户访问和权限管理操作。

管理用户和组以及相关的文件系统权限是 Linux 管理员不可或缺的技能。 我们希望,在本章中获得的知识将使你走上成为一个熟练的超级用户的轨道。

在下一章中,我们将通过探索进程、守护进程和进程间通信机制,继续我们掌握 Linux 内部机制的旅程。 需要记住的一个重要方面是,进程和守护进程也由用户或组拥有。 在本章中学习的技能将帮助我们在研究系统中任何给定时间的谁运行什么时导航相关领域。

问题

以下是总结本章主要内容的一些想法和问题:

  1. Linux 是一个多用户和多任务操作系统。 权限提供了相关的隔离和安全上下文,以保护用户资源免受无意访问。
  2. 什么是超级用户?
  3. 考虑一个用于创建用户的命令行实用程序。 你能想到另外一个吗?
  4. -rw-rw-r—访问权限的八进制值是多少?
  5. 主要群体和次要(补充)群体有什么区别?
  6. 如何更改用户的主目录的所有权?
  7. 可以在不删除主目录的情况下将用户从系统中删除吗? 如何?*******