☰
Linux用户管理核心配置文件详解:passwd、shadow与group实战
2026/10/12 2:41:35 网站建设 项目流程

之前在准备 Linux 运维和系统管理相关的面试内容时,用户管理这一块几乎每次都会被问到,尤其是/etc/passwd、/etc/shadow、/etc/group这几个文件。很多刚入行的同学能背出useradd、passwd命令,但一被问到底层改了什么文件、每个字段代表什么含义,就答不上来了。实际上,Linux 的所有账户操作最终都会落到这些配置文件上,理解了文件结构,命令只是顺带的事。

本文将围绕 Linux 用户管理的核心配置文件展开,逐一拆解/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow的文件格式与字段含义,再把/etc/login.defs、/etc/default/useradd、/etc/skel这几个关联配置讲清楚。文章末尾会整理常见的面试题和排错思路,帮助你在面试和实际运维中都能快速找到思路。

1. 为什么要重点掌握用户相关配置文件

Linux 是一个多用户、多任务的操作系统,用户管理是所有系统管理工作的基础。用户能够登录系统、访问文件、执行命令,靠的并不是“记住一个名字”,而是系统在底层去检查一组配置文件。

先思考一个问题:当你在终端执行useradd zhangsan时,系统到底做了什么?

一条命令执行后,系统实际上是依次修改了多个文件:

  • 向/etc/passwd追加了一行用户基本信息。
  • 向/etc/shadow追加了一行密码信息。
  • 如果指定了用户组,还要更新/etc/group文件。
  • 同时从/etc/skel目录复制默认的配置文件到新用户家目录。
  • 最后创建/home/zhangsan目录并设置权限。

也就是说,用户管理的本质,就是对这一组配置文件进行读写。面试中问配置文件,并不是为了考背诵,而是考察你是否理解系统账户体系的运作方式。

与此同时,这些文件也是排查用户问题的重要入口。比如用户无法登录、密码过期、找不到家目录、权限异常、无法切换用户等,这些问题最终都要回溯到配置文件中的字段值。掌握了字段含义,就相当于拿到了排查故障的第一手工具。

下图可以帮你理解用户管理配置文件之间的关系:

用户管理相关配置文件 ├── /etc/passwd 用户账户基本信息 ├── /etc/shadow 用户密码与过期策略 ├── /etc/group 用户组基本信息 ├── /etc/gshadow 用户组密码与组管理员 ├── /etc/login.defs 全局用户默认属性 ├── /etc/default/useradd useradd 命令默认配置 └── /etc/skel 用户家目录模板文件

下面我们从最核心的四个文件开始逐步拆解。

2. /etc/passwd:用户账户信息主文件

2.1 文件作用

/etc/passwd是 Linux 系统中存储用户账户信息的文本文件。系统每次用户登录时,都会读取这个文件来获取用户名、UID、家目录和登录 Shell 等信息。

需要注意的是,/etc/passwd对所有用户都是可读的,因为它包含的是非敏感信息,比如用户名和家目录路径。它并不直接保存密码,真正的密码密文存放在/etc/shadow中,这也是为什么passwd文件中密码字段通常是一个x。

2.2 文件格式与字段说明

/etc/passwd中每行代表一个用户账户,格式如下:

用户名:密码占位符:UID:GID:注释信息:家目录:登录Shell

下面用一个实际例子来说明:

zhangsan:x:1000:1000:张三:/home/zhangsan:/bin/bash
字段位置字段名示例值含义说明
1用户名zhangsan登录系统时使用的账户名,不能包含冒号
2密码占位符x表示真实密码存储在 /etc/shadow 中
3UID1000用户 ID,系统内核通过 UID 识别用户
4GID1000用户主组 ID,对应 /etc/group 中的组
5注释信息张三通常为用户全名、联系方式等描述,可以为空
6家目录/home/zhangsan用户登录后的默认工作目录
7登录 Shell/bin/bash用户登录后启动的 Shell 程序

