问个 Linux 问题,纠结一下午了,关于 user 和 group, /etc/passwd 和 /etc/group

2021-04-10 21:59:44 +08:00
 AllenHua

/etc/passwd 和 /etc/group 文件详解 https://www.cnblogs.com/zx3212/p/9141381.html

/etc/group 的英文原版解释:

其中纠结的点在于 /etc/group 的第四个字段,这个字段是属于该组成员的用户名列表,以逗号分隔的

使用命令创建一个 user,并指定它的家目录,指定他的主组( primary group ),还指定它的 shell 解释器

useradd test2 -d /home/test2 -g testgroup -m -s /bin/bash

查看 /etc/passwd

用户 test2 的组 id 是 6803


接着查看 /etc/group

组 id 6803 组名的确是 testgroup,但是问题来了,为什么第四个字段没有 test2 这个用户?不是该组名下的用户列表么,为什么是空的,为什么没有 test2 这个用户

关于这一点,楼主和朋友搜索了大量资料,关于 Linux 的一个 user,它有 primary group (有且仅有一个主组),还有 supplementary group (还有补充组,一个 user 可以属于多个补充组)

The primary group is the main one shown in /etc/passwd

The supplementary groups give access to resources, but any new files are created with primary group.

现在简要说明一下,楼主还是不太明白为什么我刚刚创建 test2 这个 user,并且指定了他的 primary group 是 testgroup 但是!但是! 但是在 /etc/group 中看这个组的用户列表里却没有 test2

希望有人来帮楼主解惑,感激万分!

2333 次点击
所在节点    Linux
14 条回复
dorothyREN
2021-04-10 22:19:55 +08:00
用户的初始组 不显示,你再加个组就有了
codehz
2021-04-10 22:23:24 +08:00
(补充组才需要在 /etc/group 里记录,这是约定)
你可以反过来思考下为什么要这样约定
假设不遵循约定会发生什么。。。
简单说就是数据库设计里避免冗余的方法,如果已经在 passwd 里决定了主组,如果还在 group 里重复记录,那么在出现不一致的时候就会产生歧义,到底按哪个记录为准,现在这样设计就很明确了,登录的时候程序只需要读取 passwd 改变程序的 UID gid,读取 group 扫描有对应用户的 group,通过 setgroups 系统调用设置补充组即可
AllenHua
2021-04-10 22:50:01 +08:00
@codehz #2 有这个约定就好了。谢谢解答!
AllenHua
2021-04-10 22:59:07 +08:00
@codehz #2

![20210410225440.png]( https://cdn.jsdelivr.net/gh/hellodk34/image@main/img/20210410225440.png)

刚创建 test2 这个用户,它的 supplementary group (也就是 GROUPS ) 就包含了 dkgroup 了(就是帖子正文中的 testgroup ),啊这,为啥 /etc/group 没有显示呢

手动追加 `usermod -a -G dkgroup test2` 之后才显示

```
# id test2
uid=6803(test2) gid=6802(dkgroup) groups=6802(dkgroup),6802(dkgroup)
```

此时显示了,看 test2 的 groups 里有两个 dkgroup ?
palytoxin
2021-04-10 23:13:10 +08:00
查了下,http://linux.vbird.org/linux_basic/0410accountmanager.php#account_group_init,鸟哥这里讲的有效群組(effective group)與初始群組(initial group)应该对应你说的 primary group,supplementary group 。然后 groups 还有根据 /etc/nsswitch.conf 所定义的一些内容,不过根据你的操作,我在本机上试了试,passwd 的群组是不需要在 /etc/group 里体现的
AllenHua
2021-04-10 23:16:49 +08:00
@palytoxin #5 对 主组应该不需要在 /etc/group 中体现。这是回应本帖正文

能否接着看看 4 楼的内容?
palytoxin
2021-04-10 23:23:10 +08:00
man usermod 有个

-g, --gid GROUP
The group name or number of the user's new initial login group. The group must exist.

Any file from the user's home directory owned by the previous primary group of the user will be owned by
this new group.

The group ownership of files outside of the user's home directory must be fixed manually.

-G, --groups GROUP1[,GROUP2,...[,GROUPN]]]
A list of supplementary groups which the user is also a member of. Each group is separated from the next
by a comma, with no intervening whitespace. The groups are subject to the same restrictions as the group
given with the -g option.

If the user is currently a member of a group which is not listed, the user will be removed from the
group. This behaviour can be changed via the -a option, which appends the user to the current
supplementary group list.

我自己测试
usermod -g testgroup test2
usermod: no changes

-g 是初始组 -G 是追加组

不过在我这里 追加`usermod -a -G testgroup test2` 还是显示一个 testgroup
id test2
uid=1002(test2) gid=1002(testgroup) groups=1002(testgroup)

这个考虑你的软件环境
palytoxin
2021-04-10 23:24:29 +08:00
id -Gn test2 显示什么?
codehz
2021-04-10 23:40:12 +08:00
@AllenHua 这不就是我说的不遵循约定的后果吗,你的主要组已经是是 dkgroup 了,然后再加入 group 里,id 程序就会显示两个了。。。
id 程序的逻辑你可以理解成这样
主组(/etc/passwd 拿到的)的加入 groups 显示
补充组(/etc/group 拿到的)也加入 groups 显示,然后这里没有做去重处理,就显示出两个了。
你直接 su 登录那个账户,再用 id 命令,此时应该会走另一个逻辑,直接从当前进程获取 gid 和 groups,这样应该不至于显示出两个重复的 dkgroup 了(根据 https://man.archlinux.org/man/getgroups.2 文档,getgroups 可能或不能列出主组,所以应用程序要自己整理,id 程序应该会自己去除重复项目)
codehz
2021-04-10 23:55:30 +08:00
linux 用户组管理整个都是用户态处理的,内核只认识数字,也不会去读取文件什么的,所以按照程序显示去学 linux 机制,是要遇坑的。。。
linux 内核的视角来看,就只能看到如下这些信息(暂时不考虑 euid 等复杂的机制)这些信息都是归属于进程的
uid gid groups
对应的就是用户 id,主组 id,补充组 id
为什么要区分主组和补充组呢,除了历史原因之外,就是为了在使用文件操作的时候有一个唯一的 gid 可用,毕竟文件只能有一个 gid
但是 id 程序,为了用户方便,就把主组也加入补充组的范畴内了,这样就能一眼看出用户加入了哪些组了
AllenHua
2021-04-11 00:10:46 +08:00
@palytoxin #8 显示 testgroup

-g 是设置 primary group

-G 是设置 supplementary group

看来和不同的 linux 环境有关 我目前是在 openwrt 下 我后面再试试手头的 ubuntu 谢谢老哥
AllenHua
2021-04-11 00:14:15 +08:00
@codehz #10 好的 非常感谢! 🙏
AllenHua
2021-04-11 00:16:40 +08:00
@palytoxin #7 -g 就是改主组

刚在 ubuntu 下测试了 groups 并没有变成两个 hhh

`usermod -a -G testgroup test2` 后

执行 id test2 groups 没有出现两个 😂️

ps: 本帖我一直用的 openwrt 测试的

![20210411001551.png]( https://cdn.jsdelivr.net/gh/hellodk34/image@main/img/20210411001551.png)
mikeguan
2021-04-11 10:29:34 +08:00
主用户组你不是已经可以查到了吗? Linux 也可以查到呀,如果写了反而感觉是画蛇添足

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/769788

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX