标签 用户组 下的文章

在 Linux 系统中管理用户组并不费力,但相关命令可能比你所知的更为灵活。

Scott 97006 (CC BY 2.0)

在 Linux 系统中用户组起着重要作用。用户组提供了一种简单方法供一组用户互相共享文件。用户组也允许系统管理员更加有效地管理用户权限,因为管理员可以将权限分配给用户组而不是逐一分配给单个用户。

尽管通常只要在系统中添加用户账户就会创建用户组,关于用户组如何工作以及如何运用用户组还有很多需要了解的。

一个用户一个用户组?

Linux 系统中多数用户账户被设为用户名与用户组名相同。用户 jdoe 会被赋予一个名为 jdoe 的用户组,且成为该新建用户组的唯一成员。如本例所示,该用户的登录名,用户 id 和用户组 id 在新建账户时会被添加到 /etc/passwd 和 /etc/group 文件中:

$ sudo useradd jdoe
$ grep jdoe /etc/passwd
jdoe:x:1066:1066:Jane Doe:/home/jdoe:/bin/sh
$ grep jdoe /etc/group
jdoe:x:1066:

这些文件中的配置使系统得以在文本(jdoe)和数字(1066)这两种用户 id 形式之间互相转换—— jdoe 就是 1006,且 1006 就是 jdoe。

分配给每个用户的 UID(用户 id)和 GID(用户组 id)通常是一样的,并且顺序递增。若上例中 Jane Doe 是最近添加的用户,分配给下一个新用户的用户 id 和用户组 id 很可能都是 1067。

GID = UID?

UID 和 GID 可能不一致。例如,如果你用 groupadd 命令添加一个用户组而不指定用户组 id,系统会分配下一个可用的用户组 id(在本例中为 1067)。下一个添加到系统中的用户其 UID 会是 1067 而 GID 则为 1068。

你可以避免这个问题,方法是添加用户组的时候指定一个较小的用户组 id 而不是接受默认值。在下面的命令中我们添加一个用户组并提供一个 GID,这个 GID 小于用于用户账户的 GID 取值范围。

$ sudo groupadd -g 500 devops

创建账户时你可以指定一个共享用户组,如果这样对你更合适的话。例如你可能想把新来的开发人员加入同一个 DevOps 用户组而不是一人一个用户组。

$ sudo useradd -g staff bennyg
$ grep bennyg /etc/passwd
bennyg:x:1064:50::/home/bennyg:/bin/sh

主要用户组和次要用户组

用户组实际上有两种: 主要用户组 primary group 和 次要用户组 secondary group 。

主要用户组是保存在 /etc/passwd 文件中的用户组,该用户组在账户创建时配置。当用户创建一个文件时,用户的主要用户组与此文件关联。

$ whoami
jdoe
$ grep jdoe /etc/passwd
jdoe:x:1066:1066:John Doe:/home/jdoe:/bin/bash
             ^
             |
             +-------- 主要用户组
$ touch newfile
$ ls -l newfile
-rw-rw-r-- 1 jdoe jdoe 0 Jul 16 15:22 newfile
                   ^
                   |
                   +-------- 主要用户组

用户一旦拥有账户之后被加入的那些用户组是次要用户组。次要用户组成员关系在 /etc/group 文件中显示。

$ grep devops /etc/group
devops:x:500:shs,jadep
          ^
          |
          +-------- shs 和 jadep 的次要用户组

/etc/group 文件给用户组分配组名称(例如 500 = devops)并记录次要用户组成员。

首选的准则

每个用户是他自己的主要用户组成员,并可以成为任意多个次要用户组成员,这样的一种准则允许用户更加容易地将个人文件和需要与同事分享的文件分开。当用户创建一个文件时,用户所属的不同用户组的成员不一定有访问权限。用户必须用 chgrp 命令将文件和次要用户组关联起来。

哪里也不如自己的家目录

添加新账户时一个重要的细节是 useradd 命令并不一定为新用户添加一个 家目录 /home 家目录。若你只有某些时候想为用户添加家目录,你可以在 useradd 命令中加入 -m 选项(可以把它想象成“安家”选项)。

$ sudo useradd -m -g devops -c "John Doe" jdoe2

此命令中的选项如下:

  • -m 创建家目录并在其中生成初始文件
  • -g 指定用户归属的用户组
  • -c 添加账户描述信息(通常是用户的姓名)

若你希望总是创建家目录,你可以编辑 /etc/login.defs 文件来更改默认工作方式。更改或添加 CREATE_HOME 变量并将其设置为 yes:

$ grep CREATE_HOME /etc/login.defs
CREATE_HOME     yes

另一种方法是用自己的账户设置别名从而让 useradd 一直带有 -m 选项。

$ alias useradd=’useradd -m’

确保将该别名添加到你的 ~/.bashrc 文件或类似的启动文件中以使其永久生效。

深入了解 /etc/login.defs

