Linux 用户密码管理指南:passwd 命令与系统安全策略全解
发布时间:2026/10/8 8:57:47 作者:尧图编辑部 阅读量:1,286

1. 为什么一个“改密码”的命令值得专门写一篇说实话我刚接触 Linux 那会儿一直觉得passwd是个“没啥技术含量”的命令——不就是改个密码吗直到有一次在生产环境上因为对 passwd 的某些机制理解不到位差点把一台承载线上业务的服务器搞到无法登录那次之后我才开始重新审视这个命令。后来在带新人的过程中我发现几乎所有人都低估了它的深度passwd 不只是“改密码”三个字它的背后牵扯到用户认证体系、密码策略、安全审计、系统权限模型等一系列核心机制。这篇文章我想把多年实操中积累的东西完整讲一遍不光讲命令怎么敲更重要的是讲清楚它为什么这么设计、实际运维中会遇到哪些坑以及怎么用好它来保障系统安全。这篇文章适合这几类人看刚入坑 Linux 的初学者想系统搞懂用户管理工作中经常要处理账号权限的运维工程师还有那些被等保、合规要求追着跑需要落实密码策略的朋友。我会从最基础的用法讲起逐步深入到影子密码、密码老化、安全日志这些进阶话题确保小白跟得上老手也能有收获。先说一个核心认知passwd 命令的本质是修改/etc/shadow文件中的密码哈希和相关属性。明白这一点你就知道它不是一个孤立命令而是整个 PAM可插拔认证模块认证体系中的一个环节。所以我会先用一节把 Linux 密码存储机制讲透——这是理解后面所有操作的基础。2. 先搞懂 Linux 到底把密码存在哪2.1 不只是 /etc/passwd/etc/shadow 才是核心早期的 Unix 系统把用户密码哈希直接存在/etc/passwd文件里但这个文件是全局可读的意味着任何用户都能拿到密码哈希然后离线跑字典攻击。后来引入了影子密码机制把密码哈希挪到了只有 root 能读的/etc/shadow文件/etc/passwd中的密码字段统一替换为x占位符。在/etc/shadow文件中每一行代表一个用户由九个冒号分隔的字段组成。以 root 用户为例root:$6$saltingvalue$veryLongHashString:19000:0:99999:7:::第1字段用户名第2字段加密后的密码哈希。如果为!或*表示该账户已被锁定无法用密码登录第3字段最后一次修改密码的日期自1970年1月1日起的天数第4字段两次修改密码之间的最小间隔天数0表示随时可改第5字段密码有效期的最长天数99999表示永不过期第6字段密码过期前的警告天数第7字段密码过期后的宽限天数超过该天数仍未改密账户将被禁用第8字段账户失效日期第9字段保留字段从攻击面的角度看shadow 文件权限通常是-rw-------只有 root 可读写。日常运维中我偶尔会看到有人把权限改松这基本等于给攻击者送分——只要拿到 shadow 文件配合 John the Ripper 或 hashcat离线破解只是时间问题。2.2 密码哈希算法的演进从 MD5 到 yescrypt我随机翻几台机器的 shadow 文件哈希字段前缀不同代表用了不同的哈希算法前缀算法说明$1$MD5老古董已被破解必须淘汰$2y$bcrypt常见于 BSD 系有 72 字节输入限制$5$SHA-256相对安全但仍建议升级$6$SHA-512目前最常见的默认算法$y$yescrypt新一代算法部分新版系统默认使用这个前缀直接决定了密码哈希的破解难度。我曾在一次内部安全演练中做过对比8 位纯小写字母密码MD5 哈希在 GPU 集群上跑不到两小时全出SHA-512 需要两天左右yescrypt 的运算时长能达到 SHA-512 的数十倍。现代 Linux 发行版如 Debian 12、Ubuntu 23.04已经逐步把默认算法切到 yescrypt原因就在这儿。这里要纠正一个常见的认知误区加密和哈希不是一回事。密码存储用的是单向哈希也就是从密码算出哈希很容易但从哈希反推原始密码在计算上不可行。这个设计保证了即使数据库泄露攻击者也只能对着哈希列表猜密码而不是直接拿到明文。3. passwd 命令完整语法与常用用法3.1 基础语法与权限模型passwd [选项] [用户名]不带任何参数直接执行passwd修改的是当前登录用户的密码。修改其他用户的密码需要 root 权限。这个权限模型非常值得细品普通用户修改自己密码时系统要求先输入旧密码验证身份而 root 修改任何用户密码时直接设置新密码不需要知道旧密码。实际运维场景里root 重置用户密码是最常见的操作之一比如员工离职交接、用户忘记密码、账号被锁需要恢复。但也正因为 root 不需要旧密码就能改这也是一条敏感的权限路径建议通过堡垒机操作并留审计日志。3.2 快速上手增删改查的完整闭环我平时新建用户后第一步就是设置密码。完整的闭环是这样的# 创建用户同时创建家目录和指定 shell useradd -m -s /bin/bash zhangsan # 设置或修改密码 passwd zhangsan执行后系统会交互式提示输入两次新密码密码不回显。这里有个小细节第一次出现passwd: password updated successfully时密码策略没生效可以直接用弱密码如果你在/etc/login.defs或 PAM 配置中启用了pam_pwquality弱密码会被当场拒绝并提示长度、复杂度要求。删除用户时最好一并处理密码相关数据# 锁定用户密码而不是直接删 shadow 条目 passwd -l zhangsan # 彻底删除用户及其家目录 userdel -r zhangsan这里我特意强调锁定而非删除。实际故障场景中我遇到过删掉用户后才发现他是某个服务账号程序用它跑着定时任务结果服务直接起不来。遇到这种情况用passwd -l先冻结账号等确认无影响后再做清理更稳妥。3.3 常用选项详解选项作用我的使用建议-l锁定账户在哈希前加!前缀临时冻结账号比删除安全得多-u解锁账户移除!前缀解封被误锁的账号时用-d删除密码账户变为无密码危险操作仅限特殊场景用完立刻设回-e强制用户下次登录时改密新账号初始化时强烈推荐-n设置最短修改间隔防止用户频繁改密绕过策略-x设置最长有效期等保合规必配-w设置过期告警天数提醒用户提前改密-i设置账号非活动天数过期后仍不改账号锁定-S查看密码状态排查账号问题第一利器举个例子查看某用户密码状态# passwd -S zhangsan zhangsan P 07/09/2024 0 99999 7 -1逐字段解释P表示有有效密码L表示锁定NP表示无密码07/09/2024是上次改密日期0是最小修改间隔99999是最大有效期永不过期7是告警天数-1表示账号不会因过期而禁用。这个输出看起来不起眼但排查用户突然登录不上时它比看日志快多了。4. 进阶操作密码老化与安全策略配置4.1 用 passwd 实现密码定期更换等保 2.0 要求通常包含密码有效期、复杂度、会话超时等条款。我在配置服务器时经常用 passwd 直接设置密码老化参数# 设置密码 90 天过期提前 7 天告警过期 3 天后锁定 passwd -x 90 -w 7 -i 3 zhangsan这三条参数的含义要理解清楚-x 90表示密码在 90 天后视为过期-w 7表示在过期前 7 天开始提醒-i 3表示密码过期后 3 天内不修改账号直接锁定。这个组合是我比较推荐的基线配置——既不至于太苛刻导致用户频繁因忘记密码找你解锁又能满足大多数合规要求。对于新创建的用户我更推荐用chage命令配合-e选项实现首次登录强制改密useradd -m -s /bin/bash lisi echo Temp123 | passwd --stdin lisi chage -d 0 lisichage -d 0把上次改密时间设置为从未用户首次登录时系统会强制要求修改密码。这里有个交互细节强制改密时用户必须输入旧密码然后再设置新密码所以临时初始密码要提前告知用户通过安全的渠道。要注意--stdin这个选项并非所有发行版都支持。RHEL/CentOS 系列默认可用但 Debian 系的 passwd 需要自己编译或通过chpasswd实现相同效果echo Temp123 | chpasswd4.2 通过 /etc/login.defs 设置全局密码策略passwd 命令的行为有一部分受/etc/login.defs参数控制。我梳理一下关键配置项PASS_MAX_DAYS 90 PASS_MIN_DAYS 1 PASS_WARN_AGE 7PASS_MAX_DAYS密码最长使用天数超过后必须修改PASS_MIN_DAYS改密最小间隔防止用户改完立刻改回原密码PASS_WARN_AGE过期前多少天开始警告这个文件设置的是一种默认值新建用户时如果 passwd 命令没指定-x -n -w就套用这里的值。老用户的密码属性不会自动受新配置影响因为它们的 shadow 字段已经写死需要注意这点。4.3 PAM 密码质量模块实战pam_pwquality或pam_cracklib控制密码复杂度。在/etc/pam.d/passwd中加一行配置password required pam_pwquality.so retry3 minlen12 difok3各参数解释retry3用户最多输错 3 次minlen12最小长度 12 位difok3新密码至少要有 3 个字符与旧密码不同我见过不少团队把minlen设成 8这在纯数字场景下根本不够看。等保三级环境下我建议至少 12 位且要求至少包含大写、小写、数字、特殊字符中的三类。如果直接在命令行用非交互方式设置密码PAM 策略默认会严格校验不符合策略的密码会被拒绝。有个问题是某些自动化脚本比如批量初始化服务器用passwd --stdin设置密码会遇到 PAM 校验导致的失败。我的处理方法是把复杂的默认策略放宽放在/etc/login.defs中做基线把复杂度校验只放到交互式登录场景。也可以写一个批量脚本用chpasswd -e传入已经用openssl passwd -6预生成的哈希绕过交互式输入同时保留策略校验。5. 从内核级密码策略配置的完整方案5.1 密码复杂度与反复利用防护除了进程级策略内核级还有一个机制叫 密码哈希内存保护其实是指/proc/sys/kernel/randomize_va_space等内核安全参数但它们更多作用于地址空间随机化和 passwd 本身关系不大。实际运维中真正受内核参数影响的是账户锁定策略。我常配置的/etc/security/faillock.conf如下deny 5 unlock_time 300 even_deny_rootdeny5表示允许连续输错 5 次unlock_time300表示锁定 300 秒后自动解锁。even_deny_root表示 root 用户也受此限制。默认情况 root 是不受限制的这可能带来暴力破解风险但要注意如果机房只有你一个人能访问控制台启用 root 锁定后解锁会比较麻烦。密码防复用不能只靠 PAM 的remember配置因为/etc/security/opasswd默认只记录旧密码用于比对如果用户连续改两次密码就能绕过最近多少次不得重复的限制。把这行加入配置password sufficient pam_unix.so sha512 shadow nullok remember10remember10表示记住最近 10 个密码用户改密时不得复用这 10 个历史密码。但有个坑opasswd 文件只在改密时更新如果用户被锁定后管理员直接passwd -u解锁opasswd 的历史记录不会被清理。这意味着老密码仍然有效的可能性增大我通常会建议在解锁后手动检查/etc/security/opasswd。5.2 shadow 文件中字段的详细解读与手工修改方法虽然平常用 passwd 命令就够了但有时候需要直接手工修改 shadow 文件的某些字段。典型场景比如测试环境想要快速模拟密码过期状态而不想等 90 天。我用一个例子说明手工修改方法。假设现在日期是 2025 年 1 月 1 日对应的 epoch 天数是 20089如果我想设置用户密码当天立即过期# 先把当前日期换算成天数 echo $(($(date %s) / 86400)) # 将第三个字段改为 20088表示上次改密是昨天 # 这样密码已经在过期状态修改前务必先备份cp /etc/shadow /etc/shadow.bak。修改后可以用passwd -S验证效果。还有更简单的方式chage -d 0 username效果相同而且不会触碰文件权限问题。5.3 无交互式修改密码的多种方法批量运维场景下交互式输密码不现实。整理一下无交互设置密码的所有方式# 方法1echo passwd --stdin仅 RedHat 系列 echo NewPass123 | passwd --stdin zhangsan # 方法2chpasswd通用性较好 echo zhangsan:NewPass123 | chpasswd # 方法3直接生成哈希写入最稳妥不经过 PAM echo zhangsan:$6$salt$hash:19000:0:99999:7::: /etc/shadow方法3有点黑客味一般不推荐日常使用。我最常用的是方法2因为chpasswd在所有主流发行版上都有而且可以配合-c MD5或-c SHA512指定算法。如果密码中包含特殊字符比如$一定要用单引号包裹整个字符串防止 shell 展开变量。我曾遇到一个真实的坑用双引号传递密码里面含$2y$10$...这样的 bcrypt 哈希shell 把它当变量展开结果写进 shadow 的是一串空值用户彻底登录不了。排查了半天才发现是引号问题。所以脚本里凡是涉及密码的统一用单引号或者干脆从文件读取不直接内联在命令行。6. 故障排查用户登录失败相关的典型案例6.1 状态异常账号未锁定但密码无法登录这类问题经常出现在/etc/shadow的哈希格式与系统配置不匹配。比如某服务器从 CentOS 6 迁移到 CentOS 7登录时提示密码错误排查过程如下# 第一步查看密码状态 passwd -S username # 第二步检查 shadow 文件中的哈希前缀 grep username /etc/shadow # 第三步确认系统当前使用的哈希算法 authconfig --test | grep hashing定位到哈希前缀是$1$MD5而系统当前配置为 SHA-512 时直接把密码哈希更新一下就行用 root 重新passwd username。其实一般情况下 passwd 命令会自动匹配算法这种故障更常见于系统迁移或手工修改 shadow 文件。6.2 密码被锁定后的恢复操作用户连续输错密码导致的临时锁定恢复方式如下# 清除 /run/faillock/username 下的计数文件 rm -f /run/faillock/username # 或者使用 pam_faillock 的 reset 命令 pam_faillock --user username --reset对于管理员主动passwd -l锁定的账号使用passwd -u解锁。但这里有一个重要细节需要注意如果passwd -l是在账号密码哈希为!状态时执行的直接passwd -u不会真正解锁因为 shadow 字段中的!前缀还在。需要先用passwd重新设置密码再解锁。这属于很隐蔽的坑官方文档几乎没有提示。6.3 密码过期导致无法登录的处理用户登录时提示 password has expired 但密码输入正确说明 shadow 的第 5 字段到期了。处理方式要看业务场景# 如果这是一个应该长期存在的账号立即重置有效期 passwd -x 90 -w 7 -i 3 username # 如果用户暂无改密条件先把过期状态清掉 passwd -x 99999 username在自动化运维场景中类似的密码过期问题会用 cron 定时任务提前检查例如每个月扫描一次并邮件提醒即将过期用户。我写过一个简单的扫描脚本核心逻辑就是读取/etc/shadow解析第三字段和第五字段计算剩余天数小于 14 天时就发送告警。这里要提醒一句不要在脚本里硬编码密码用系统自带的sendmail或集成企业邮箱网关更安全。6.4 忘记 root 密码的恢复流程这是最经典的应急场景。单用户模式rd.break或init/bin/bash下重置 root 密码核心流程是# 进入单用户模式以 GRUB 为例 # 在引导菜单按 e找到 linux 行末尾添加 rd.break # 按 CtrlX 启动 # 重新挂载根文件系统 mount -o remount,rw /sysroot chroot /sysroot # 重置密码 passwd root # 关键步骤让 SELinux 重新标记 touch /.autorelabel # 退出并重启 exit reboot这个流程中touch /.autorelabel非常关键如果跳过重启后可能因为 SELinux 上下文错误导致无法登录。我遇到过不止一次密码改好了重启后系统直接进入紧急模式就是因为忽略了这一步。7. passwd 相关安全审计与日志分析7.1 日志文件中留下的痕迹passwd 操作在系统日志中会留下痕迹熟练掌握日志检索对排查安全事件至关重要/var/log/secureRedHat 系或/var/log/auth.logDebian 系记录所有认证行为包括 passwd 执行和 sudo 记录/var/log/faillog记录账户登录失败记录/var/log/tallylog是 PAM tally 的二进制日志实际安全排查中的常用命令# 查看最近所有 passwd 相关操作 grep -i passwd /var/log/secure # 查看 sudo 方式执行的 passwd grep sudo.*passwd /var/log/secure # 查看错误密码尝试 grep authentication failure /var/log/secure # 查看用户锁定记录 grep lock /var/log/secure7.2 审计用户密码变更事件使用auditd做更细粒度的审计# 添加审计规则监控 passwd 命令和 shadow 文件 auditctl -a always,exit -F archb64 -S execve -F exe/usr/bin/passwd -k passwd_change auditctl -w /etc/shadow -p wa -k shadow_watch然后通过ausearch -k passwd_change查询审计记录。生产环境建议同时把审计日志转发到集中日志平台如 ELK、Wazuh否则攻击者一旦拿到 root 权限删掉本地日志就什么也查不到了。等保测评时审计这一项经常被卡住。团队里统一的做法把审计规则写成/etc/audit/rules.d/passwd.rules每次重启后自动加载同时在/etc/audit/auditd.conf中配置max_log_file和num_logs防止日志文件写满导致服务异常。7.3 密码策略定期自检清单我每隔一个季度会对所有服务器做一次自检顺手整理成清单检查 shadow 文件权限是否为 600属主属组是否 root检查/etc/passwd中是否有 UID 为 0 的非 root 账号用passwd -S遍历所有账号找出密码永不过期或未设置告警的高权限账号检查口令历史记录机制是否开启/etc/pam.d/passwd中的remember参数检查是否有多个账号使用相同密码这个需要借助第三方工具比如cracklib-check这个清单中遍历账号的脚本大致长这样for user in $(cut -d: -f1 /etc/passwd); do state$(passwd -S $user 2/dev/null | awk {print $2}) if [ $state P ]; then maxdays$(passwd -S $user | awk {print $5}) if [ $maxdays 99999 ]; then echo $user 密码永不过期 fi fi done8. 实用技巧与经验补充8.1 批量创建用户并设置随机密码服务器扩容时批量创建账号的需求不少。我一般写这样一个脚本核心思路是生成随机密码并加密写入#!/bin/bash # 批量创建用户输出初始密码到单独文件 while read username; do useradd -m -s /bin/bash $username password$(openssl rand -base64 12) echo $username:$password | chpasswd chage -d 0 $username echo $username $password /root/initial_passwords.txt done user_list.txt chmod 600 /root/initial_passwords.txtchage -d 0是这串命令的灵魂用户第一次登录就会被迫改掉临时密码。initial_passwords.txt只在创建时生成一次交接给管理员后建议删除或转存加密存储不留在服务器明文存放。8.2 锁定的正确姿势passwd -l 还是 usermod -L严格说passwd -l和usermod -L最终效果相同——都在 shadow 哈希前加!前缀。但两者在脚本可读性上存在差异。我在自动化脚本里统一用passwd -l因为语义更清晰。另外有时需要给账户添加一个安全备注例如标记离职我习惯用usermod -c 离职 2025-01-15 username方便后续审计追溯。8.3 passwd 在容器环境中的注意事项Docker 容器里执行passwd很多时候会报错因为基础镜像通常没有安装passwd包或者 PAM 配置不全。我在构建镜像时一般这样做RUN apt-get update apt-get install -y passwd更推荐的方案是容器内不设置密码认证而靠 SSH 公钥或身份代理。如果一定要密码认证模板镜像中预置好/etc/shadow的哈希比进入容器后再执行 passwd 更可控。此外容器内的 UID 映射机制可能导致 shadow 文件归属不对容器中 root 的 UID 是 0宿主上的普通用户可能是 1000这本身不影响容器内 passwd 执行但如果你把宿主目录挂载进容器并改密码注意是否会把宿主文件权限改乱了。8.4 实操心得遇到用户“密码正确但登录不上”的排查顺序多年的故障处理经验让我养成了一套固定排查顺序按这个顺序走绝大多数问题都能在十分钟内定位passwd -S username查状态是 P、L、NP 中的哪一种grep username /etc/shadow看哈希前缀和字段值是否正常journalctl -u sshd或tail /var/log/secure看具体认证失败原因检查/etc/ssh/sshd_config中的PasswordAuthentication是否被设为 no检查faillock --user username看是否触发锁定最后看 PAM 配置/etc/pam.d/sshd是否有异常规则比如被安全加固工具改过这个顺序的核心逻辑是先看密码本身有没有问题再看认证通道有没有问题最后看策略层有没有拦截。很多新手一上来就翻 PAM 配置结果密码本身早就过期了白折腾半天。最后分享两个踩坑较多的细节第一passwd -d username这个删除密码的操作我强烈建议不是迫不得已不要用。无密码账户在 SSH 登录时默认会被拒绝但在本地控制台或某些 PAM 配置不严的场景下可能放行等于开了一个不设防的后门。如果确实要临时禁用密码登录用passwd -l锁定账号而不是-d删除密码。第二chage -M和passwd -x本质是同一个功能但chage能输出更友好的信息passwd更适合在脚本中快速设置。两者按场景选择即可。另外改完策略后记得做一次验证登录不要改了配置就以为万事大吉因为 PAM 配置加载有时会滞后新配置也可能不生效。我用 passwd 命令的频率远高于其他命令它看似简单却在用户管理、安全防护、合规审计中扮演着不可替代的角色。扎实掌握它受益的不仅是你的日常工作效率更是在关键时刻避免一次重大安全事故。希望这篇文章能帮你把 passwd 从会用提升到用好的层面。