V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
AllenHua
V2EX  ›  Linux

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

  •  
  •   AllenHua · 2021-04-10 21:59:44 +08:00 · 2177 次点击
    这是一个创建于 1083 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    20210410214419.png

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

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

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

    查看 /etc/passwd

    20210410215059.png

    用户 test2 的组 id 是 6803


    接着查看 /etc/group

    20210410215211.png

    组 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

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

    14 条回复    2021-04-11 10:29:34 +08:00
    dorothyREN
        1
    dorothyREN  
       2021-04-10 22:19:55 +08:00
    用户的初始组 不显示,你再加个组就有了
    codehz
        2
    codehz  
       2021-04-10 22:23:24 +08:00 via Android   ❤️ 4
    (补充组才需要在 /etc/group 里记录,这是约定)
    你可以反过来思考下为什么要这样约定
    假设不遵循约定会发生什么。。。
    简单说就是数据库设计里避免冗余的方法,如果已经在 passwd 里决定了主组,如果还在 group 里重复记录,那么在出现不一致的时候就会产生歧义,到底按哪个记录为准,现在这样设计就很明确了,登录的时候程序只需要读取 passwd 改变程序的 UID gid,读取 group 扫描有对应用户的 group,通过 setgroups 系统调用设置补充组即可
    AllenHua
        3
    AllenHua  
    OP
       2021-04-10 22:50:01 +08:00
    @codehz #2 有这个约定就好了。谢谢解答!
    AllenHua
        4
    AllenHua  
    OP
       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
        5
    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
        6
    AllenHua  
    OP
       2021-04-10 23:16:49 +08:00
    @palytoxin #5 对 主组应该不需要在 /etc/group 中体现。这是回应本帖正文

    能否接着看看 4 楼的内容?
    palytoxin
        7
    palytoxin  
       2021-04-10 23:23:10 +08:00   ❤️ 1
    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
        8
    palytoxin  
       2021-04-10 23:24:29 +08:00
    id -Gn test2 显示什么?
    codehz
        9
    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
        10
    codehz  
       2021-04-10 23:55:30 +08:00
    linux 用户组管理整个都是用户态处理的,内核只认识数字,也不会去读取文件什么的,所以按照程序显示去学 linux 机制,是要遇坑的。。。
    linux 内核的视角来看,就只能看到如下这些信息(暂时不考虑 euid 等复杂的机制)这些信息都是归属于进程的
    uid gid groups
    对应的就是用户 id,主组 id,补充组 id
    为什么要区分主组和补充组呢,除了历史原因之外,就是为了在使用文件操作的时候有一个唯一的 gid 可用,毕竟文件只能有一个 gid
    但是 id 程序,为了用户方便,就把主组也加入补充组的范畴内了,这样就能一眼看出用户加入了哪些组了
    AllenHua
        11
    AllenHua  
    OP
       2021-04-11 00:10:46 +08:00
    @palytoxin #8 显示 testgroup

    -g 是设置 primary group

    -G 是设置 supplementary group

    看来和不同的 linux 环境有关 我目前是在 openwrt 下 我后面再试试手头的 ubuntu 谢谢老哥
    AllenHua
        12
    AllenHua  
    OP
       2021-04-11 00:14:15 +08:00
    @codehz #10 好的 非常感谢! 🙏
    AllenHua
        13
    AllenHua  
    OP
       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
        14
    mikeguan  
       2021-04-11 10:29:34 +08:00 via Android
    主用户组你不是已经可以查到了吗? Linux 也可以查到呀,如果写了反而感觉是画蛇添足
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2339 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 16:11 · PVG 00:11 · LAX 09:11 · JFK 12:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.