下面这个命令可列出 /etc/login.defs 文件中的全部设置。下面的 grep 命令会隐藏所有注释和空行。

$ cat /etc/login.defs | grep -v "^#" | grep -v "^$"
MAIL_DIR        /var/mail
FAILLOG_ENAB            yes
LOG_UNKFAIL_ENAB        no
LOG_OK_LOGINS           no
SYSLOG_SU_ENAB          yes
SYSLOG_SG_ENAB          yes
FTMP_FILE       /var/log/btmp
SU_NAME         su
HUSHLOGIN_FILE  .hushlogin
ENV_SUPATH      PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV_PATH        PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
TTYGROUP        tty
TTYPERM         0600
ERASECHAR       0177
KILLCHAR        025
UMASK           022
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_WARN_AGE   7
UID_MIN                  1000
UID_MAX                 60000
GID_MIN                  1000
GID_MAX                 60000
LOGIN_RETRIES           5
LOGIN_TIMEOUT           60
CHFN_RESTRICT           rwh
DEFAULT_HOME    yes
CREATE_HOME         yes                 <===
USERGROUPS_ENAB yes
ENCRYPT_METHOD SHA512

注意此文件中的各种设置会决定用户 id 的取值范围以及密码使用期限和其他设置(如 umask)。

如何显示用户所属的用户组

出于各种原因用户可能是多个用户组的成员。用户组成员身份给与用户对用户组拥有的文件和目录的访问权限,有时候这种工作方式是至关重要的。要生成某个用户所属用户组的清单,用 groups 命令即可。

$ groups jdoe
jdoe : jdoe adm admin cdrom sudo dip plugdev lpadmin staff sambashare

你可以键入不带任何参数的 groups 命令来列出你自己的用户组。

如何添加用户至用户组

如果你想添加一个已有用户至别的用户组,你可以仿照下面的命令操作:

$ sudo usermod -a -G devops jdoe

你也可以指定逗号分隔的用户组列表来添加一个用户至多个用户组:

$ sudo usermod -a -G devops,mgrs jdoe

参数 -a 意思是“添加”,-G 指定用户组列表。

你可以编辑 /etc/group 文件将用户名从用户组成员名单中删除,从而将用户从用户组中移除。usermod 命令或许也有个选项用于从用户组中删除某个成员。

fish:x:16:nemo,dory,shark
           |
           V
fish:x:16:nemo,dory

提要

添加和管理用户组并非特别困难,但长远来看配置账户时的一致性可使这项工作更容易些。


via: https://www.networkworld.com/article/3409781/mastering-user-groups-on-linux.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:0x996 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Linux 组是用于管理 Linux 中用户帐户的组织单位。对于 Linux 系统中的每一个用户和组,它都有惟一的数字标识号。它被称为 用户 ID(UID)和组 ID(GID)。组的主要目的是为组的成员定义一组特权。它们都可以执行特定的操作,但不能执行其他操作。

Linux 中有两种类型的默认组。每个用户应该只有一个 主要组 primary group 和任意数量的 次要组 secondary group 。

  • 主要组: 创建用户帐户时,已将主要组添加到用户。它通常是用户的名称。在执行诸如创建新文件(或目录)、修改文件或执行命令等任何操作时,主要组将应用于用户。用户的主要组信息存储在 /etc/passwd 文件中。
  • 次要组: 它被称为次要组。它允许用户组在同一组成员文件中执行特定操作。例如,如果你希望允许少数用户运行 Apache(httpd)服务命令,那么它将非常适合。

你可能对以下与用户管理相关的文章感兴趣。

可以使用以下四种方法实现。

  • usermod:修改系统帐户文件,以反映在命令行中指定的更改。
  • gpasswd:用于管理 /etc/group 和 /etc/gshadow。每个组都可以有管理员、成员和密码。
  • Shell 脚本:可以让管理员自动执行所需的任务。
  • 手动方式:我们可以通过编辑 /etc/group 文件手动将用户添加到任何组中。

我假设你已经拥有此操作所需的组和用户。在本例中,我们将使用以下用户和组:user1、user2、user3,另外的组是 mygroup 和 mygroup1。

在进行更改之前,我希望检查一下用户和组信息。详见下文。

我可以看到下面的用户与他们自己的组关联,而不是与其他组关联。

# id user1
uid=1008(user1) gid=1008(user1) groups=1008(user1)

# id user2
uid=1009(user2) gid=1009(user2) groups=1009(user2)

# id user3
uid=1010(user3) gid=1010(user3) groups=1010(user3)

我可以看到这个组中没有关联的用户。

# getent group mygroup
mygroup:x:1012:

# getent group mygroup1
mygroup1:x:1013:

方法 1:使用 usermod 命令

usermod 命令修改系统帐户文件,以反映命令行上指定的更改。

如何使用 usermod 命令将现有的用户添加到次要组或附加组?