看到这里你可能会问,为什么密码字段不直接写密文?早期 Unix 系统确实直接把密码密文放在/etc/passwd的第二个字段中。但后来人们发现这个文件需要被所有用户读取(很多程序需要查询用户名和 UID),这样一来密码密文就暴露给了所有人,任何人都可以用暴力破解工具去尝试。于是系统改成了 shadow 机制,把密码密文转移到只有 root 用户可读的/etc/shadow文件中,而/etc/passwd的第二个字段统一用x占位。

2.3 UID 与 GID 的分配规则

在 CentOS、Ubuntu 等发行版中,UID 的分配是有策略的:

  • 0:root 用户,超级用户。
  • 1-999:系统用户,例如bin、daemon、sshd、nginx等。这些用户通常用于运行后台服务,不需要登录系统。
  • 1000-60000:普通用户,通过useradd创建的用户默认从 1000 开始分配。

GID 的规则与 UID 类似,不单独划分。

UID 范围: 0 → root 超级用户 1-999 → 系统服务账户 1000+ → 普通用户

在面试中,如果被问到“如何查一个用户的 UID”,可以直接使用:

id zhangsan

输出示例:

uid=1000(zhangsan) gid=1000(zhangsan) groups=1000(zhangsan),10(wheel)

如果想直接查看/etc/passwd中某一行的内容:

grep zhangsan /etc/passwd

3. /etc/shadow:用户密码与过期策略文件

3.1 文件作用

/etc/shadow是保存用户密码密文及密码策略的文件。它只允许 root 用户和具有必要权限的程序读取,普通用户无法查看,这样大大提高了密码的安全性。

这个文件解决的不仅是“密码隐藏”的问题,还引入了密码过期、密码最小修改间隔、账号失效等字段,让系统管理员可以精细化控制账号生命周期。

3.2 文件格式与字段说明

/etc/shadow中每行对应一个用户,格式如下:

用户名:加密密码:最后一次修改时间:最小修改间隔:最大有效天数:提前警告天数:过期宽限天数:账号失效日期:保留字段

实际示例:

zhangsan:$6$abc123$xxxxxxxx:20000:0:99999:7:0:19799:
字段位置字段名示例值含义说明
1用户名zhangsan与 /etc/passwd 中的用户名对应
2加密密码$6$...密码密文,!或!!表示锁定或无密码
3最后一次修改时间20000从 1970-01-01 到最近一次改密码的天数
4最小修改间隔0距上次修改至少多少天后才能再次修改
5最大有效天数99999密码最长使用天数,超过后必须修改
6提前警告天数7密码过期前多少天开始提醒用户
7过期宽限天数0密码过期后仍允许登录的天数
8账号失效日期19799从 1970-01-01 起算的账号失效日期
9保留字段空保留未使用

第三段时间“最后一次修改时间”通常新手看不懂,它不是一个日期格式,而是天数。可以通过下面命令换算成可读日期:

# 例如 shadow 中第三个字段是 20000 date -d "1970-01-01 20000 days" +"%Y-%m-%d"

关于密码加密算法,$6$表示 SHA-512,$5$表示 SHA-256,$1$表示 MD5,$y$表示 yescrypt(部分新版发行版)。看到以$开头的密文时,可以通过第一个分隔段判断算法类型。

3.3 密码锁定状态

如果/etc/shadow中密码字段以!或!!开头,表示该用户密码被锁定,无法登录。例如:

zhangsan:!!$6$abc123$xxxxxxxx:20000:0:99999:7:0:19799:

这里!!是 passwd -l 锁定操作留下的标记。解锁操作则使用:

passwd -u zhangsan

还有种情况是新用户刚创建时,密码字段就是!!,表示尚未设置密码。此时必须用passwd zhangsan设置密码后才能登录。

4. /etc/group 与 /etc/gshadow:用户组信息

4.1 /etc/group 基本格式

Linux 的权限模型不仅针对用户,也针对用户组。用户组方便了权限的批量分配,比如把多个开发人员加入同一个组,然后设置该组对某个目录有读写权限。

