RHEL忘记root密码?单用户模式与rd.break实操指南
做运维的人十个有九个都经历过那种“人在机房密码想不起来”的窒息时刻。尤其是碰到老旧的 RHEL 6.9 服务器手边没有文档、没有密码本业务还在跑重启窗口约到半夜三点root 密码就这么凭空消失了。别急着拆硬盘RHEL 系统从设计上就给管理员留了一条标准救援路径通过单用户模式或者 initramfs 阶段的中断机制在控制台直接重置 root 密码。这篇文章把我这些年处理 RHEL 忘记密码找回的完整经验写清楚重点覆盖 RHEL 6.x含 6.9和 RHEL 7/8/9 的差异并附上一堆实操踩坑记录适合系统管理员、运维工程师也适合刚接手服务器想提前做准备的新手。1. 找回RHEL密码前先搞清楚三件事1.1 找回密码的本质不是“破解”而是“接管启动过程”很多新手第一次听说“找回密码”时脑子里想的可能是漏洞利用、暴力破解之类的操作。其实完全不是这回事。Linux 系统的密码认证核心在/etc/shadow文件里里头存的是经过哈希处理的密码串普通用户没有读取权限root 也没法把这串哈希直接“还原”成明文密码。所以所谓找回密码真正的操作路径是通过系统启动期间的特殊模式拿到一个等同于 root 的执行环境然后调用passwd命令重新设置一个新密码。这不是绕过认证而是利用系统设计时预留的本地控制台恢复机制。前提是你得有这台服务器的物理控制台或者虚拟化平台的控制台权限否则一切都无从谈起。这个理解很重要因为它决定了排查方向。如果远程 SSH 还通着、本地又没有控制台那么再牛的“找回密码”技巧也派不上用场反过来只要你手里有控制台哪怕 SSH 完全不可用、root 密码彻底遗失这台机器的系统层面也拦不住你。专业一点的说法是Linux 信任的是“能碰控制台的人就是管理员”密码只是登录环节的一道闸门不是磁盘加密的钥匙。1.2 RHEL 6.x 与 RHEL 7/8/9 的分水岭在哪里很多人一搜资料就懵了因为网上的教程写法完全不同。有的告诉你按e进 grub 菜单然后加single有的告诉你加rd.break还有的直接让你改init/bin/sh。其实这些差异的根源只有一个RHEL 6 和 RHEL 7 之后的启动流程不是一套东西。对比项RHEL 6.x含 6.9RHEL 7/8/9引导程序GRUB 第一代GRUB LegacyGRUB 2初始化系统SysVinit / Upstartsystemd内核启动参数直接由 grub.conf 管理由 grub.cfg 生成并传递紧急模式机制单用户模式runlevel 1rd.break / emergency 模式进入恢复环境后的根目录直接是/先到/sysroot需 chrootRHEL 6.9 是 RHEL 6 系列的收官版本市面上到现在还有大量生产环境在运行。它的恢复方法就是经典的“单用户模式”。而 RHEL 7 开始换成 GRUB 2 和 systemd单用户模式的玩法变了更主流的做法是rd.break。所以后面我会把这两条路线分开讲先讲老的再讲新的对照着看就不会乱。2. RHEL 6.x含 6.9经典操作单用户模式找回密码2.1 进入 GRUB 菜单给内核加一个“单用户”参数RHEL 6.9 默认的启动倒计时只有 5 秒所以第一步动作要快。在虚拟机控制台或物理服务器显示器前重启主机在看到 GRUB 菜单界面时迅速按任意键让倒计时停下来。菜单里一般有几个内核条目选择实际使用的那个内核行按e进入编辑模式。注意这里的e是编辑整条启动配置不是 GRUB 2 的按e修内核命令行但操作直觉是一样的。进入编辑界面后找到以kernel开头的那一行它后面跟着一长串参数类似/vmlinuz-2.6.32-696.el6.x86_64 ro root/dev/mapper/vg_xxx-lv_root rd_NO_LUKS ...。把光标挪到这行末尾添加一个单词single。老版本 GRUB 里single、数字1、字母s效果基本等同都表示以运行级别 1单用户模式启动我习惯写single语义最清晰别的同事接手时一眼能看懂。改完之后按回车回到菜单再按b启动。这个模式启动后系统不会拉起完整的图形界面和多用户服务而是直接进入一个 root shell。因为是 console 登录不需要密码。但要注意单用户模式下的根文件系统挂载状态在不同发行版上不完全一样有的版本自动挂载为读写有的还是只读。保险起见执行passwd之前先手动挂载一下mount -o remount,rw /如果真的处于只读状态直接跑passwd root会报错提示无法打开/etc/shadow。先 remount 再改密码都是正常操作别慌。2.2 重置 root 密码以及那道“SELinux 后处理”进入单用户模式的 root shell 后直接敲passwd root按提示输入两次新密码。这样系统会重新生成/etc/shadow里 root 对应的哈希串。这里我强烈建议用passwd命令而不是手动vi /etc/shadow去改。passwd命令除了更新哈希值还会处理文件权限、文件属主、甚至部分 SELinux 上下文手动编辑器一旦弄错一行格式轻则密码改失败重则整个系统所有账户都登录不了。密码改完后RHEL 6 还有一个容易被忽略的坑SELinux 上下文。如果你直接退出单用户模式重启某些版本上会发现 root 密码明明改了登录时却被拒绝或者系统在启动阶段疯狂刷 SELinux 报错。这是因为/etc/shadow的 SELinux 标签在单用户模式下出现了异常。最简单的处理就是在重启前执行touch /.autorelabel这行命令会在系统下次启动时强制对整个文件系统重新标注 SELinux 标签虽然会延长首次启动时间几百 GB 的盘可能要十几分钟但能一次性把所有文件的上下文校正回来。如果系统原本就通过/etc/selinux/config把 SELinux 设成了disabled那这一步可以跳过。改完密码、处理完标签执行reboot然后用新密码从控制台登录验证即可。3. RHEL 7/8/9 找回密码rd.break 与 init/bin/sh3.1 首选方案rd.break 强制中断 initramfsRHEL 7 之后的系统启动流程被 systemd 接管传统的single参数虽然还兼容但在很多定制场景下不够可靠更标准的做法是用rd.break。这个名字里的rd指 ramdiskinitramfs含义是在加载完 initramfs、真正切根到磁盘系统之前强制停下来进入一个临时 shell。操作步骤也不复杂。重启后在 GRUB 2 菜单界面选中内核条目按e进入编辑。找到以linux或linux16开头的那一行这一行末尾通常有rhgb quiet把它们后面或前面追加一个参数rd.break加在末尾最简单。按Ctrlx或F10启动系统会在 initramfs 阶段中断出现一个提示符。在这个提示符下根文件系统还没有真正挂载好但它已经被 initramfs 挂载到了/sysroot目录而且是只读状态。所以接下来要做的就是重挂读写、chroot 进去mount -o remount,rw /sysroot chroot /sysroot passwd root touch /.autorelabel exit exit这里有两个细节值得说清楚。第一为什么需要chroot /sysroot因为你现在所在的 shell 属于 initramfs 这个微系统里面只有最基本的工具直接跑passwd改的是临时环境里的 shadow不是磁盘上真正的 shadow只有 chroot 到/sysroot才能像进入完整系统一样操作。第二为什么还要touch /.autorelabel和 RHEL 6 一样RHEL 7 默认 SELinux 是 enforcing 状态从 initramfs 里改密码会打乱/etc/shadow的上下文不重标的话重启后登录可能直接被 SELinux 拒绝。连续输入两次exit第一次退出 chroot第二次继续让系统完成剩余的启动流程最后正常进入登录界面。3.2 备选方案init/bin/sh什么时候用rd.break在绝大多数情况下都好用但如果你遇到的是某些特殊定制的内核或非常老的磁盘驱动rd.break中断之后 chroot 不进去可以换一条路把内核参数里的rhgb quiet删掉改成init/bin/sh。这告诉内核切根之后不要启动 systemd 的默认流程直接拉起一个/bin/sh。这种方式下根文件系统的挂载时机更靠后但同样默认是只读的。进入 shell 后先执行mount -o remount,rw / passwd root touch /.autorelabel sync reboot -f注意最后的reboot -f。由于系统的正常初始化流程被跳过了直接敲reboot可能不会干净地重启加-f强制重启反而更省事。这个方法相比rd.break少了一层 chroot但对新手来说反而更容易理解我就是进入了一个 root shell改密码然后重启。缺点是它完全跳过了 systemd 的关停逻辑不适合在生产系统上反复玩。3.3 RHEL 8/9 特有的三个“新坑”RHEL 8 和 RHEL 9 的整体操作和 RHEL 7 类似但有几个版本特有的事项我在实际处理中踩到过。第一密码策略更严格了。RHEL 8 开始默认启用passwd的复杂度检查pwquality如果你在 chroot 环境下设了一个过于简单的密码比如123456系统会直接拒绝。设置失败后别愣着换一个至少包含大小写和数字、长度足够的新密码即可。第二RHEL 9 对内核参数做了更严格的校验rd.break依然有效但如果你同时保留了rhgb quiet之外的旧参数可能启动时出现警告。无所谓只要能看到断点提示符就说明参数传递成功。第三如果你给 root 和业务数据做了 LUKS 磁盘加密那么上述所有操作的前提是你记得 LUKS 解密 passphrase。启动过程中系统会在 initramfs 阶段先问你 LUKS 密码输入之后才会挂载加密根分区之后的rd.break/chroot流程照常可用。如果 LUKS 密码也忘了那就不是“找回密码”能解决的问题了属于数据恢复范畴复杂度完全不在一个量级。4. 实操现场一台 RHEL 6.9 老服务器的完整找回过程4.1 现场情况记录去年帮朋友处理过一次比较典型的故障一台运行在 VMware 上的 RHEL 6.9 虚拟机跑着内部报表系统SSH 密钥登录原本是正常的但某天管理员在做安全整改时重启了 sshd之后发现 root 的密码文件丢失了所有人都联系不上之前的负责人。业务系统不能停太久重启窗口只有上午一小时。我接手时先把网络拓扑确认了确定这台机器可以通过 vSphere Web Console 直接看控制台不需要去机房这给后面操作省了大量时间。然后和业务方确认窗口预计整个操作 5-10 分钟内完成因为流程已经烂熟于心。4.2 逐步操作实录窗口开始后我在控制台发送重启指令。RHEL 6.9 的 GRUB 倒计时出现时迅速按了下方向键屏幕停在菜单界面。选中默认内核条目按e找到kernel那一行在末尾补了single回车后按b。系统日志刷刷滚动大约一分钟后出现#提示符没有要求输入密码。我先敲了mount -o remount,rw /确认根文件系统可写然后直接执行[rootlocalhost /]# passwd root输入两次新密码。这里有个小细节控制台默认键盘布局是美式英语如果新密码里带中文输入法容易出的特殊字符可能在登录时打不出来所以我在设置时特意避免了特殊符号只用大小写字母加数字的组合。密码设置成功后我没急着重启而是执行了touch /.autorelabel因为这台机器原来的 SELinux 是 enforcing 模式。之后输入reboot系统开始重启。由于 autorelabel 是强制执行重启过程中的启动时间明显变长大约多花了五六分钟这个现象正常。之后控制台出现登录界面用新密码成功登录 root。整个找回过程加上等待 relabel总耗时在 15 分钟以内比窗口余量还富余不少。4.3 登录后的必要收尾密码找回只是第一步。我登录后做了几件收尾的事getenforce ls -l /etc/shadow tail -n 50 /var/log/securegetenforce确认 SELinux 已经回到Enforcing并在正常运行检查/etc/shadow权限没有变化翻/var/log/secure是想确认重启前后有没有异常登录尝试毕竟这次故障来得不明不白。同时和业务方确认如果有其他账户密码也丢了趁 root 权限在手里直接passwd 用户名重新设置别等到下次出事再折腾。5. 常见问题与排查技巧实录5.1 GRUB 也设了密码导致根本改不了启动参数这是找回密码场景里最尴尬的一种。RHEL 6 可以在/etc/grub.conf里设置password指令RHEL 7 之后可以用grub2-setpassword给 GRUB 菜单加密码。一旦 GRUB 保护开了进入编辑模式之前就会要求输入 GRUB 密码而如果这个密码也丢了上面讲的所有“改内核参数”的办法全部失效。这种局面下的出路是用安装光盘或救援镜像启动到 rescue 模式挂载根分区然后手工编辑/boot/grub/grub.conf或/boot/grub2/grub.cfg把 GRUB 密码相关的行去掉或替换成你知道的哈希。RHEL 7 上可以用grub2-mkpasswd-pbkdf2生成新哈希再用grub2-setpassword重新设置。如果机器在虚拟化平台上也可以试试把启动盘挂到另一台同版本 Linux 上修改。但这一套操作比单纯改 root 密码复杂得多所以我特别建议GRUB 密码这类引导层凭据一定要单独记录在团队的密码管理库里不能只躺在某一个人的脑子里。5.2 改了密码仍然登录失败先查账户锁定状态有些单位的服务器跑过安全基线检查给 root 加过锁定策略。你辛辛苦苦进入单用户模式改完密码结果重启后登录时提示Account is locked那问题就出在/etc/shadow里 root 这一行的密码字段前缀。正常情况下root:$6$xxxx...如果它变成了root:!!$6$xxxx...或者root:*$6$xxxx...说明账户处于被锁状态passwd命令直接设置密码不会自动解锁。处理方式很简单在单用户模式或 root shell 下执行passwd -u root如果是因为账户过期/etc/shadow中root行的第 8 字段有值可以用chage -l root查看过期信息再用usermod -e或chage -E -1清除过期时间。这类问题在找回密码的帖子里很少被提到但在等保、SSL 合规改造过的机器上相当常见。5.3 单用户模式进去后发现根目录是只读的这个问题在 RHEL 6.9 上尤其多见。原因在于单用户模式默认挂载根文件系统时会沿用内核参数里的ro。如果没注意直接执行passwd会报类似cannot lock /etc/passwd的错误。解决办法就是开写权限mount -o remount,rw /执行完之后可以用touch /test快速验证是否能写入能写再继续改密码。另外如果在单用户模式下你做了其他操作比如顺手改了/etc/fstab重置回读写挂载一定在重启前再确认一次避免把配置改坏了还开机失败。5.4 云主机 / 虚拟机环境的特殊玩法云上的机器和物理机不太一样。如果你用的是公有云厂商的标准镜像绝大多数厂商控制台都提供“重置密码”功能背后原理通常是卸载系统盘、挂到一台临时救援实例上修改 shadow 文件然后再挂回来。这种情况下你其实不需要手动进单用户模式直接点控制台的重置密码按钮即可。但要注意云厂商的重置密码功能往往只对“支持镜像”有效如果你用的是自己导入的 RHEL 6.9 自定义镜像可能没有这个功能。这种时候我建议的路径是用厂商控制台把系统盘作为数据盘挂到另一台同版本 RHEL 机器上修改/etc/shadow后再卸载挂回。改 shadow 之前一定先备份cp /etc/shadow /etc/shadow.bak手工修改时保持原有行格式密码哈希可以用openssl passwd -6或python3 -c import crypt; print(crypt.crypt(newpass, crypt.mksalt(crypt.METHOD_SHA512)))生成后再替换到 shadow 文件中。这种“挂盘改密”的方式不依赖启动菜单遇到 GRUB 密码、启动参数损坏等极端情况反而是最稳的兜底方案。6. 找回密码之后建议给生产系统立几条规矩经历过几次半夜找密码的折腾后我在自己维护的系统上定了几条简单的规矩分享出来当一个参考。第一条任何服务器的 root 密码和 GRUB 密码必须存放在团队共享的密码管理工具中离职交接时强制轮换不允许“只有某某知道”。第二条生产环境能不开 root 远程登录就不开日常操作全部走普通用户加 sudo并开启 sudo 日志这样即使 root 密码丢了影响面也小很多。第三条在任何 rescue 模式、单用户模式下执行过写操作之后优先用touch /.autorelabel再重启哪怕系统当前 SELinux 是 permissive这个动作也能避免后续莫名其妙的文件标签异常。第四条找一个非业务高峰时段主动做一次密码找回演练把步骤文档标准化真出事时照着文档执行能把人为失误降到最低。另外还有个小习惯值得提一下在 RHEL 6.9 这种老版本上grub.conf里的默认启动内核如果有多个建议把常用内核调整到第一个避免紧急情况下按错选项。别小看这些细节我见过太多故障处理时因为启动到了旧内核导致密码改成功了但系统服务起不来最后又浪费一轮窗口的案例。每次改完密码顺手确认uname -r和预期内核版本一致是花十几秒就能避免大坑的好做法。