要将现有用户添加到辅助组,请使用带有 -G 选项和组名称的 usermod 命令。

语法:

# usermod [-G] [GroupName] [UserName]

如果系统中不存在给定的用户或组,你将收到一条错误消息。如果没有得到任何错误,那么用户已经被添加到相应的组中。

# usermod -a -G mygroup user1

让我使用 id 命令查看输出。是的,添加成功。

# id user1
uid=1008(user1) gid=1008(user1) groups=1008(user1),1012(mygroup)

如何使用 usermod 命令将现有的用户添加到多个次要组或附加组?

要将现有用户添加到多个次要组中,请使用带有 -G 选项的 usermod 命令和带有逗号分隔的组名称。

语法:

# usermod [-G] [GroupName1,GroupName2] [UserName]

在本例中,我们将把 user2 添加到 mygroup 和 mygroup1 中。

# usermod -a -G mygroup,mygroup1 user2

让我使用 id 命令查看输出。是的,user2 已成功添加到 myGroup 和 myGroup1 中。

# id user2
uid=1009(user2) gid=1009(user2) groups=1009(user2),1012(mygroup),1013(mygroup1)

如何改变用户的主要组?

要更改用户的主要组,请使用带有 -g 选项和组名称的 usermod 命令。

语法:

# usermod [-g] [GroupName] [UserName]

我们必须使用 -g 改变用户的主要组。

# usermod -g mygroup user3

让我们看看输出。是的,已成功更改。现在,显示user3 主要组是 mygroup 而不是 user3。

# id user3
uid=1010(user3) gid=1012(mygroup) groups=1012(mygroup)

方法 2:使用 gpasswd 命令

gpasswd 命令用于管理 /etc/group 和 /etc/gshadow。每个组都可以有管理员、成员和密码。

如何使用 gpasswd 命令将现有用户添加到次要组或者附加组?

要将现有用户添加到次要组,请使用带有 -M 选项和组名称的 gpasswd 命令。

语法:

# gpasswd [-M] [UserName] [GroupName]

在本例中,我们将把 user1 添加到 mygroup 中。

# gpasswd -M user1 mygroup

让我使用 id 命令查看输出。是的,user1 已成功添加到 mygroup 中。

# id  user1
uid=1008(user1) gid=1008(user1) groups=1008(user1),1012(mygroup)

如何使用 gpasswd 命令添加多个用户到次要组或附加组中?

要将多个用户添加到辅助组中,请使用带有 -M 选项和组名称的 gpasswd 命令。

语法:

# gpasswd [-M] [UserName1,UserName2] [GroupName]

在本例中,我们将把 user2 和 user3 添加到 mygroup1 中。

# gpasswd -M user2,user3 mygroup1

让我使用 getent 命令查看输出。是的,user2 和 user3 已成功添加到 myGroup1 中。

# getent group mygroup1
mygroup1:x:1013:user2,user3

如何使用 gpasswd 命令从组中删除一个用户?

要从组中删除用户,请使用带有 -d 选项的 gpasswd 命令以及用户和组的名称。

语法:

# gpasswd [-d] [UserName] [GroupName]

在本例中,我们将从 mygroup 中删除 user1 。

# gpasswd -d user1 mygroup
Removing user user1 from group mygroup

方法 3:使用 Shell 脚本

基于上面的例子,我知道 usermod 命令没有能力将多个用户添加到组中,可以通过 gpasswd 命令完成。但是,它将覆盖当前与组关联的现有用户。

例如,user1 已经与 mygroup 关联。如果要使用 gpasswd 命令将 user2 和 user3 添加到 mygroup 中,它将不会按预期生效,而是对组进行修改。

如果要将多个用户添加到多个组中,解决方案是什么?

两个命令中都没有默认选项来实现这一点。

因此,我们需要编写一个小的 shell 脚本来实现这一点。

如何使用 gpasswd 命令将多个用户添加到次要组或附加组?

如果要使用 gpasswd 命令将多个用户添加到次要组或附加组,请创建以下 shell 脚本。

创建用户列表。每个用户应该在单独的行中。

$ cat user-lists.txt
user1
user2
user3

使用以下 shell 脚本将多个用户添加到单个次要组。

vi group-update.sh

#!/bin/bash
for user in `cat user-lists.txt`
do
usermod -a -G mygroup $user
done

设置 group-update.sh 文件的可执行权限。

# chmod + group-update.sh

最后运行脚本来实现它。

# sh group-update.sh

让我看看使用 getent 命令的输出。 是的,user1、user2 和 user3 已成功添加到 mygroup 中。

# getent group mygroup
mygroup:x:1012:user1,user2,user3

如何使用 gpasswd 命令将多个用户添加到多个次要组或附加组?

如果要使用 gpasswd 命令将多个用户添加到多个次要组或附加组中,请创建以下 shell 脚本。

创建用户列表。每个用户应该在单独的行中。

$ cat user-lists.txt
user1
user2
user3