/etc/group中每行代表一个组:

组名:密码占位符:GID:组成员列表

示例:

devteam:x:1001:zhangsan,lisi,wangwu
字段位置字段名示例值含义说明
1组名devteam组的名称
2组密码占位符x真实组密码存放在 /etc/gshadow
3GID1001组的唯一 ID
4组成员zhangsan,lisi逗号分隔的组成员列表

注意区分“主组”和“附加组”:

  • 主组:用户在/etc/passwd中第 4 字段指定的 GID,创建文件时默认属组。
  • 附加组:用户额外加入的组,用于扩展权限。

查看用户所在所有组可以使用:

groups zhangsan

4.2 /etc/gshadow 基本格式

/etc/gshadow与/etc/shadow类似,存储用户组的密码和组管理员信息:

组名:加密组密码:组管理员:组成员

示例:

devteam:!:zhangsan:zhangsan,lisi,wangwu

字段含义如下:

  • 组名:与/etc/group第一字段一致。
  • 加密组密码:如果为!表示没有组密码或组密码被锁定。
  • 组管理员:有权限修改组密码和组成员的用户列表,逗号分隔。
  • 组成员:属于该组的用户列表。

组密码在实际使用中频率并不高。一般场景下,用户加入附加组是通过 root 用usermod -G完成,而不是通过组密码。

5. 用户管理的辅助配置文件

5.1 /etc/login.defs:全局密码策略与 UID 范围

/etc/login.defs定义了创建用户和密码策略时的一组默认值。它被useradd、passwd、chage等命令读取。

常见配置项如下:

配置示例:/etc/login.defs 关键片段 PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 PASS_MIN_LEN 5 PASS_WARN_AGE 7 UID_MIN 1000 UID_MAX 60000 SYS_UID_MIN 201 SYS_UID_MAX 999 GID_MIN 1000 GID_MAX 60000 CREATE_HOME yes UMASK 077 USERGROUPS_ENAB yes

这些配置项的含义:

  • PASS_MAX_DAYS:密码最大有效天数,超过后强制修改密码。
  • PASS_MIN_DAYS:两次修改密码之间的最小间隔天数。
  • PASS_MIN_LEN:密码最小长度。
  • PASS_WARN_AGE:密码过期前警告天数。
  • UID_MIN、UID_MAX:普通用户的 UID 范围。
  • SYS_UID_MIN、SYS_UID_MAX:系统用户的 UID 范围。
  • CREATE_HOME:是否默认创建家目录。
  • UMASK:新用户家目录和文件权限掩码,077表示家目录权限为700。
  • USERGROUPS_ENAB:是否在创建用户时自动创建同名主组。

需要注意的是,/etc/login.defs中的配置只是默认值,如果useradd命令显式指定了参数,则命令参数优先于配置文件。

5.2 /etc/default/useradd:useradd 命令默认值

/etc/default/useradd主要被useradd命令读取,用于确定新用户的默认家目录路径、默认登录 Shell、默认主组等。

典型内容:

配置示例:/etc/default/useradd GROUP=100 HOME=/home INACTIVE=-1 EXPIRE= SHELL=/bin/bash SKEL=/etc/skel CREATE_MAIL_SPOOL=yes

字段含义:

  • GROUP=100:默认主组 GID,如果/etc/login.defs设置了USERGROUPS_ENAB yes,通常会自动创建同名组,这里不一定会生效。
  • HOME=/home:用户家目录的父目录。
  • INACTIVE=-1:密码过期后账号宽限天数,-1表示不启用该策略。
  • EXPIRE=:账号失效日期,空表示不设置。
  • SHELL=/bin/bash:默认登录 Shell。
  • SKEL=/etc/skel:创建家目录时的模板目录。
  • CREATE_MAIL_SPOOL=yes:是否创建用户对应的邮件池文件。

5.3 /etc/skel:用户模板目录

