1. 从“创建一条命令”到“理解一套机制”
很多运维新手第一次接触 Linux 用户管理,都是这样上手的:useradd testuser,然后 passwd testuser,完事。最多再补一个 usermod -aG wheel testuser 提个权,就觉得自己会了。直到有一天生产环境出了问题——用户明明创建成功了,却登录不上;加了 sudo 权限,却提示不在 sudoers 中;删了一个用户,结果发现该用户创建的一堆文件变成了一个莫名数字的属主。这时候你才会意识到:Linux 的“用户和组”,根本不只是一条命令、一个配置文件,而是一整套由 UID/GID 分配、认证数据存储、组权限继承机制共同组成的系统。
这篇文章我想系统梳理一下 Linux 用户和组的创建机制,不是罗列 useradd 的参数表,而是把“创建用户时系统到底做了什么”这件事讲透。你会看到 /etc/passwd、/etc/shadow、/etc/group 这三个文件如何协同工作,UID/GID 是怎么分配的,为什么说“组”是 Linux 权限管理里最核心的抽象,以及当 SSH 登录、sudo 授权、文件属主这些实际场景叠加进来时,用户和组的创建机制是如何影响你后续所有操作的。
不管你是刚接触 Linux 的在校学生,还是在生产环境摸爬滚打的运维,这篇文章都值得你从头读到尾。前 2000 字讲机制和原理,中间 3000 字给实操步骤和参数选择逻辑,最后 1500 字分享我在真实服务器上踩过的问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 创建用户时系统到底做了什么
useradd 看起来只是往系统里加了一条记录,但如果你把整个流程拆开看,它涉及至少七个环节的联动。这也是为什么很多人在“创建用户”这件事上出错,因为只盯着命令本身,没看到背后完整的处理流程。
2.1 三个核心文件的工作机制
Linux 系统中用户和组的持久化信息主要存在三个文件里:
/etc/passwd:用户账户的基础信息,包括用户名、UID、GID、家目录、登录 shell。/etc/shadow:用户的密码哈希和密码策略(有效期、最短修改间隔、过期警告等),普通用户不可读。/etc/group:组的信息,包括组名、GID、组成员列表。
这三个文件以冒号分隔字段,每一行代表一条记录。/etc/passwd 的一行长这样:
code复制testuser:x:1001:1001::/home/testuser:/bin/bash
字段依次是:用户名、密码占位符(x 表示真实密码在 shadow 中)、UID、主组 GID、注释信息、家目录、登录 shell。
/etc/shadow 对应行则是:
code复制testuser:$6$randomSalt$hashValue:19000:0:99999:7:::
这里存的是加密后的密码哈希、最后一次修改密码的日期、最短修改间隔、最长有效期、过期前警告天数等。注意一个在运维里很关键的细节:如果 shadow 文件中密码字段为 ! 或 !!,表示该账户没有设置密码或被锁定,这时候哪怕你创建了用户,他也没办法通过密码登录。
/etc/group 的一行是这样:
code复制testuser:x:1001:
对应:组名、组密码占位符、GID、组成员列表(可以为空,表示只有同名用户是该组成员)。
很多初学者会忽略这三者的一致性。实际上,用户管理出问题,大部分时候都是这三个文件之间的对应关系被破坏了。所以我给新人的第一个建议就是:在手动编辑这些文件之前,务必先备份,或者尽量使用 useradd、usermod、groupadd 这些官方命令来操作,而不是直接 vi /etc/passwd。
2.2 创建用户的完整流程拆解
当我们执行 useradd -m -G wheel -s /bin/bash testuser 时,系统按顺序做了这些事情:
- 读取
/etc/login.defs和/etc/default/useradd,获取默认配置(UID 范围、密码过期策略、默认 shell、默认家目录路径等)。 - 在
/etc/passwd末尾追加一行新用户记录,分配一个未使用的 UID 和主组 GID。 - 在
/etc/shadow中创建对应条目,初始密码字段为!,表示账户暂时被锁定,直到passwd设置密码后才可用。 - 在
/etc/group中创建一个与用户名同名的组(如果不指定-g),GID 与 UID 相等。 - 如果指定了
-m,在/home下创建家目录,并复制/etc/skel下的隐藏文件(.bashrc、.bash_profile、.profile等)进去。 - 设置家目录的属主和权限,默认是
testuser:testuser,目录权限为 700。这就是为什么其他用户无法查看你 home 目录下文件的原因。 - 如果指定了
-G,将用户添加到附加组列表中,这一步实际修改的是/etc/group中对应组的成员字段。
第七步有一个容易踩坑的地方:-G wheel 表示将用户加入 wheel 组作为“附加组”,而 -g 指定的是“主组”。主组决定用户创建文件时默认的属组,附加组决定用户还能访问哪些额外权限资源。这两者的区别,在实际运维中经常被人混淆。
2.3 UID/GID 分配的底层逻辑
Linux 内核并不关心你的用户名是什么,它只认识 UID(用户 ID)和 GID(组 ID)。内核在进行权限检查时,比较的是进程的有效 UID 和文件系统对象的属主 UID。也就是说,用户名只是给人看的映射表。
useradd 分配 UID 时遵循一套规则:
- 默认从
/etc/login.defs中UID_MIN和UID_MAX之间找空闲值,常见的发行版配置是 1000-60000 或 1000-65534。 - 分配时会优先选择当前已有最大的 UID 加 1,而不是去“补空位”。这样可以避免 UID 被重复使用引发的安全问题。
- UID 0 是 root,1-999 系统保留给服务账户(如
sshd、nginx、mysql等),