创建组列表。每组应在单独的行中。

$ cat group-lists.txt
mygroup
mygroup1

使用以下 shell 脚本将多个用户添加到多个次要组。

#!/bin/sh
for user in `more user-lists.txt`
do
for group in `more group-lists.txt`
do
usermod -a -G $group $user
done

设置 group-update-1.sh 文件的可执行权限。

# chmod +x group-update-1.sh

最后运行脚本来实现它。

# sh group-update-1.sh

让我看看使用 getent 命令的输出。 是的,user1、user2 和 user3 已成功添加到 mygroup 中。

# getent group mygroup
mygroup:x:1012:user1,user2,user3

此外,user1、user2 和 user3 已成功添加到 mygroup1 中。

# getent group mygroup1
mygroup1:x:1013:user1,user2,user3

方法 4:在 Linux 中将用户添加到组中的手动方法

我们可以通过编辑 /etc/group 文件手动将用户添加到任何组中。

打开 /etc/group 文件并搜索要更新用户的组名。最后将用户更新到相应的组中。

# vi /etc/group

via: https://www.2daygeek.com/linux-add-user-to-group-primary-secondary-group-usermod-gpasswd/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:NeverKnowsTomorrow 校对:wxy

本文由 LCTT 原创编译,Linux 中国 荣誉推出

我们继续创建和管理用户和组的 Linux 教程之旅。

在正在进行的 Linux 之旅中,我们了解了如何操作文件夹或目录,现在我们继续讨论 权限、用户 和 组,这对于确定谁可以操作哪些文件和目录是必要的。上次,我们展示了如何创建新用户,现在我们将重新起航:

你可以使用 groupadd 命令创建新组,然后随意添加用户。例如,使用:

sudo groupadd photos

这将会创建 photos 组。

你需要在根目录下创建一个目录:

sudo mkdir /photos

如果你运行 ls -l /,结果中会有如下这一行:

drwxr-xr-x 1 root root 0 jun 26 21:14 photos

输出中的第一个 root 是所属的用户,第二个 root 是所属的组。

要将 /photos 目录的所有权转移到 photos 组,使用:

chgrp photos /photos

chgrp 命令通常采用两个参数,第一个参数是将要获得文件或目录所有权的组,第二个参数是希望交给组的文件或目录。

接着,运行 ls -l /,你会发现刚才那一行变了:

drwxr-xr-x 1 root photos 0 jun 26 21:14 photos

你已成功将新目录的所有权转移到了 photos 组。

然后,将你自己的用户和 guest 用户添加到 photos 组:

sudo usermod <你的用户名> -a -G photos
sudo usermod guest -a -G photos

你可能必须注销并重新登录才能看到更改,但是当你这样做时,运行 groups 会将 photos 显示为你所属的组之一。

关于上面提到的 usermod 命令,需要指明几点。第一:注意要使用 -G 选项而不是 -g 选项。-g 选项更改你的主要组,如果你意外地使用它,它可能会锁定你的一些东西。另一方面,-G 将你添加到列出的组中,并没有干扰主要组。如果要将用户添加到多个组中,在 -G 之后逐个列出它们,用逗号分隔,不要有空格:

sudo usermod <your username> -a -G photos,pizza,spaceforce

第二点:小心点不要忘记 -a 参数。-a 参数代表追加,将你传递给 -G 的组列表附加到你已经属于的组。这意味着,如果你不包含 -a,那么你之前所属的组列表将被覆盖,再次将你拒之门外。

这些都不是灾难性问题,但这意味着你必须手动将用户添加回你所属的所有组,这可能是个麻烦,特别是如果你失去了对 sudo 和 wheel 组的访问权限。

权限

在将图像复制到 /photos 目录之前,还要做一件事情。注意,当你执行上面的 ls -l / 时,该文件夹的权限将以 drwxr-xr-x 形式返回。

如果你阅读我在本文开头推荐的文章,你将知道第一个 d 表示文件系统中的条目是一个目录,接着你有三组三个字符(rwx、r-x、r-x),它们表示目录的所属用户(rwx)的权限,然后是所属组(r-x)的权限,最后是其他用户(r-x)的权限。这意味着到目前为止唯一具有写权限的人,即能够在 /photos 目录中复制或创建文件的唯一人员是 root 用户。

但是我提到的那篇文章也告诉你如何更改目录或文件的权限:

sudo chmod g+w /photos

运行 ls -l /,你会看到 /photos 权限变为了 drwxrwxr-x。这就是你希望的:组成员现在可以对目录进行写操作了。

现在你可以尝试将图像或任何其他文件复制到目录中,它应该没有问题:

cp image.jpg /photos

guest 用户也可以从目录中读取和写入。他们也可以读取和写入,甚至移动或删除共享目录中其他用户创建的文件。

总结