/etc/skel是一个模板目录,里面存放着新用户家目录的默认文件。当你执行useradd创建用户时,系统会自动把/etc/skel中的所有文件(包括隐藏文件)复制到新用户的家目录中。

常见的模板文件包括:

  • .bashrc:用户交互式 Shell 配置。
  • .bash_profile:登录 Shell 配置文件。
  • .bash_logout:退出登录时执行的脚本。
  • 其他.vimrc、.zshrc等文件可以根据需要自行添加。

比如你想让所有新用户默认看到一段欢迎信息,可以这样操作:

echo "Welcome to Linux Server" > /etc/skel/welcome.txt

之后再创建的新用户,家目录下就会自动多出welcome.txt。已经存在的用户不会自动获得该文件,需要手动复制。

6. 实战:通过文件变化理解用户管理全过程

理论知识说完之后,我们进入一个实操环节。通过实际操作来观察创建用户时文件的变化,把所有知识点串起来。

6.1 创建用户并观察文件变化

在 root 权限下执行:

useradd -m testuser

-m参数表示创建用户的同时创建家目录。执行后查看相关配置文件:

grep testuser /etc/passwd grep testuser /etc/shadow grep testuser /etc/group

第一次执行时,由于还没有设置密码,你会看到类似输出:

testuser:x:1002:1002::/home/testuser:/bin/bash testuser:!!:20015:0:99999:7:0:19799: testuser:x:1002:

逐行解释:

  • /etc/passwd中多了一行,UID 是 1002,GID 是 1002,家目录是/home/testuser,登录 Shell 是/bin/bash。
  • /etc/shadow中密码字段是!!,表示用户尚未设置密码,不能登录。
  • /etc/group中新增一个组testuser,GID 为 1002。这是因为默认配置USERGROUPS_ENAB yes,系统自动创建了与用户名同名的组。

再查看家目录内容:

ls -la /home/testuser

你会看到从/etc/skel复制过来的隐藏文件,例如.bashrc、.bash_profile、.bash_logout。

6.2 设置密码并观察 shadow 变化

给用户设置密码:

passwd testuser

设置完成后再次查看 shadow 文件:

grep testuser /etc/shadow

此时密码字段从!!变成了长串密文,类似:

testuser:$6$8gLxR4zI$fL0...:20015:0:99999:7:0:19799:

说明密码已经生效。此时可以用su切换用户验证:

su - testuser

6.3 修改用户属性并观察文件变化

把 testuser 的登录 Shell 改为/sbin/nologin:

usermod -s /sbin/nologin testuser

再次查看:

grep testuser /etc/passwd

输出中的最后一个字段会从/bin/bash变成/sbin/nologin。设置为/sbin/nologin后,该用户无法通过 SSH 或终端直接登录系统,但可以作为服务账户运行程序。

把用户加入附加组 wheel:

usermod -aG wheel testuser

查看用户能力:

groups testuser id testuser

输出示例:

testuser : testuser wheel uid=1002(testuser) gid=1002(testuser) groups=1002(testuser),10(wheel)

这里的10(wheel)就是附加组,testuser是主组。

6.4 设置密码过期策略

查看用户密码策略:

chage -l testuser

输出示例:

最近一次密码修改时间 :2月 04, 2025 密码过期时间 :从不 密码失效时间 :从不 帐户过期时间 :从不 两次改变密码之间相隔的最小天数 :0 两次改变密码之间相隔的最大天数 :99999 在密码过期之前警告的天数 :7

设置密码 90 天后过期,提前 7 天警告:

chage -M 90 -W 7 testuser

再次查看 shadow 文件对应行:

testuser:$6$...:20015:0:90:7:0:19799:

字段变化非常直观:最大有效天数从 99999 变成了 90,警告天数从 7 保持为 7。

7. 高频面试题与回答思路

这一部分整理一些面试场景中常见的问题。面试官不一定等你背答案,更想看你是否理解原因和场景。

7.1 为什么 /etc/passwd 中的密码字段是 x 而不是密文?

