尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Linux用户组与附加组实战:从概念到命令彻底搞懂

发布时间:2026/9/24 19:03:54

资讯中心
01
ARTICLE

Linux用户组与附加组实战:从概念到命令彻底搞懂

Linux用户组与附加组实战:从概念到命令彻底搞懂
1. 先把概念讲清楚用户、用户组与附加组各司其职上个月我在一台新装好的 Rocky Linux 9 上给项目组搭建共享环境原计划半小时搞定结果在“用户——用户组——附加组”这三层概念上来回绕了好几圈。很多人平时敲useradd、chown、chmod都很溜但被问到“主组和附加组有什么区别”“为什么加了附加组还要重登才生效”时容易卡壳。其实这三者就像是门禁系统的三层设计用户是你的身份卡片用户组是你所在部门的默认权限附加组则是你被额外授权的项目区域权限。本文就用这台测试机上的 10 个实战例子把这三层关系彻底拆开讲清楚。1.1 用户Linux 里的“身份凭证”不是你以为的“人”在 Linux 里用户不是物理意义上的人而是一个权限主体。内核并不关心你叫什么名字它只认一个整数UIDUser ID。我们常用的root、zhangsan只是给这个整数起的“别名”方便人在键盘前识别。操作系统判断“某个进程能不能访问这个文件”归根到底看的是进程的 UID、GID 以及附加组列表而不是看用户名是否匹配。普通文件也好目录也好每个文件都有两个所有权属性文件属主owner和文件属组group。属主是一个 UID属组是一个 GID。你在文件系统里看到的drwxr-xr-x root root第二列root其实是 GID 对应的组名。所以说清楚用户必须先接受一个底层事实Linux 的一切权限判断都是数值运算不是字符串匹配。这一条会在后面解释“为什么改了附加组没生效”的时候反复用到。1.2 用户组默认权限的“打包单位”用户组group是一组用户的集合以 GID 为唯一标识。它的核心作用有两个一是给一组用户赋予相同的文件访问权限二是作为新创建文件的默认属组。每个用户都必须有一个主组primary group。用户创建文件时文件的属组默认就是该用户的主组。比如用户zhangsan主组是devops那他touch一个新文件ls -l看到的属组就是devops。这个默认行为可以通过目录的 setgid 位改写后面例子 6 会专门演示。1.3 附加组给用户增加权限边界的“后门”附加组supplementary groups是用户除主组之外额外加入的组。一个用户可以同时属于多个组其中一个是主组其余都是附加组。附加组的意义在于按项目场景动态扩展权限而不用把用户的主组改来改去。举例来说zhangsan的主组是devops但他临时参与ops项目的值班需要访问/project/share目录运维管理员只要把他加入ops附加组他就能拥有该目录赋予ops组的权限。流程上是usermod -aG ops zhangsan然后让zhangsan重新登录一次。如果一开始就把zhangsan的主组改成ops那他以后建文件默认属组都会变成ops反而不利于按部门隔离。1.4 主组和附加组别再用“等级”去理解网上很多文章喜欢把组说成“上级”把用户说成“下级”这种等级化描述容易误导。更准确的理解是主组是用户“默认归属”的组决定新文件的默认属组附加组是用户“额外被授权”的组决定用户能额外访问哪些组权限的资源。两者没有“高级低级”之分只是在权限判定时地位不同。进程访问文件时内核会依次检查进程的 UID 是否等于文件属主 UID再检查进程的 GID 或附加组列表里是否有文件属组 GID最后看该组的权限位。这里的关键点附加组列表和主组一样都属于进程凭证只是修改后的生效时机不同这个在例子 4 和例子 8 里会进一步展开。2. 账号体系背后的三张表和四条命令理解了概念后必须知道这些信息落在哪里。Linux 账号体系的核心是三个文本文件Linux 之所以强大是因为这些文件是纯文本、可解释、可备份的。但这也意味着一旦手滑改错格式用户就可能登录不了系统。2.1/etc/passwd里的 7 个冒号段/etc/passwd文本格式如下zhangsan:x:1002:1003::/home/zhangsan:/bin/bash这段共 7 列按顺序分别是列含义zhangsan用户名x密码占位符真正的密码哈希在/etc/shadow1002UID1003主组 GID-用户描述信息GECOS可为空/home/zhangsan用户家目录/bin/bash登录 Shell注意第二列在现代 Linux 里固定是x如果这里直接放一段!!或*通常表示该用户禁止密码登录。不要手动改这一列要改密码就走passwd。2.2/etc/group里的 4 个冒号段成员字段就是附加组入口/etc/group的格式相对简单ops:x:1005:zhangsan,lisi四列分别是组名、密码占位符、GID、组成员列表。成员列表可以理解为“额外的用户集合”这里的用户其实都是附加组用户。如果一个用户的主组是ops他不会出现在这个成员字段里而是出现在/etc/passwd的第四列。这个细节会带来一个很常见的困惑groups zhangsan显示zhangsan : devops ops但你在/etc/group的devops行里却看不到zhangsan因为devops是他主组。看到成员字段里没有自己先别急着怀疑系统出错了。2.3/etc/shadow密码与密码策略的敏感文件/etc/shadow保存密码哈希和密码过期策略只有 root 和有特殊权限的进程能读。它的第 2 列是加密后的密码字符串常见开头有$6$SHA-512、$y$yescrypt、!锁定等。如果看到!!或者!开头说明这个用户没有可用密码通常是不能登录的。日常排查“用户无法登录”时要先看这一列而不是急着改权限。比如刚用useradd创建的用户在passwd之前shadow 字段就是!!表现为“输对密码也进不去”因为根本没有有效密码。2.4 常用命令及使用边界用户和组管理的主要命令有四条useradd创建用户配置主组、附加组、家目录、Shellusermod修改已有用户的属性比如改主组、加附加组、改家目录groupadd/groupdel创建/删除用户组passwd/chpasswd/chage设置密码和管理密码策略。另外还有两个“查询类”命令id和groups。id的输出最完整会列出 UID、GID 和 groups 列表groups则只输出用户所属的组名列表。这两者都能看到附加组但输出格式不一样后面例子 8 会专门演示其中的坑。3. 实战拆解从零搭建一个用户与组管理方案10 个例子下面这 10 个例子不是孤立的命令堆砌而是一条完整业务线。我在 Rocky Linux 9 上模拟了一个场景项目组要新来 3 个研发、2 个运维需要建共享目录/project/share研发要能读写项目文件运维要在共享目录里拥有管理权限。整个过程从确认环境开始到最终删号收尾全部覆盖。提示以下命令默认在 root 权限下执行除非特别说明否则不要在每台机器上盲目照抄请根据实际 UID/GID 范围调整。3.1 例子 1先摸清这台机器的用户 ID 分配范围创建账号前先看系统的 UID/GID 默认分配规则否则盲目useradd后可能和已有用户冲突。grep -E ^UID_MIN|^UID_MAX|^SYS_UID_MIN|^SYS_UID_MAX|^GID_MIN|^GID_MAX /etc/login.defs我这边输出是UID_MIN 1000 UID_MAX 60000 SYS_UID_MIN 201 SYS_UID_MAX 999 GID_MIN 1000 GID_MAX 60000 SYS_GID_MIN 201 SYS_GID_MAX 999这说明系统普通用户的 UID 从 1000 开始给系统服务预留的 UID 是 201~999。查看目的有两点第一给业务用户指定 UID 时不要落在系统区间第二理解不同发行版的标准不同CentOS 系用 1000Debian 系早期也有从 1000 开始但有些新版桌面版从 1000 开始却保留 1000 给首个用户需要实测。知识点提取用户 UID 分配范围由/etc/login.defs控制useradd默认按照这个范围递增分配。创建业务用户时建议显式指定一个高段 UID比如20220起方便后期从众多账号中区分业务账号和系统账号。3.2 例子 2创建三个用户组并约定 GID 编号按照项目规划需要devops研发组、ops运维组、guest访客组三组。为了未来权限审计清晰GID 也不随机分配groupadd -g 12001 devops groupadd -g 12002 ops groupadd -g 12003 guest验证getent group devops ops guest输出devops:x:12001: ops:x:12002: guest:x:12003:这里我手动指定了 GID。groupadd -g的-g选项就是指定 GID后面跟一个未使用的数字。生产环境中GID 规划比 UID 规划更重要因为组通常要配合目录权限如果组 ID 在跨服务器同步时不统一NFS 等场景下容易权限错乱。知识点提取组也分系统组和普通组系统组一般用groupadd -r创建GID 落在系统范围内用于服务运行不建议把业务用户加入系统组。业务组建议从 10000 以上开始分配并在团队 Wiki 里维护一张“GID 分配表”避免两台服务器各建各的导致同一个组两个 ID。3.3 例子 3创建研发用户指定主组和附加组创建第一个研发用户zhangsan要求主组是devops附加组带上ops家目录和 Shell 也有明确要求useradd -u 20221 -m -d /home/zhangsan -s /bin/bash -g devops -G ops zhangsan检查用户信息id zhangsan输出uid20221(zhangsan) gid12001(devops) groups12001(devops),12002(ops)这里一条命令就把三件事做了-u 20221指定 UID-g devops指定主组-G ops指定附加组。我故意把 UID 设成 20221 是为了和系统用户明显拉开距离方便后续安全策略如按 UID 段过滤使用。注意-G后面可以接多个附加组用逗号分隔比如-G ops,guest。知识点提取useradd的-g指定主组-G指定附加组。如果不指定-guseradd会默认创建与用户名同名的组作为主组这个默认行为由/etc/login.defs里的USERGROUPS_ENAB yes控制。很多人刚学 Linux 时看到“怎么创建了一个用户会自动多出一个同名组”其实就是这个原因。3.4 例子 4给已有用户追加附加组记得用-aG过了两天运维组反馈希望zhangsan也参与发布工作那就把他加入ops附加组。此时操作是usermod -aG ops zhangsan注意这个-a是--append的缩写表示“追加”。如果漏掉-a只写usermod -G ops zhangsan会把zhangsan原有的附加组列表整体替换成ops原来属于devops主组的附加组关系被清空。虽然主组不受影响但他在其他组的权限会瞬间消失。我特意做过一次破坏性实验usermod -G ops zhangsan id zhangsan输出uid20221(zhangsan) gid12001(devops) groups12001(devops),12002(ops)因为zhangsan原本只有ops一个附加组这次没看出什么问题。但如果用户原本有ops,dba两个附加组这条命令执行后就只剩ops了。生产环境改附加组的黄金法则是凡是usermod -G务必带上-a除非你明确要覆盖整个附加组列表。知识点提取usermod -aG是追加usermod -G是覆盖。两个命令在字母上看只差一个a后果天差地别。另外注意修改完附加组后已登录的会话不会自动拿到新组权限必须退出重新登录或者用newgrp临时切换这一点排在“附加组不生效”问题排查的第一位。3.5 例子 5修改用户主组后为什么文件属组不变项目调整后zhangsan从研发组调入运维组需要把主组改成opsusermod -g ops zhangsan执行后查看id zhangsan输出uid20221(zhangsan) gid12002(ops) groups12002(ops),12001(devops)主组已经变成ops原来的devops自动变成附加组。但这里有个坑zhangsan家目录以及他之前创建的文件属性组不会自动跟着变。看一下ls -ld /home/zhangsan ls -l /home/zhangsan/test.txt大概率还是zhangsan devops因为usermod只改了账号在/etc/passwd里的主组 GID不会逐个扫描文件去改属组。若业务要求文件属组也迁移必须额外执行chown -R zhangsan:ops /home/zhangsan知识点提取修改主组和修改文件属组是两件事。命令层面的usermod -g只是修改了“默认组”凡是用户以后新建的文件默认属组才会是ops。历史文件需要手动chown。操作顺序上先chown再让用户切回目录干活否则他有可能会在旧权限环境下创建一些归属混乱的文件。3.6 例子 6创建共享目录让附加组权限真正生效现在建立/project/share目录目标是属于devops和ops的用户都能进入并创建文件且所有新文件自动继承ops组。这样zhangsan虽然主组已改为ops但依然能访问。命令如下mkdir -p /project/share chown root:ops /project/share chmod 2775 /project/sharechown root:ops把目录属组设为opschmod 2775是两个权限位的组合2是 setgid 位775是 rwxr-xr-x。setgid 位的作用是在该目录下新建的文件或子目录其属组自动继承目录的属组而不是创建者主组。如果没有 setgidzhangsan在这里touch一个文件文件的属组应该是他的主组ops但如果他的主组后来变成devops新文件属组又会变成devops很容易造成混乱。用zhangsan验证访问su - zhangsan -c touch /project/share/test.txt ls -l /project/share/test.txt输出中属性组是ops说明 setgid 生效了。再让另一个用户lisi也测试只要能写就证明附加组授权生效。知识点提取共享目录权限三板斧chown root:组名、chmod 2775、成员加入附加组。如果你要给多个组共享可以创建多个目录分别 chown 给不同组再把用户分别加入对应附加组。比直接把所有用户加入同一个组更安全。3.7 例子 7临时切换主组newgrp与sg的用法有时候用户需要“临时以某个组身份”创建文件但不想退出重新登录。比如zhangsan当前主组是ops临时要以devops的身份创建一个放在共享区里的文件su - zhangsan newgrp devops touch temp_devops.txt ls -l temp_devops.txt输出中temp_devops.txt的属组就是devops。newgrp会启动一个新的子 Shell并把当前主组切换成指定的组。切换条件是你必须属于这个组也就是它要么是主组要么在附加组列表里。退出这个子 Shell 后主组恢复原样。sg命令和newgrp类似但它适合一次性执行命令而不进入交互式 Shellsg devops -c touch temp_sg.txt知识点提取newgrp/sg是“不退出登录就临时变更主组”的最便捷方式常用于解决“我想在这个目录下生成一个属于某组的文件”的需求。注意这两个命令依赖一个前提用户必须已经是该组成员否则会提示密码或拒绝。不要去改/etc/group里的主组字段来绕过那是翻车率最高的操作之一。3.8 例子 8用id和groups正确读取成员关系查用户组关系最容易踩的坑在groups输出上groups zhangsan输出zhangsan : ops devops这个列表的第一个ops是主组devops是附加组。但不少文档会把输出的第一个组当成“第一个附加组”其实它不是。要更清晰地看 UID/GID 和组关系用idid zhangsan输出uid20221(zhangsan) gid12002(ops) groups12002(ops),12001(devops)这里gid后面的是主组groups后面跟着的是完整组列表第一个仍是主组之后才是附加组。如果你只想看附加组可以用id -nG zhangsan输出中没办法一眼区分哪个是主组因为-nG会把所有组名列出。要精确区分就配合id -gn获取主组名id -gn zhangsan id -nG zhangsan知识点提取判断附加组不要凭直觉数第几个要结合id的完整输出gid即主组groups列表里去掉主组后剩下的全是附加组。如果/etc/group的成员字段里看不到某用户但groups能看到那是因为这个组恰好是它的主组并不是系统出错了。3.9 例子 9批量创建用户脚本里最容易忽略的密码策略批量添加用户是最常见的自动化需求。现在要创建 5 个用户alice、bob、carol、dave、eve前 3 个加入devops附加组全部加入ops附加组。脚本如下for user in alice bob carol dave eve; do useradd -m -s /bin/bash -G ops $user echo $user:Init123 | chpasswd chage -d 0 $user done usermod -aG devops alice usermod -aG devops bob usermod -aG devops carol分解一下第一行useradd -m -s /bin/bash -G ops表示创建用户、创建家目录、Shell 设为 bash附加组加入ops第二行echo ... | chpasswd批量设置初始密码第三行chage -d 0强制用户下次登录后必须修改密码。脚本看起来短坑其实不少。最大的坑是如果不写chage -d 0用户拿着初始密码可能一直不换安全审计一查一个准。第二坑是加了-G ops后再执行usermod -G devops alice没有-a会把ops附加组覆盖掉所以我在脚本里对需要多个附加组的用户用了-aG devops追加。知识点提取批量创建用户三个关键点密码不落库用chpasswd以 stdin 方式批量设置强制首次登录修改密码必须chage -d 0对已有用户的附加组进行追加时牢记-aG避免覆盖。脚本写完后建议先bash -n useradd.sh做语法检查再在测试机跑一遍。3.10 例子 10删除用户时家目录和组的正确清理有员工离职需要删除账号eve。生产环境里的删除操作必须谨慎先确认她不再拥有任何共享目录的属主文件find /project -user eve -ls如果确认没有需要保留的文件直接删除并清理家目录userdel -r eve-r会同时删除家目录和邮件池。如果忘记-r家目录会残留通常是很占空间的隐患。接着看eve加入的组是否需要清理成员关系gpasswd -d eve ops不过用户都删了这个命令其实会报错“user doesnt exist”正确的顺序是先把用户从所有附加组中移除再删除用户。如果已经删了组里的成员列表已经自动被系统去掉了吗不一定。实际上userdel会尝试从/etc/group的成员列表里移除该用户但有些情况下比如手动编辑过组文件会留下不再存在的用户名导致解析器发出警告。知识点提取删除用户流程建议是先检查该用户是否拥有共享文件find / -user 用户名再用gpasswd -d或直接调用userdel前先编辑组不行组操作只建议命令最后userdel -r 用户名并保留用户 UID/GID 以防重建时被新用户占用。这一步做完整个用户生命周期就完整闭环了创建、配置、授权、迁移、删除。4. 最容易翻车的三个场景与完整排查链路理论知识再熟实际运维中一样会踩坑。这里把我自己碰过的三个高发问题整理成完整排查链路照着顺序走比漫无目的地改权限高效得多。4.1 场景 A加完附加组还是访问不了共享目录某同事反馈明明已经执行了usermod -aG ops zhangsan但zhangsan访问/project/share仍然Permission denied。排查链路第一步确认组成员关系是否真的加上了id zhangsan如果输出里没有12002(ops)说明命令没执行成功回去看第 3 步。第二步确认用户当前会话是否重新加载了组身份这是最容易被忽略的一步。用户在那个报错的终端里如果是在执行usermod之前就已登录那么他的进程组列表还是旧的。让他执行exit后重新登录或直接newgrp ops临时切换再测试。第三步逐级检查目录权限namei -l /project/sharenamei会输出路径上的每一级目录权限。如果/project或/的权限没有给足 others 或相关组的x权限用户根本无法“穿过去”。常见情况是/project权限是 750属组是 root那么非 root 用户就无法进入。需要给/project设置 755 或把共享目录挂到路径更浅的位置。第四步检查文件系统挂载选项mount | grep /project如果挂载选项里有nosuid还好若是noexec会导致执行脚本受限但一般不影响读写。更关键的是有些远程文件系统如 NFS有root_squash等行为会影响属主显示这些放到远程文件系统专项讨论。知识点提取“加了组但没权限”按 90% 概率集中在两个原因会话未刷新、目录中间路径缺 x 权限。不要一上来就改 777先用id和namei定位问题。4.2 场景 B主组改完文件属组一团糟有一次我把用户的-g从devops改成ops旧文件属组依然停留在devops导致共享备份脚本按组匹配时把该用户文件漏了。这里的原因是usermod -g不负责重新分配文件属组。正确的排查和处理方式find /home/zhangsan -group devops -exec chgrp ops {} \;先把该用户家目录中所有属组为旧组的文件批量改成新组再检查共享目录find /project -user zhangsan -exec chgrp ops {} \;如果文件特别多建议在业务低峰期执行并在执行前确认不会影响正在运行的应用。另外如果你想让用户主组和设备上的默认组保持一致还要调整/etc/default/useradd或/etc/login.defs里的GROUP变量。知识点提取主组变更后文件属组不会自动跟随。所以改usermod -g后强制更新目标目录的文件属组是标准动作。这一步在操作计划里就要写好别等用户反馈“新文件是 ops老文件还是 devops”才补补的次数多了容易漏。4.3 场景 C手动编辑/etc/group导致用户直接“消失”我见过有人直接用vi /etc/group在成员列表末尾加用户名结果保存后系统里某些服务读取组信息时直接报错用户登录后也看不到那个组。这类问题通常出在格式细节上成员之间必须用英文逗号分隔不能有空格成员列表末尾不要留逗号组名、GID、成员行不能有额外冒号如果你新增了一行GID 不能与其他行重复。一旦格式被破坏getent group会跳过异常行用户在groups输出里也就看不到该组。强烈建议不要手动编辑/etc/group添加组成员用usermod -aG或gpasswd -a删除组成员用gpasswd -d。万一你真手改了赶紧恢复cp /etc/group /etc/group.bak getent group | grep xxx如果连getent都无法输出可以把/etc/group.bak恢复回来再检查是否与/etc/passwd、/etc/shadow里的主组 GID 对应。恢复用的备份建议提前用 cron 每天拷贝一次这是防止“手滑”的最后防线。5. 知识点提取一张表命令、作用、坑位速查把上面 10 个例子里反复出现的命令整理成一张速查表适合贴在便签上或在排障时快速回忆。命令作用关键选项/易错点useradd新建用户-u指定 UID-g指定主组-G指定附加组-m创建家目录usermod修改用户属性-aG追加附加组-G覆盖附加组-g修改主组注意文件属组不会自动变userdel删除用户-r同时删除家目录/邮件池删除前先检查用户文件groupadd新建组-g指定 GID业务组建议从 10000 开始分配gpasswd管理组成员-a添加成员-d删除成员不要手动编辑/etc/groupid查看完整身份信息id显示 uid/gid/groupsid -gn只看主组名id -nG列出所有组名groups查看组列表输出第一个是主组不是附加组newgrp临时切换主组需要已是组成员sg适合一次性命令chown修改属主/属组chown user:group file同时改两者chown :group file只改属组chmod 2xxx设置 setgid/setuid/sticky2775的2表示 setgid使新文件自动继承目录属组chage管理密码老化策略chage -d 0 user强制用户下次登录改密chpasswd批量设置密码通过 stdin 传user:password适合脚本这张表对比下来能看出 Linux 用户管理的一条核心原则所有“变更”都应该通过专用命令完成而不是直接编辑配置文件。配置文件只是最终落地的结果命令才是经过了校验和封装的正式入口。如果你在做自动化运维建议在脚本里加上set -e并对每一步操作的结果做校验比如id user确认追加成功后再继续下一步。这样一套下来用户、用户组、附加组这套体系就不会再是“命令会敲报错不会查”的状态了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。