Linux 中的权限和特权系统已经磨练了几十年,它继承自昔日的旧 Unix 系统。就其本身而言,它工作的非常好,而且经过了深思熟虑。熟悉它对于任何 Linux 系统管理员都是必不可少的。事实上,除非你理解它,否则你根本就无法做很多事情。但是,这并不难。

下一次,我们将深入研究文件,并以一个创新的方式查看创建,操作和销毁文件的不同方法。最后一个总是很有趣。

回头见!

通过 Linux 基金会和 edX 的免费“Linux 简介”课程了解有关 Linux 的更多信息。


via: https://www.linux.com/blog/learn/intro-to-linux/2018/7/users-groups-and-other-linux-beasts-part-2

作者:Paul Brown 选题:lujun9972 译者:MjSeven 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Linux 和其他类 Unix 操作系统依赖于用户组,而不是逐个为用户分配权限和特权。一个组就是你想象的那样:一群在某种程度上相关的用户。

到这个阶段,在看到如何操作目录或文件夹之后,但在让自己一头扎进文件之前,我们必须重新审视 权限、用户 和 组。幸运的是,有一个网站上已经有了一个优秀而全面的教程,讲到了权限,所以你应该去立刻阅读它。简而言之,你使用权限来确定谁可以对文件和目录执行操作,以及他们可以对每个文件和目录执行什么操作 —— 从中读取、写入、移动、擦除等等。

要尝试本教程涵盖的所有内容,你需要在系统上创建新用户。让我们实践起来,为每一个需要借用你电脑的人创建一个用户,我们称之为 guest 账户。

警告: 例如,如果你错误地删除了自己的用户和目录,那么创建用户,特别是删除用户以及主目录会严重损坏系统。你可能不想在你日常的工作机中练习,那么请在另一台机器或者虚拟机上练习。无论你是否想要安全地练习,经常备份你的东西总是一个好主意。检查备份是否正常工作,为你自己以后避免很多咬牙切齿的事情。

一个新用户

你可以使用 useradd 命令来创建一个新用户。使用超级用户或 root 权限运行 useradd,即使用 sudo 或 su,这具体取决于你的系统,你可以:

sudo useradd -m guest

然后输入你的密码。或者也可以这样:

su -c "useradd -m guest"

然后输入 root 或超级用户的密码。

( 为了简洁起见,我们将从现在开始假设你使用 sudo 获得超级用户或 root 权限。 )

通过使用 -m 参数,useradd 将为新用户创建一个主目录。你可以通过列出 /home/guest 来查看其内容。

然后你可以使用以下命令来为新用户设置密码:

sudo passwd guest

或者你也可以使用 adduser,这是一个交互式的命令,它会询问你一些问题,包括你要为用户分配的 shell(是的,shell 有不止一种),你希望其主目录在哪里,你希望他们属于哪些组(有关这点稍后会讲到)等等。在运行 adduser 结束时,你可以设置密码。注意,默认情况下,在许多发行版中都没有安装 adduser,但安装了 useradd。

顺便说一下,你可以使用 userdel 来移除一个用户:

sudo userdel -r guest

使用 -r 选项,userdel 不仅删除了 guest 用户,还删除了他们的主目录和邮件中的条目(如果有的话)。

主目录中的内容

谈到用户的主目录,它依赖于你所使用的发行版。你可能已经注意到,当你使用 -m 选项时,useradd 使用子目录填充用户的目录,包括音乐、文档和诸如此类的内容以及各种各样的隐藏文件。要查看 guest 主目录中的所有内容,运行 sudo ls -la /home/guest。

进入新用户目录的内容通常是由 /etc/skel 架构目录确定的。有时它可能是一个不同的目录。要检查正在使用的目录,运行:

useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

这会给你一些额外的有趣信息,但你现在感兴趣的是 SKEL=/etc/skel 这一行,在这种情况下,按照惯例,它指向 /etc/skel/。

由于 Linux 中的所有东西都是可定制的,因此你可以更改那些放入新创建的用户目录的内容。试试这样做:在 /etc/skel/ 中创建一个新目录:

sudo mkdir /etc/skel/Documents

然后创建一个包含欢迎消息的文件,并将其复制过来:

sudo cp welcome.txt /etc/skel/Documents

现在删除 guest 账户:

sudo userdel -r guest

再次创建:

sudo useradd -m guest

嘿!你的 Documents/ 目录和 welcome.txt 文件神奇地出现在了 guest 的主目录中。

你还可以在创建用户时通过编辑 /etc/default/useradd 来修改其他内容。我的看起来像这样:

GROUP=users
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

这些选项大多数都是不言自明的,但让我们仔细看看 GROUP 选项。

群组心态

Linux 和其他类 Unix 操作系统依赖于用户组,而不是逐个为用户分配权限和特权。一个组就是你想象的那样:一群在某种程度上相关的用户。在你的系统上可能有一组允许使用打印机的用户,他们属于 lp(即 “line printer”)组。传统上 wheel 组的成员是唯一可以通过使用 su 成为超级用户或 root 的成员。network 用户组可以启动或关闭网络。还有许多诸如此类的。