这是最基础的问题,回答思路有三点:

  1. /etc/passwd需要被所有用户读取,因为很多程序需要通过它获取用户名、UID 和家目录信息。
  2. 如果将密码密文存放在其中,相当于把密文暴露给所有用户,增加被暴力破解的风险。
  3. 因此系统采用 shadow 机制,将密文转移到仅 root 可读的/etc/shadow文件中,/etc/passwd中的x只是占位符,表示真实密码在 shadow 中。

还可以追问一句:/etc/shadow的权限是怎样的?一般答案是-rw-------,只有 root 用户可读写。

7.2 UID 为 0 的用户为什么危险?

UID 为 0 是超级用户的标志,系统内核判断权限时只看 UID。如果一个普通用户被改成 UID 0,那它就会拥有 root 权限。面试中如果被问到检查系统是否有异常 uid 为 0 的用户,可以执行:

awk -F: '$3==0{print $1}' /etc/passwd

正常情况下输出只有root。如果出现其他用户名,说明存在安全隐患。

7.3 创建用户时 system user 和普通用户有什么区别?

使用useradd -r可以创建系统用户。主要区别:

  • 系统用户 UID 在/etc/login.defs的SYS_UID_MIN到SYS_UID_MAX范围内,普通用户 UID 在UID_MIN到UID_MAX之间。
  • 系统用户通常没有家目录,或家目录不常用。
  • 系统用户默认 Shell 通常是/sbin/nologin,不允许登录。
  • 系统用户用于运行服务进程,例如 nginx、mysql 等。

7.4 如何让一个用户不能登录系统但又保留账户?

有三种常见做法:

  • 将用户 Shell 改为/sbin/nologin:只影响登录,不影响该用户运行已启动的服务。
  • 在/etc/shadow密码字段前加!锁定用户:用户完全无法通过密码认证。
  • 使用usermod --expiredate 1设置账号过期,使账号在过期日之后失效。

一般推荐第一种,因为它保留了服务运行能力,同时禁止交互式登录。

7.5 useradd 和 adduser 有什么区别?

在 Debian/Ubuntu 系列系统中,adduser是一个 Perl 脚本,封装了useradd并增加了交互式流程,如设置密码、填写用户信息。在 RHEL/CentOS 系列系统中,useradd是底层命令,adduser 可能只是 useradd 的链接或并不存在。面试时可以先说清这一点,再说明实际项目更倾向于使用带参数的命令或脚本批量创建。

8. 常见问题与排错思路

8.1 用户无法登录

现象:输入密码后认证失败,或者账号被锁定。

排查顺序:

# 1. 查看用户是否存在 id username # 2. 查看 /etc/shadow 中密码字段是否以 ! 开头 grep username /etc/shadow # 3. 查看用户 Shell 是否为 nologin grep username /etc/passwd # 4. 查看账号是否过期 chage -l username

对应处理方式:

  • 密码字段为!!:设置密码passwd username。
  • 密码已过期:使用chage -M 90 username或强制重新设置密码。
  • Shell 为/sbin/nologin:改用usermod -s /bin/bash username。
  • 账号过期:使用usermod -e "" username取消过期日期。

8.2 用户已存在但家目录丢失

现象:登录后进入/,提示无法切换目录。

排查与恢复:

# 查看家目录路径 grep username /etc/passwd # 创建家目录并复制模板 mkdir /home/username cp -r /etc/skel/. /home/username/ # 修改属主属组和权限 chown -R username:username /home/username chmod 700 /home/username

8.3 删除用户后 UID 被复用

如果你强制删除了用户,但没有删除 UID 对应的文件,之后创建新用户时,系统可能会复用这个 UID,导致新用户继承原来用户文件的属主关系。这在实际生产环境中有安全隐患。

安全删除流程:

# 1. 锁定用户 passwd -l username # 2. 查看用户相关文件 find / -uid 1005 2>/dev/null # 3. 确认后删除用户及家目录 userdel -r username

尽量避免先删用户再发现遗留文件,因为 UID 无法快速找回归属。

