
我先说个真实场景半夜两点机房电话响了——一台RHEL服务器被人改了密码或者干脆过期了业务起不来客户盯着你而你连root都登不进去。这种时候你脑子里唯一想的就是怎么把密码找回来。其实找回这个词不太准确密码本身是哈希存储的根本找不回来我们能做的是重置。这篇文章就把RHEL上重置密码的几条路一次性讲透从RHEL 6的老做法到RHEL 7/8/9的rd.break方案再到光盘救援模式这个终极大招顺便把密码过期、SELinux拦截这些衍生坑一起处理掉。不管你是刚接手公司服务器的运维新手还是在自己笔记本上装RHEL做实验的开发者这套东西都值得全文收藏——毕竟密码这玩意谁都有忘的一天。1. 被锁在门外之前先搞清楚密码存哪、怎么锁的1.1 用户的密码到底放在什么地方早期Linux把用户信息和密码全都放在/etc/passwd里但那个文件所有用户都能读密码哈希一旦泄露就是安全隐患。后来引入了影子密码机制真正的密码哈希挪到了/etc/shadow这个文件只有root能读写。记住这条重置密码本质上就是改/etc/shadow里的哈希值方式是用passwd命令重新生成一个哈希再写进去。/etc/shadow里一行就是一个用户的完整密码策略以冒号分隔我们平时用得最多的是前几个字段字段含义实操意义第1列用户名对应/etc/passwd里的登录名第2列密码哈希以$6$开头的是SHA-512算法第3列最近修改时间从1970年1月1日起的天数第4列最小修改间隔距离上次改密码多少天内不允许再改第5列密码最大有效期超期就必须改密码这就是密码过期第6列过期前警告天数快到期时登录会收到警告第7列宽限期过期后还能登录的天数超过则锁定看到第5列你就明白热搜里的密码过期是怎么回事了。很多默认镜像里root密码的有效期设得比较短等你想起来的时候已经过了宽限期密码直接失效。这时候哪怕你输入的密码是对的系统也照样不让你进。这就是为什么后面我要单独讲chage的处理办法。1.2 为什么RHEL重置密码不能只背一套教程网上搜Linux忘记密码会翻出一堆千篇一律的文章十有八九说的是单用户模式重启Linux进GRUB菜单往kernel行后面加个single然后进去直接passwd。这个流程在RHEL 5/6时代确实行但RHEL 7开始整个启动链路换成了GRUB2加systemd原来的init 1那套玩法变了。更麻烦的是SELinux默认Enforcing你改完密码重启后如果SELinux上下文不对系统可能直接卡登录或者各种诡异的权限报错。所以我的建议很简单RHEL 6及以下用单用户模式RHEL 7及以上用rd.break都不行就上救援光盘。接下来三章分别讲这三条路的具体操作和原理你按自己的系统版本来挑。2. 首选方案rd.break断点重置RHEL 7/8/9通用2.1 操作步骤照着敲就行rd.break是dracut框架提供的一个启动调试参数。它的原理是在initramfs阶段的root挂载完成后、系统切换到真正根分区之前暂停一下把你扔进一个临时的shell——这时候的根文件系统还没完全接管你可以对磁盘上的真实系统做任何修改。整个操作流程如下。第一步重启服务器在启动画面出现GRUB菜单时按下E键进入编辑模式。注意时机要快一般开机后两三秒内就得按。第二步找到以linux开头的那一行RHEL 8/9上通常是linux /boot/vmlinuz-...RHEL 7可能是linux16光标移到这一行的末尾追加如下内容rd.break consoletty0不追加consoletty0也可以但有些服务器上不指定的话中断后可能看不到shell提示符追加了更稳妥。第三步按CtrlX或F10引导系统。很快你会看到一个提示符这正是initramfs里的调试shell。此时的真实系统根分区被只读挂载在/sysroot下。第四步重新以读写方式挂载/sysroot并切进去mount -o remount,rw /sysroot chroot /sysroot为什么需要重新挂载原因是这个断点阶段的默认挂载参数是只读的你直接chroot进去发现任何文件都改不了passwd命令会报错。先remount,rw再切换就不会碰这个坑。第五步在chroot环境中执行密码修改passwd root按提示输入两遍新密码就完成了。第六步这一步很多人漏掉——如果你的SELinux是启用的RHEL默认就是需要创建一个标记文件touch /.autorelabel这个文件的含义是告诉系统下次启动时自动重新标记所有文件的安全上下文。因为你绕过正常登录流程改了/etc/shadow这个文件原先的SELinux类型可能不对正常情况下应该是etc_t等如果不重新标记重启后系统可能出现奇怪的问题甚至SELinux拒绝某些服务加载配置。第七步输入exit退出chroot再输入exit退出断点shell系统会继续完成启动流程——注意不是让你直接按电源键重启而是顺着流程走完。启动完成后用新密码登录root。2.2 为什么说rd.break比单用户模式更可靠单用户模式最怕一个东西root密码本身被锁死或者SSH禁止root登录。单用户模式能让你进入系统但很多教程没说清楚——RHEL 7之后如果你在GRUB里只加single而不做其他处理systemd会要求你输入root密码才能进单用户shell。你想想你本来就是因为忘了密码才来重置的进了单用户模式还要密码这不死循环吗rd.break好就好在它绕过了systemd对单用户模式的认证逻辑直接给你一个root权限的调试shell完全不需要输入任何密码。这是它成为RHEL 7及以上系统重置密码首选方案的根本原因。另外还有个细节rd.break适用的内核参数在RHEL 7/8/9上都有效。RHEL 7早期用的可能是rd.break挂在initramfs阶段RHEL 8/9改用了systemctl的调试钩子但rd.break仍然兼容。实测下来RHEL 8.6、9.2都是OK的。2.3 实测中的意外情况SELinux的坑有一个案例让我印象很深。朋友的RHEL 8服务器忘密码我远程指导他走rd.break重置密码改完没做touch /.autorelabel就直接重启了。结果系统起来了root能登录但一跑systemctl restart sshd就报权限错误看/var/log/audit/audit.log里全是SELinux的AVC denied记录。原因就是我前面说的/etc/shadow的安全上下文因为被我们以调试模式修改而变掉了。解决办法倒也简单重新进rd.breakmount -o remount,rw /sysroot然后chroot /sysroot执行restorecon -v /etc/shadow恢复上下文或者干脆创建/.autorelabel让系统全盘重打标签。注意全盘重打标签这步在文件多的服务器上可能耗时几分钟到十几分钟别以为是卡死了。最稳妥的方案还是每次重置完都touch /.autorelabel让它一次性把所有文件的上下文都校正到位。3. 老版本方案RHEL 6及以前的单用户模式3.1 操作步骤如果你手里还有RHEL 6.x的环境这么老的系统其实不建议跑生产了但实验环境或特定行业的老设备里确实还存在单用户模式是重置密码最直接的方式。具体操作如下。开机进入GRUB菜单后按E编辑找到以kernel开头的那一行在行尾追加数字1或者单词single二选一即可效果一样。有些教程让你顺手把rhgb quiet去掉这俩参数只是控制开机画面的不影响进入单用户模式去掉的好处是能看到更详细的启动日志方便确认到底进没进对状态。追加完按B键引导。RHEL 6的启动流程是经典的SysV init内核启动后会直接以单用户模式拉起shell不会像RHEL 7那样要密码。进入shell后执行passwd root改密码然后reboot重启即可。结束之后有个小环节如果你的系统启用了SELinux改完密码建议执行一下restorecon -v /etc/shadow或者保险起见也touch /.autorelabel理由和第二章说的一样。RHEL 6时代很多人不重视这个但SELinux上下文紊乱确实会在某些策略下导致异常尤其是装了较全策略包的系统。3.2 单用户模式在RHEL 6上的两个注意事项第一个注意事项是/etc/fstab的挂载行为。单用户模式下系统默认只挂载了根分区如果你需要读写某个业务数据盘比如正好业务数据盘里存着密码备份或者解密脚本你得手动mount它。很多新手直接忽略这步等重启后才发现数据盘没动过。第二个注意事项是键盘布局。如果服务器在机房本地接的键盘可能跟你平时用的不一样输入密码时需要额外小心。我遇到过日文键盘布局的机器输密码时/变成了别的符号白折腾了半小时。如果你也碰上这种情况试试在shell里执行loadkeys us切换美式键盘布局再改密码。4. 终极大招用安装光盘/镜像进救援模式4.1 什么时候必须用救援模式rd.break和单用户模式都有一个前提GRUB引导菜单还能进得去。但有些情况这个前提就不成立了——系统引导损坏、你手贱把GRUB条目删了、或者磁盘加密LUKS层锁住了。这些情况下最可靠的办法是拿RHEL的安装介质启动进入救援模式Rescue Mode从外部挂载磁盘来重置密码。这个方案对应的就是热搜里那个rhel 9.2系统安装盘iso映像文件——下载官方ISO做成启动U盘既能装机也能救援。4.2 完整操作流程用安装介质引导系统在启动菜单里选择Troubleshooting再选Rescue a RHEL system。系统会问你要不要挂载现有系统选1让它搜索硬盘上的RHEL安装通常会自动挂载到/mnt/sysimage。有LUKS磁盘加密的话中间会提示你输入加密口令解锁磁盘这一步需要你记得LUKS口令——如果连这个都忘了那就不是密码重置的问题了是数据恢复的级别。挂载完成后会有一个shell提示先切换根目录chroot /mnt/sysimage之后的流程就和rd.break基本一样passwd root如果启用了SELinux同样需要touch /.autorelabel。退出exit后执行reboot拔掉安装介质正常从硬盘启动。4.3 救援模式下的其他用途救援模式能做的事远不止改密码。系统关键库损坏导致起不来、GRUB配置文件写坏了、/etc/fstab加错了一条挂载导致启动失败这类问题都能在救援模式下用chroot进入原系统后修复。我个人的习惯是任何系统本身没坏但就是进不去的问题先用救援模式再用rd.break。因为在救援模式下你能直接看到完整文件系统诊断效率比在initramfs调试shell里高得多。不过RHEL 8/9的救援模式需要较完整的安装镜像如果你手头只有DVD迷你镜像可能没有Troubleshooting这一项这算是当前版本救援模式的限制。5. 顺带解决密码过期和密码锁定两个衍生问题5.1 密码过期了该怎么处理热搜里密码过期四个字频繁出现说明这不是个例。密码过期和密码忘记是两码事密码忘记是你不知道密码是什么密码过期是你知道密码但系统不让你用。处理办法不是重置新密码而是调整密码策略。在你还能用某个sudo账号登录时执行chage -l root看一下Password expires和Account expires两行前者就是密码有效期后者是账户有效期。如果root密码已经过期最快的办法是切到root然后强制把有效期改成最大值chage -M 99999 root chage -I -1 root-M 99999表示密码最大有效期接近无限实际是99999天-I -1表示永不锁定。改完再执行chage -l root确认New的值变成never就对了。对普通用户也一样chage -M 90 username是很多公司安全策略的标准配置90天强制改一次密码配合chage -d 0 username可以强制该用户下次登录时先改密码。这里补充一下为什么-d 0有用它把最近修改时间设成1970年1月1日系统一算密码早就该改了于是强制走密码修改流程。5.2 密码被锁定后想解锁并且不想改密码有一种情况是你确切地知道密码是什么但系统提示Account locked或者Authentication failure这往往是因为多次输错密码触发了pam_faillock锁定策略。RHEL 8/9默认有这个机制5次输错锁定15分钟。如果你不想改密码只想解锁账户可以这样操作。先用root身份登录你总得有某种方式进去比如rd.break重置的或者是sudo账号然后faillock --user root --reset如果系统提示没有faillock命令就执行pam_faillock --user root --reset重置后再次尝试登录就会正常。这个机制对防范暴力破解确实有用但运维自己手滑输错几次被锁的案例也不少见知道解锁命令能少走很多弯路。5.3 忘记密码后密码哈希的几种常见格式如果你在救援模式下打算手工改/etc/shadow不建议容易玩坏认识一下哈希格式还是有必要的。$1$是MD5$5$是SHA-256$6$是SHA-512现代RHEL默认是$6$。有些系统会配置使用yescrypt$y$开头这是RHEL 9里较新的默认选项安全性更强但如果你想把哈希改写成$6$的老格式系统也能认只是密码强度测算算法会不一样。强烈不建议直接编辑/etc/shadow来复制别人的密码哈希哪怕是从另一台同版本机器copy。因为每台机器的哈希盐不同而且passwd命令本身会做合法性检查你手工改了下次用chage或其他工具管理时可能报错。正常操作永远是进入救援环境执行passwd让系统自己生成正确的哈希。6. 重置完之后的善后这次不能白忘6.1 立刻做的四件小事密码改完、系统能登录了别急着走按下面的顺序检查一遍。第一验证SELinux状态。执行getenforce如果显示Enforcing确认/.autorelabel是否已经触发过没有的话手动执行restorecon -v /etc/shadow。第二确认SSH能正常登录。systemctl status sshd看一下服务状态再用别的机器ssh root主机IP试一下。很多情况下密码改好了但SSH服务因为之前SELinux或者PAM配置出错根本没起来这不叫修完。第三检查/etc/shadow里root密码的过期时间直接执行chage -l root如果剩余天数不多了顺手chage -M 99999 root避免过几天又来一遍。第四查看审计日志确认有没有异常登录痕迹。journalctl -u sshd --since today或者cat /var/log/secure | grep -i fail | tail -20。如果发现重置前已有可疑的登录尝试那要考虑的不只是改密码还有系统是否已被入侵。6.2 给运维的预防机制配置经历过一次半夜重置密码之后我的经验是与其相信人不会忘不如把预防机制建好。比较实用的几个做法创建一个有完整sudo权限的备用账号比如ops平时用这个账号日常管理root密码只存在密码保险箱里。给root账号配置SSH密钥登录。就算密码忘了只要密钥文件在照样能登进去。如果服务器在机房有带外管理口iDRAC/ILO确保带外管理密码单独妥善保存——因为它能在系统完全起不来的时候提供远程控制台。KVM/IPMI的设备上把rd.break这招记在运维手册里遇到事情不用翻浏览器。合理设置密码策略/etc/login.defs里PASS_MAX_DAYS、PASS_MIN_DAYS、PASS_WARN_AGE这组参数按公司规范设好别把有效期设成0天——0天表示密码立即过期一觉醒来全办公室都在找你。6.3 一个值得养成的习惯我自己的习惯是每个季度找一台空闲的RHEL机器按上面rd.break的流程走一遍确认当前内核版本、dracut参数、GRUB界面有没有什么变化顺手把操作步骤更新到本地知识库里。系统在升级教程也在过期网上的老文章十有八九写的是RHEL 6时代的操作等到你真正需要的时候发现步骤对不上那才是最被动的局面。除了rd.break我还会顺带看一眼journalctl -b确认系统启动有没有其他即将爆发的故障——毕竟你都进过一次救援环境了这台机器大概率不是铁板一块提前发现问题总比下次再半夜爬起来强。密码重置这件事说到底不复杂五步之内能说清楚。但它发展的分支很多SELinux要管、PAM要管、磁盘加密要管、GRUB版本差异要管每个分支都能坑你一次。把这篇文章里一层层的问题过一次你以后再碰到忘记密码这个场景心里就有谱了——不是靠背命令而是靠理解这套启动、认证、安全机制各自在什么位置发挥作用。真到了那一步你会发现最值钱的不是那条passwd命令而是你对整个系统重启流程的掌控感。