不同的发行版有不同的组,具有相同或相似名称的组具有不同的权限,这也取决于你使用的发行版。因此,如果你在前一段中读到的内容与你系统中的内容不匹配,不要感到惊讶。

不管怎样,要查看系统中有哪些组,你可以使用:

getent group

getent 命令列出了某些系统数据库的内容。

要查找当前用户所属的组,尝试:

groups

当你使用 useradd 创建新用户时,除非你另行指定,否则用户将只属于一个组:他们自己。guest 用户属于 guest 组。组使用户有权管理自己的东西,仅此而已。

你可以使用 groupadd 命令创建新组,然后添加用户:

sudo groupadd photos

例如,这将创建 photos 组。下一次,我们将使用它来构建一个共享目录,该组的所有成员都可以读取和写入,我们将更多地了解权限和特权。敬请关注!


via: https://www.linux.com/learn/intro-to-linux/2018/7/users-groups-and-other-linux-beasts

作者:Paul Brown 选题:lujun9972 译者:MjSeven 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

嗨!就在上周,我还自认为对 Linux 上的用户和组的工作机制了如指掌。我认为它们的关系是这样的:

  1. 每个进程都属于一个用户(比如用户 julia)
  2. 当这个进程试图读取一个被某个组所拥有的文件时, Linux 会 a. 先检查用户julia 是否有权限访问文件。(LCTT 译注:此处应该是指检查文件的所有者是否就是 julia) b. 检查 julia 属于哪些组,并进一步检查在这些组里是否有某个组拥有这个文件或者有权限访问这个文件。
  3. 如果上述 a、b 任一为真(或者“其它”位设为有权限访问),那么这个进程就有权限访问这个文件。

比如说,如果一个进程被用户 julia 拥有并且 julia 在awesome 组,那么这个进程就能访问下面这个文件。

r--r--r-- 1 root awesome     6872 Sep 24 11:09 file.txt

然而上述的机制我并没有考虑得非常清楚,如果你硬要我阐述清楚,我会说进程可能会在运行时去检查 /etc/group 文件里是否有某些组拥有当前的用户。

然而这并不是 Linux 里“组”的工作机制

我在上个星期的工作中发现了一件有趣的事,事实证明我前面的理解错了,我对组的工作机制的描述并不准确。特别是 Linux 并不会在进程每次试图访问一个文件时就去检查这个进程的用户属于哪些组。

我在读了《Linux 编程接口》这本书的第九章(“进程资格”)后才恍然大悟(这本书真是太棒了),这才是组真正的工作方式!我意识到之前我并没有真正理解用户和组是怎么工作的,我信心满满的尝试了下面的内容并且验证到底发生了什么,事实证明现在我的理解才是对的。

用户和组权限检查是怎么完成的

现在这些关键的知识在我看来非常简单! 这本书的第九章上来就告诉我如下事实:用户和组 ID 是进程的属性,它们是:

  • 真实用户 ID 和组 ID;
  • 有效用户 ID 和组 ID;
  • 保存的 set-user-ID 和保存的 set-group-ID;
  • 文件系统用户 ID 和组 ID(特定于 Linux);
  • 补充的组 ID;

这说明 Linux 实际上检查一个进程能否访问一个文件所做的组检查是这样的:

  • 检查一个进程的组 ID 和补充组 ID(这些 ID 就在进程的属性里,并不是实时在 /etc/group 里查找这些 ID)
  • 检查要访问的文件的访问属性里的组设置
  • 确定进程对文件是否有权限访问(LCTT 译注:即文件的组是否是以上的组之一)

通常当访问控制的时候使用的是有效用户/组 ID,而不是真实用户/组 ID。技术上来说当访问一个文件时使用的是文件系统的 ID,它们通常和有效用户/组 ID 一样。(LCTT 译注:这句话针对 Linux 而言。)

将一个用户加入一个组并不会将一个已存在的进程(的用户)加入那个组

下面是一个有趣的例子:如果我创建了一个新的组:panda 组并且将我自己(bork)加入到这个组,然后运行 groups 来检查我是否在这个组里:结果是我(bork)竟然不在这个组?!

bork@kiwi~> sudo addgroup panda
Adding group `panda' (GID 1001) ...
Done.
bork@kiwi~> sudo adduser bork panda
Adding user `bork' to group `panda' ...
Adding user bork to group panda
Done.
bork@kiwi~> groups
bork adm cdrom sudo dip plugdev lpadmin sambashare docker lxd

panda 并不在上面的组里!为了再次确定我们的发现,让我们建一个文件,这个文件被 panda 组拥有,看看我能否访问它。

$  touch panda-file.txt
$  sudo chown root:panda panda-file.txt
$  sudo chmod 660 panda-file.txt
$  cat panda-file.txt
cat: panda-file.txt: Permission denied