8.4 普通用户无法切换到 root

现象:su -提示认证失败。

原因通常是/etc/pam.d/su或/etc/pam.d/su-l中配置了wheel组限制,只有 wheel 组成员可以提权到 root。解决方法:

# 将用户加入 wheel 组 usermod -aG wheel username

也可以检查 Pam 配置,但一般推荐将管理员账号加入 wheel 组而不是直接改 Pam 规则。

9. 最佳实践与工程建议

9.1 不要手动编辑 shadow 文件设置密码

很多新手在用passwd修改密码失败后会尝试直接编辑/etc/shadow写入密文,这是比较危险的操作。如果密文格式错误或者权限不对,会导致用户无法登录。正确做法是使用passwd命令,或者通过脚本批量执行chpasswd。

批量创建用户并设置密码的示例:

for user in dev01 dev02 dev03; do useradd -m -s /bin/bash "$user" echo "$user:Init@123" | chpasswd passwd -e "$user" done

其中passwd -e会让用户下次登录时强制修改密码。

9.2 修改配置文件前先备份

在修改/etc/passwd、/etc/shadow、/etc/group这类系统关键文件前,建议先备份。很多发行版在useradd、usermod等命令内部已经通过 PAM 和 shadow 机制保证原子性,但如果你需要手动改文件,备份就是最基本的保障:

cp /etc/passwd /etc/passwd.bak.$(date +%F) cp /etc/shadow /etc/shadow.bak.$(date +%F) cp /etc/group /etc/group.bak.$(date +%F)

9.3 合理规划 UID 范围

生产环境中,建议为不同业务或不同应用系统划分 UID 范围,比如运维账号1000-1999,应用账号2000-2999,服务账号使用系统用户范围。这样可以减少 UID 冲突,也方便审计。创建用户时显式指定 UID:

useradd -m -u 2501 -s /bin/bash appuser

9.4 定期审计用户账户

定期检查系统中是否存在异常 UID 为 0 的用户、空密码用户、近期不活跃的用户:

# 查找 UID 为 0 的用户 awk -F: '$3==0{print $1}' /etc/passwd # 查找空密码用户 awk -F: '($2==""){print $1}' /etc/shadow # 查找密码永不过期的用户 awk -F: '$5==99999{print $1}' /etc/shadow

将这些命令写入定时任务或自动化巡检脚本中,是运维工作中比较常见的安全手段。

9.5 理解 PAM 与配置文件的边界

配置文件定义了用户和密码的数据,但真正的认证逻辑由 PAM(可插拔认证模块)控制。比如你设置了/etc/login.defs中的PASS_MIN_LEN,但程序如果绕过了 PAM 检查,这个最小长度未必会强制生效。理解这个边界,能帮助你在排查认证类问题时看得更准。

10. 总结与下一步学习路径

掌握 Linux 用户管理配置文件,本质上是理解了系统账户体系的底层数据结构。通过这篇文章,你应该已经能够做到:

  1. 说出/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow四个文件的字段含义。
  2. 解释为什么密码字段存放位置从/etc/passwd迁移到/etc/shadow。
  3. 使用useradd、usermod、passwd、chage命令后,知道底层哪些文件发生了变化。
  4. 快速排查用户无法登录、账号过期、家目录丢失等常见问题。

下一步可以继续学习的内容包括:用户切换命令(su、sudo)的配置与区别、PAM 认证机制、文件权限体系中 ACL 和特殊权限位(如 SUID、SGID)的应用。如果你在实际配置中遇到某个字段不太确定,建议多用man shadow、man passwd、man login.defs查阅对应手册,这些资料比任何博客都更权威。

最后还是那句话:Linux 用户管理命令固然重要,但配置文件才是真正的幕后逻辑。多动手创建几个用户,对照文件变化去看,很快就能把这些知识点内化。如果这篇教程对你有帮助,可以收藏备用,后续遇到用户管理相关面试题时再翻一翻,思路会清晰很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询