Linux passwd命令全解析:账户密码管理与故障排查 我自己用 passwd 这个命令的时间算下来超过十年了。在 Linux 日常管理里它大概是出镜率最高、也最容易被低估的一个命令。很多人以为它就是“改个密码”但实际上 passwd 背后牵动的是一整套账户与密码管理机制/etc/shadow 里的密码哈希、账号锁定标志、密码过期策略全都跟它有关。这篇就把 passwd 命令从用法、原理到常见坑位完整过一遍适合刚入门 Linux 的同学也适合写脚本、做运维的朋友拿来当排查手册。我为什么想写这个主题因为工作里见太多人栽在 passwd 的细节上。有人批量建号后用户第一次登录就被要求改密不知道怎么配置有人发现账户被锁定想解开结果 passwd -u 解完还是登录不了还有人把密码直接写在命令行里当天就被同事提醒“你密码全公司都看得见”。这些都不是大故障但每一个都够折腾一阵。所以这篇我按“先讲原理、再讲实操、最后讲排查”的顺序来写。1. passwd 到底改的是什么shadow 文件与密码哈希机制要真正会用 passwd第一步不是记参数而是搞清楚它到底在哪个文件里动刀子。很多人对用户管理的理解停留在 useradd 建用户、passwd 改密码但其实用户信息存在哪、密码存在哪、为什么普通用户也能改自己的密码这三件事搞明白后面所有坑都能少踩一半。1.1 /etc/passwd 管身份信息/etc/shadow 才是密码的保险柜Linux 里用户信息分两个文件存/etc/passwd 和 /etc/shadow。前者是几乎所有程序都能读的公开文件里面每一行代表一个账户字段用冒号分隔用户名、密码占位符、UID、GID、注释信息、家目录、登录 Shell。这里要强调一点/etc/passwd 第二列的x并不是密码只是一个占位符真正密码哈希全部挪到 /etc/shadow 里了。早期 Unix 系统确实是把密码哈希直接放在 /etc/passwd 里的但后来发现这条路走不通——这个文件需要被各种程序读取等于把密码哈希公开给了所有能登录系统的用户暴力破解的门槛太低。于是才有了 /etc/shadow它的权限通常只有 root 和 shadow 组能读普通用户根本没机会看到别人的哈希。一句话总结/etc/passwd 是用户信息的“名片夹”/etc/shadow 才是真正上锁的“密码保险柜”。1.2 shadow 里密码字段的一串字符到底在说什么再看 /etc/shadow每一行同样用冒号分隔核心字段包括用户名、密码哈希、最后一次修改时间、最短使用天数、最长有效期、警告天数、宽限期、保留字段。密码哈希那一列就是 passwd 命令主要折腾的对象。标准格式长这样$算法id$盐值$真正的哈希比如$6$KxQ9...$fTG...开头的$6$说明用的是 SHA-512。把这个结构拆开后很多命令输出就好解释了。常见算法标识对应关系如下算法标识对应算法常见场景$1$MD5老版本系统通常不建议新用$5$SHA-256部分旧发行版使用$6$SHA-512目前最常见多数发行版默认$y$yescryptRHEL9 及更新系统的默认选项$2b$bcrypt部分系统或应用使用为什么不用明文或者可逆加密因为密码一旦可逆文件泄露等于全盘送出。哈希是单向的你只能拿候选密码一次次计算哈希然后比对。盐值则是用来对抗彩虹表攻击的同一密码在不同用户身上算出来的哈希也不一样。所以以后看到两个用户 shadow 里的哈希不同别急着断定密码不同有可能只是盐值不同。这是很多人容易误解的一个点。1.3 为什么普通用户也能用 passwd 改自己的密码回到 passwd 命令本身。你可以执行ls -l /usr/bin/passwd看一眼会发现它的权限位是-rwsr-xr-x中间那个s就是 setuid 位。普通用户执行 passwd 时进程会以文件属主 root 的身份运行于是就有权限去写只有 root 能写的 /etc/shadow改完自己的密码后进程退出root 权限随之释放。这其实是经典面试考点为什么 /usr/bin/passwd 要带 setuid 位答案就是它需要在不给普通用户完整 root 权限的前提下让用户能修改自己的密码哈希。当然setuid 程序一直是安全攻击面历史上 passwd 也出过缓冲区溢出一类的问题所以现在内核和发行版在这个位置的防护都非常谨慎。2. 五个高频实战场景从自己改密码到批量脚本重置原理讲完进入实战。下面这几种场景覆盖了我日常工作中 90% 以上的 passwd 用法也是在面试、考证里最常出现的操作命令。2.1 普通用户修改自己的密码交互流程别跳过终端直接敲passwd不带任何参数就是修改当前登录用户的密码。系统会先要求输入原密码再让你输入两次新密码。这里有两个细节容易被忽略。第一为什么要先验证原密码如果你以普通用户身份执行 passwd系统必须确认操作者确实是账号本人这是最基本的身份校验防止别人趁你离开终端时把你的密码改掉。第二新密码输入时终端不会回显也不显示输入位数很多新手以为键盘坏了其实这是密码输入的正常设计。输完两次新密码一致命令返回 success/etc/shadow 里的哈希就更新了。如果你设的密码太简单比如六个 1PAM 策略会弹一个BAD PASSWORD警告。在多数发行版上这仅仅是个警告密码依然会设置成功但在启用了严格 pwquality 策略的系统上会直接拒绝错误信息一般是“密码未通过字典检查”。这个后面排查部分再细讲。2.2 root 强制重置指定用户密码别忘了强制过期root 管理员给其他用户重置密码的语法是passwd 用户名。root 改别人密码不会要求输入旧密码设置完成后直接覆盖 shadow 里的哈希。这个场景在运维中很常见用户忘记密码、新人入职分配临时密码、离职交接账号。我平时给测试部门的同事重置完密码一般还会顺手敲一句chage -d 0 用户名让他们下次登录时强制修改密码初始密码只在工单里通知一次。别省这一步不然初始密码会被一直沿用时间长了部门里人人都知道这个密码是什么账号安全就等于筛子。这个做法原理上等价于 passwd -e后面章节会展开。2.3 脚本里非交互式改密码--stdin 和 chpasswd 的取舍脚本里批量重置密码是最容易写错的地方。很多人看到网上教程用echo password | passwd --stdin user这个写法在 RHEL/CentOS/Fedora 这一系是能跑的因为 passwd 自带 --stdin 参数echo Tmp2026 | passwd --stdin alice但同样的命令拿到 Debian/Ubuntu 上会直接报错提示 unrecognized option因为 Debian 系的 passwd 默认不支持这个选项。Debian 系更通用的方案是 chpasswdecho alice:Tmp2026 | chpasswdchpasswd 专门为批量更新密码设计可以一次喂多行用户名:密码数据。所以我的习惯是跨发行版环境一律用 chpasswd少给自己挖坑。不管是 --stdin 还是 chpasswd明文密码出现在命令行里都有泄露风险。echo 密码这句话会进 shell 历史如果你是在共享终端或录屏的服务器上操作等于把密码当众念了一遍。更稳的做法是用变量read -s -p 输入新密码: NEWPASS echo alice:$NEWPASS | chpasswd unset NEWPASS让密码只存在于内存变量里中转之后立即清除。如果非要在一次性脚本里硬编码记得把脚本文件权限设成 600并且用完后删除。2.4 用 passwd -S 快速判断账户状态P、L、NP 的含义判断一个账户能不能正常登录比改密码更常用的命令是passwd -S 用户名。比如输出alice P 08/10/2026 0 90 7 5第一个字段是用户名第二个字母就是账号密码状态后面跟的是上次修改日期、最短天数、最长天数、警告天数、宽限天数。看一眼这一列账户当前能不能登录就心里有数了。状态标识含义处理建议P密码可用账户正常无需处理L密码被锁定用 passwd -u 解锁NP无密码shadow 密码字段为空补一个密码或锁定账户如果状态是 L直接passwd -u解锁就能恢复如果是 NP说明 shadow 里密码字段是空的这个账户已经处于无密码状态相当危险正常应该补一个密码或直接锁定。root 可以用passwd -a查看所有账户的状态用于定期巡检。3. 账号锁定、解锁与密码生命周期管理账号管理里比改密码更让人头疼的是锁账号和密码过期。我处理过不止一次“用户突然登不上服务器”的工单排查到最后都是 passwd 相关参数被之前的同事误配。这里单独开一章讲清楚。3.1 锁定和解锁账号passwd -l / -u 的内部机制passwd -l 用户名用来锁定账号本质是在 /etc/shadow 的密码哈希前面加一个感叹号!。别小看这个字符它会让整段哈希永久失去匹配能力无论输什么密码都验证失败。对应的解锁是passwd -u 用户名会把开头的!移除恢复原哈希。这里有个真实踩过的坑如果之前连续的锁定操作产生了!!两个感叹号passwd -u 只会移除一个剩下的!还在账户依然处于锁定状态。所以解锁完记得回头用passwd -S看一眼状态确认从 L 变回 P 再收工。还要注意区分两种锁定passwd -l 是改 shadow 哈希属于硬锁定而有些系统配置了 pam_faillock 登录失败锁定那是把失败记录写在 /var/run/faillock 下不会动 shadow。这种情况下 passwd -u 根本解不了必须用faillock --reset来清。有一次我远程实验环境里故意输错 root 密码三次被锁折腾半天才意识到要清 faillock教训深刻。另外远程会话里锁定 root 要极度谨慎锁完直接退出的话你就把自己关在门外了。3.2 强制用户下次登录改密passwd -e 的正确用法passwd -e 用户名又叫强制密码过期效果是让 shadow 里“最后一次修改时间”字段变成 0。用户下一次登录时系统发现密码已经“超期”太久会强制要求先设置新密码再进入 shell。它和chage -d 0 用户名完全等价。我在创建账号、重置密码后的固定套路就是这样先给一个临时密码再passwd -e保证用户第一次登录就把密码换掉。这样即使临时密码在传输过程中泄露没过多久也作废了。新员工入职时我还会在邮件里明确写“第一次登录必须改密码”有效减少初始密码被长期沿用的问题。3.3 密码老化参数最短天数、最长天数、警告期与宽限期除了一次性强制过期更多场景需要给密码设一个生命周期。passwd 相关的几个参数分别是-n最短使用天数密码设置后多久内不允许再次修改-x最长有效期密码多少天后过期-w过期前警告天数提前多少天提醒用户-i到期后宽限天数过期后还能登录多少天比如要求密码 90 天必须换一次提前 7 天提醒到期后宽限 5 天还能登录passwd -n 0 -x 90 -w 7 -i 5 alice其中-n 0意思是密码可以立即修改。这条写完之后可以用chage -l alice查看当前策略能看到 Maximum age、Warning 这些行。顺便提一句这组参数最终是否生效还取决于 PAM 配置。比如有的系统 pam_unix 里没开密码过期检查那即使到期了也不会自动锁只是登录时提示警告。实际项目里最好把系统自带的密码策略告警也接上等用户被卡在外面才去处理就很被动了。4. 常见故障排查与实操经验最后这部分是真正的排查实录。下面几种情况都是我在生产环境真遇到过的分别带上原因和处置方式建议收藏起来当速查表。4.1 忘记 root 密码后的恢复思路自己的实验机或者拥有物理机/云控制台权限的机器root 密码忘了不用重装系统。最常用的思路是重启时进 GRUB在要启动的内核行末尾追加参数进入单用户或紧急模式追加single进单用户或追加rd.break进入 initramfs 的 shell也可以用init/bin/bash绕过 systemd。进入 shell 后先以 rw 方式重新挂载根分区然后直接passwd root重置SELinux 环境下记得touch /.autorelabel避免文件上下文写错导致启动异常。云服务器一般不需要这么折腾控制台基本都提供“重置密码”入口原理类似都是离线改 shadow。这套操作我只建议在自己管理和授权的机器上用生产环境先走变更流程和备份别半夜手痒直接重启。4.2 改密码报错排障从 PAM 策略到 shadow 被锁改密码最常见的报错是Authentication token manipulation error原因挺多我遇到的典型情况有两类。第一类是 /etc/shadow 被chattr i加了不可修改属性此时即使 root 也照样改不了先lsattr /etc/shadow确认再chattr -i /etc/shadow解除后重试。第二类是根分区或 /var 分区满了passwd 写新哈希时落不了盘df -h看一眼就明白。如果是普通用户遇到类似You may not view or modify password information for username的提示那就是权限不足老老实实切 root 或让管理员处理。另外还有两个容易被忽略的场景“用户密码明明刚改过却提示密码已使用”说明系统开了密码历史记录用户密码过期后登录提示“密码已过期请更改”但 ssh 终端里改密一直失败那大概率是 PAM 里 password 模块链路有问题。下面做个速查表错误现象可能原因处理方式密码未通过字典检查pwquality 复杂度策略过严查看 /etc/security/pwquality.conf调整 minlen 等参数Authentication token manipulation errorshadow 被 chattr 锁定或磁盘满lsattr、df -h 排查普通用户提示无权修改非本人账户或权限不足用 root 执行或检查 sudo 配置登录提示密码过期但改密失败PAM password 链路配置错误检查 /etc/pam.d/common-password 或 system-auth账户锁定后 passwd -u 无效pam_faillock 软锁定faillock --reset 清除记录4.3 批量创建用户时密码设置的稳妥姿势批量创建用户的场景里passwd 一般不会单独用而是 useradd 和 chpasswd 搭配。我常用的做法for user in alice bob carol; do useradd -m -s /bin/bash $user echo ${user}:Tmp2026! | chpasswd chage -d 0 $user done先建用户再写入密码最后把密码设为过期。这样用户第一次登录就必须改密码临时密码只过渡一次。有几个细节值得说初始密码里尽量带大小写、数字、特殊符号免得和系统密码复杂度策略正面冲突脚本中明文密码要谨慎脚本文件本身要设置 600 权限跑完顺手删除。如果是大规模导用户可以把用户名:密码的清单做成文件chpasswd userlist一次性处理效率更高也更可控。4.4 顺带盘一下 passwd 相关的几个面试考点最后盘点几个面试常问点。第一为什么 /usr/bin/passwd 带 setuid 位因为普通用户要以 root 身份更新 shadow又不能给完整 root 权限。第二shadow 里密码哈希前的感叹号表示什么表示该账户被锁定。第三怎么让用户下次登录强制改密passwd -e 或 chage -d 0。第四passwd -S 输出 P/L/NP 分别代表什么可用的密码、被锁定、无密码。第五为什么不能在命令行直接带密码shell history、ps 瞬时参数、日志记录都可能泄露。这些都是很基础的题但能把原理讲明白的人不多。顺带一提现在不少单位面试会考“如何批量给已有用户设置随机密码”这个场景用 chpasswd 生成随机串再导入比逐个交互式 passwd 靠谱得多。我这些年用 passwd 踩过的坑最有代表性的有两个一是给 root 做了锁定后直接退出了远程会话结果把自己关在门外最后只能走控制台恢复二是改了密码却忘了在定时任务或服务配置里更新部署账号的密码导致半夜任务全线失败被叫起来。现在我的习惯是所有涉及账户密码的操作前后都先备份 shadow 文件或者至少先passwd -S看一眼状态所有脚本里的明文密码一律用变量配合 read -s 来传并且跑完清理历史。这个命令虽然小但连接着整个账户体系的完整性值得每个 Linux 使用者认真对待。如果你在实操中遇到这篇文章里没提到的报错建议把现场输出贴出来一起讨论。排查这类问题最忌讳只盯 passwd 本身把 PAM、权限、磁盘、文件属性都过一遍基本都能找到答案。