好吧,确定了,我(bork)无法访问 panda-file.txt。这一点都不让人吃惊,我的命令解释器并没有将 panda 组作为补充组 ID,运行 adduser bork panda 并不会改变这一点。

那进程一开始是怎么得到用户的组的呢?

这真是个非常令人困惑的问题,对吗?如果进程会将组的信息预置到进程的属性里面,进程在初始化的时候怎么取到组的呢?很明显你无法给你自己指定更多的组(否则就会和 Linux 访问控制的初衷相违背了……)

有一点还是很清楚的:一个新的进程是怎么从我的命令行解释器(/bash/fish)里被执行而得到它的组的。(新的)进程将拥有我的用户 ID(bork),并且进程属性里还有很多组 ID。从我的命令解释器里执行的所有进程是从这个命令解释器里 fork() 而来的,所以这个新进程得到了和命令解释器同样的组。

因此一定存在一个“第一个”进程来把你的组设置到进程属性里,而所有由此进程而衍生的进程将都设置这些组。而那个“第一个”进程就是你的 登录程序 login shell ,在我的笔记本电脑上,它是由 login 程序(/bin/login)实例化而来。登录程序以 root 身份运行,然后调用了一个 C 的库函数 —— initgroups 来设置你的进程的组(具体来说是通过读取 /etc/group 文件),因为登录程序是以 root 运行的,所以它能设置你的进程的组。

让我们再登录一次

好了!假如说我们正处于一个登录程序中,而我又想刷新我的进程的组设置,从我们前面所学到的进程是怎么初始化组 ID 的,我应该可以通过再次运行登录程序来刷新我的进程组并启动一个新的登录命令!

让我们试试下边的方法:

$ sudo login bork
$ groups
bork adm cdrom sudo dip plugdev lpadmin sambashare docker lxd panda
$ cat panda-file.txt # it works! I can access the file owned by `panda` now!

当然,成功了!现在由登录程序衍生的程序的用户是组 panda 的一部分了!太棒了!这并不会影响我其他的已经在运行的登录程序(及其子进程),如果我真的希望“所有的”进程都能对 panda 组有访问权限。我必须完全的重启我的登录会话,这意味着我必须退出我的窗口管理器然后再重新登录。(LCTT 译注:即更新进程树的树根进程,这里是窗口管理器进程。)

newgrp 命令

在 Twitter 上有人告诉我如果只是想启动一个刷新了组信息的命令解释器的话,你可以使用 newgrp(LCTT 译注:不启动新的命令解释器),如下:

sudo addgroup panda
sudo adduser bork panda
newgrp panda # starts a new shell, and you don't have to be root to run it!

你也可以用 sg panda bash 来完成同样的效果,这个命令能启动一个bash 登录程序,而这个程序就有 panda 组。

seduid 将设置有效用户 ID

其实我一直对一个进程如何以 setuid root 的权限来运行意味着什么有点似是而非。现在我知道了,事实上所发生的是:setuid 设置了
“有效用户 ID”! 如果我(julia)运行了一个 setuid root 的进程( 比如 passwd),那么进程的真实用户 ID 将为 julia,而有效用户 ID 将被设置为 root。

passwd 需要以 root 权限来运行,但是它能看到进程的真实用户 ID 是 julia ,是 julia 启动了这个进程,passwd 会阻止这个进程修改除了 julia 之外的用户密码。

就是这些了!

在《Linux 编程接口》这本书里有很多 Linux 上一些功能的罕见使用方法以及 Linux 上所有的事物到底是怎么运行的详细解释,这里我就不一一展开了。那本书棒极了,我上面所说的都在该书的第九章,这章在 1300 页的书里只占了 17 页。

我最爱这本书的一点是我只用读 17 页关于用户和组是怎么工作的内容,而这区区 17 页就能做到内容完备、详实有用。我不用读完所有的 1300 页书就能得到有用的东西,太棒了!


via: https://jvns.ca/blog/2017/11/20/groups/

作者:Julia Evans 译者:DavidChen 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

groups

本教程可以了解如何通过用户组和访问控制表(ACL)来管理用户。

当你需要管理一台容纳多个用户的 Linux 机器时,比起一些基本的用户管理工具所提供的方法,有时候你需要对这些用户采取更多的用户权限管理方式。特别是当你要管理某些用户的权限时,这个想法尤为重要。比如说,你有一个目录,某个用户组中的用户可以通过读和写的权限访问这个目录,而其他用户组中的用户对这个目录只有读的权限。在 Linux 中,这是完全可以实现的。但前提是你必须先了解如何通过用户组和访问控制表(ACL)来管理用户。

我们将从简单的用户开始,逐渐深入到复杂的访问控制表(ACL)。你可以在你所选择的 Linux 发行版完成你所需要做的一切。本文的重点是用户组,所以不会涉及到关于用户的基础知识。

为了达到演示的目的,我将假设:

你需要用下面两个用户名新建两个用户:

  • olivia
  • nathan

你需要新建以下两个用户组:

  • readers
  • editors

olivia 属于 editors 用户组,而 nathan 属于 readers 用户组。reader 用户组对 /DATA 目录只有读的权限,而 editors 用户组则对 /DATA 目录同时有读和写的权限。当然,这是个非常小的任务,但它会给你基本的信息,你可以扩展这个任务以适应你其他更大的需求。

我将在 Ubuntu 16.04 Server 平台上进行演示。这些命令都是通用的,唯一不同的是,要是在你的发行版中不使用 sudo 命令,你必须切换到 root 用户来执行这些命令。

创建用户

我们需要做的第一件事是为我们的实验创建两个用户。可以用 useradd 命令来创建用户,我们不只是简单地创建一个用户,而需要同时创建用户和属于他们的家目录,然后给他们设置密码。

sudo useradd -m olivia
sudo useradd -m nathan

我们现在创建了两个用户,如果你看看 /home 目录,你可以发现他们的家目录(因为我们用了 -m 选项,可以在创建用户的同时创建他们的家目录。

之后,我们可以用以下命令给他们设置密码:

sudo passwd olivia
sudo passwd nathan

就这样,我们创建了两个用户。

创建用户组并添加用户

现在我们将创建 readers 和 editors 用户组,然后给它们添加用户。创建用户组的命令是:

addgroup readers
addgroup editors

(LCTT 译注:当你使用 CentOS 等一些 Linux 发行版时,可能系统没有 addgroup 这个命令,推荐使用 groupadd 命令来替换 addgroup 命令以达到同样的效果)

groups

图一:我们可以使用刚创建的新用户组了。

创建用户组后,我们需要添加我们的用户到这两个用户组。我们用以下命令来将 nathan 用户添加到 readers 用户组:

sudo usermod -a -G readers nathan

用以下命令将 olivia 添加到 editors 用户组:

sudo usermod -a -G editors olivia

现在我们可以通过用户组来管理用户了。

给用户组授予目录的权限

假设你有个目录 /READERS 且允许 readers 用户组的所有成员访问这个目录。首先,我们执行以下命令来更改目录所属用户组:

sudo chown -R :readers /READERS 

接下来,执行以下命令收回目录所属用户组的写入权限:

sudo chmod -R g-w /READERS

然后我们执行下面的命令来收回其他用户对这个目录的访问权限(以防止任何不在 readers 组中的用户访问这个目录里的文件):

sudo chmod -R o-x /READERS

这时候,只有目录的所有者(root)和用户组 reader 中的用户可以访问 /READES 中的文件。

假设你有个目录 /EDITORS ,你需要给用户组 editors 里的成员这个目录的读和写的权限。为了达到这个目的,执行下面的这些命令是必要的:

sudo chown -R :editors /EDITORS
sudo chmod -R g+w /EDITORS
sudo chmod -R o-x /EDITORS

此时 editors 用户组的所有成员都可以访问和修改其中的文件。除此之外其他用户(除了 root 之外)无法访问 /EDITORS 中的任何文件。

使用这个方法的问题在于,你一次只能操作一个组和一个目录而已。这时候访问控制表(ACL)就可以派得上用场了。

使用访问控制表(ACL)

现在,让我们把这个问题变得棘手一点。假设你有一个目录 /DATA 并且你想给 readers 用户组的成员读取权限,并同时给 editors 用户组的成员读和写的权限。为此,你必须要用到 setfacl 命令。setfacl 命令可以为文件或文件夹设置一个访问控制表(ACL)。

这个命令的结构如下:

setfacl OPTION X:NAME:Y /DIRECTORY

其中 OPTION 是可选选项,X 可以是 u(用户)或者是 g (用户组),NAME 是用户或者用户组的名字,/DIRECTORY 是要用到的目录。我们将使用 -m 选项进行修改。因此,我们给 readers 用户组添加读取权限的命令是:

sudo setfacl -m g:readers:rx -R /DATA

现在 readers 用户组里面的每一个用户都可以读取 /DATA 目录里的文件了,但是他们不能修改里面的内容。

为了给 editors 用户组里面的用户读写权限,我们执行了以下命令:

sudo setfacl -m g:editors:rwx -R /DATA 

上述命令将赋予 editors 用户组中的任何成员读取权限,同时保留 readers 用户组的只读权限。

更多的权限控制

使用访问控制表(ACL),你可以实现你所需的权限控制。你可以添加用户到用户组,并且灵活地控制这些用户组对每个目录的权限以达到你的需求。如果想了解上述工具的更多信息,可以执行下列的命令:

  • man usradd
  • man addgroup
  • man usermod
  • man sefacl
  • man chown
  • man chmod

via: https://www.linux.com/learn/intro-to-linux/2017/12/how-manage-users-groups-linux

作者:[Jack Wallen] 译者:imquanquan 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出