☰
Red Hat 9.0 root密码重置:rd.break与救援模式实战
2026/10/26 18:52:48 网站建设 项目流程

凌晨两点,值班手机响了,一台跑着 Red Hat 9.0 的业务机要紧急重启,交接文档里 root 密码那一栏却是空的。这种事在运维圈不算稀奇:系统可能是别人装的,密码可能随人员交接丢了,也可能被安全策略强制改过之后没人记录。Red Hat 9.0 重置 root 密码这件事,说大不大,说小也不小——做对了,十分钟恢复;做错了,SELinux 一拦、GRUB 一锁,机器直接进 emergency mode。下面我按自己实际处理过的顺序,把rd.break、init=/bin/bash、安装介质救援、rescue.target这几条路径拆开讲,重点放在每一步为什么这么做、参数怎么选、哪里容易翻车。无论你是刚接触企业级 Linux 的新手,还是偶尔要帮人救场的老手,都能直接照着操作。

1. 先弄清 Red Hat 9.0 的启动链路和密码落点

1.1 从固件到 systemd:密码重置可插入的四个窗口

Red Hat 9.0 这类企业级 Linux 的启动链路比桌面发行版多几层“关卡”:固件自检、GRUB2 引导、内核加载 initramfs、initramfs 挂载真实根分区、switch_root切换到真实根、systemd 拉起服务。每一层都可能成为重置密码的入口,但权限边界完全不同。你在 GRUB 里改内核参数,等于在系统正式启动前“插队”;你用安装介质引导,等于绕开本机引导链;你在已经登录的系统里执行passwd,那是最省事的路径,可前提是你还进得去。

我把可用的窗口归成四类,后面几种方式基本都在这四类里打转:

  • GRUB 内核参数窗口:在 GRUB 菜单按e,给内核命令行加rd.break、init=/bin/bash或systemd.unit=rescue.target。不用额外介质,适合有本地控制台或虚拟机控制台的场景。
  • 安装介质救援窗口:用系统安装 ISO 引导,进入救援环境,把原系统根分区挂到/mnt/sysroot,再chroot进去改密码。适合 GRUB 被锁、initramfs 损坏、根分区无法正常挂载的情况。
  • 已登录系统窗口:普通用户sudo passwd root,或者 root 自己passwd。这不是“忘记密码”的解法,但很多人其实是“密码没忘,只是没权限”,别把问题想复杂。
  • 托管环境救援窗口:没有本地控制台,只能把系统盘挂到另一台救援实例上,操作逻辑和安装介质救援一样,只是挂载点变成/mnt/sysroot或类似路径。

选择哪条路,核心看三个条件:你有没有控制台、GRUB 有没有被密码保护、根分区是不是加密的。三个条件里只要有一个不满足,方案就得换。下面每讲一种方式,我都会把适用边界写清楚,免得你照着步骤做到一半才发现进错了门。

1.2 /etc/shadow 里到底改了什么

很多人以为重置密码是“把密码改掉”,实际上 Linux 本地账户的密码并不以明文存在任何文件里。/etc/passwd的第二字段通常是一个x,真正的密码哈希在/etc/shadow。一行典型的 shadow 记录长这样:

root:$6$随机盐$一串哈希:19800:0:99999:7:::

字段用冒号分隔,从左到右分别是:用户名、密码哈希、最后一次修改密码的天数(从 1970-01-01 起算)、最小修改间隔、最大有效天数、过期前警告天数、不活动天数、账户过期天数、保留字段。passwd root做的事,本质上是调用 PAM 模块校验新密码强度,然后用当前算法生成新的哈希,更新第二字段和第三字段。

这也解释了两个常见现象。第一,手工编辑/etc/shadow把第二字段改成明文密码,登录一定失败,因为系统会用crypt去比对哈希,不是比对明文。第二,如果你只改了哈希没改第三字段,系统可能认为密码“很久没改”,登录后立刻要求你改密码,甚至因为过期策略直接拒绝。用passwd命令是最稳的,它会把这些字段一起处理好,权限和文件锁也由它维护。

提示:/etc/shadow的权限通常是0000或000,属主 root、属组 root。手工编辑很容易把权限改坏,改完登录不了,排查起来比重置密码还麻烦。能用passwd就不要用手改。

1.3 SELinux 与 XFS:两个最容易忽略的副作用

Red Hat 9.0 默认启用 SELinux,根文件系统默认是 XFS。这两个东西在正常运行时是安全加成,在重置密码时却经常变成“隐形坑”。先说 SELinux:/etc/shadow有固定的安全上下文,通常是shadow_t。你在rd.break的 initramfs 环境里用passwd改密码,新写入的内容可能带上错误的标签,或者文件被重新创建后标签变成etc_t、unlabeled_t。systemd 启动后,登录程序读/etc/shadow被 SELinux 拒绝,表现就是“密码明明改对了,就是登不进去”,/var/log/secure里能看到 AVC 拒绝记录。

解决办法不是关 SELinux,而是在真实根分区上创建一个标记文件:

touch /.autorelabel

系统下次启动时,systemd 会检测到/.autorelabel,触发一次全盘重新标记,把/etc/shadow的上下文恢复成shadow_t。代价是启动时间变长,文件越多、磁盘越慢,等得越久。几十万文件的系统在机械盘上跑十几分钟很常见,别以为卡死了就断电。

再说 XFS。XFS 是日志文件系统,挂载时默认可能以只读方式进入,尤其是 initramfs 阶段。你要改/etc/shadow,必须先让根分区可写。rd.break环境下根分区挂在/sysroot,需要mount -o remount,rw /sysroot;init=/bin/bash环境下根分区就是/,需要mount -o remount,rw /。少这一步,passwd会报“Authentication token manipulation error”,很多人卡在这里以为是密码策略问题,其实是文件系统只读。

1.4 重置前的风险清单

重置 root 密码本身不复杂,但它是一个“高权限、低容错”的操作。我一般会在动手前花两分钟确认几件事,这两分钟能省掉后面两小时:

检查项为什么要确认不确认的后果
是否有虚拟机快照快照是最快的回滚手段操作失误后只能走更复杂的救援
根分区是否 LUKS 加密加密盘要先解锁才能挂载卡在 initramfs 提示符,误以为命令错了
GRUB 是否设置密码有密码时按e要先验证进不了编辑界面,白折腾
是否有物理/带外控制台云主机没有本地控制台方案要从“本地引导”换成“挂载系统盘”
当前是否业务高峰重置过程需要重启影响面扩大,压力翻倍
磁盘剩余空间全盘 relabel 和日志写入需要空间空间不足导致启动失败

注意:生产环境里,重置 root 密码属于变更操作,不是“随手修一下”。哪怕你有百分百把握,也建议先留快照或备份关键配置。物理机没有快照,至少确认一下最近有没有可用的系统备份。

2. 方式一:rd.break 在 initramfs 阶段截停

2.1 为什么首选 rd.break

rd.break是我处理 Red Hat 9.0 忘记 root 密码时最常用的方式,没有之一。它的原理是在 initramfs 阶段、真实根分区已经挂载到/sysroot、但还没有执行switch_root切换到真实根之前,给用户一个调试 shell。这个时候 systemd 还没起来,服务没启动,SELinux 策略也没完全生效,你面对的是一个相对“干净”的环境。

它比init=/bin/bash稳的地方在于:真实根分区已经被 initramfs 挂载好了,LVM、LUKS、软 RAID 这些存储栈通常已经激活,你不需要自己再去vgchange -ay、cryptsetup luksOpen。你只需要重新挂载为可写、chroot进去、改密码、打标记、退出。步骤少,变量少,成功率高。

它比安装介质救援方便的地方在于:不用找 ISO、不用做启动盘、不用进服务器 BMC 挂虚拟光驱。只要你能在 GRUB 菜单按e,就能操作。虚拟机里尤其快,重启、按e、改一行、Ctrl+X,几分钟搞定。

提示:rd.break是 dracut 的参数,不是普通内核参数。它必须写在 GRUB 的linux行末尾,不能写到initrd行,也不能单独一行。写错位置,系统会当普通参数忽略掉,直接正常启动。

2.2 GRUB 命令行怎么改

重启系统,在 GRUB 菜单出现时按e进入编辑模式。Red Hat 9.0 的 GRUB 菜单可能默认隐藏,开机时连续按Esc或Shift能调出来。UEFI 环境下一般是按Esc。进入编辑界面后,找到以linux开头的那一行,它通常长这样:

linux ($root)/vmlinuz-5.14.0-xxx root=/dev/mapper/rhel-root ro crashkernel=auto resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet

在行尾加一个空格,然后写rd.break:

linux ($root)/vmlinuz-5.14.0-xxx root=/dev/mapper/rhel-root ro crashkernel=auto resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet rd.break

改完按Ctrl+X启动。注意不要删掉原来的root=参数,也不要把ro改成rw——rd.break阶段根分区本来就是只读挂载到/sysroot,你后面会手动 remount。有人习惯在这里加rw,没必要,反而可能让 initramfs 的行为变得不好预测。

如果系统有多個内核,选当前正在用的那个,别选 rescue 内核。如果 GRUB 设置了密码,按e后会要求输入用户名和密码,通常是root加 GRUB 密码。忘记 GRUB 密码的话,这条路径走不通,直接看第 4 节的安装介质救援。

2.3 进入 switch_root 后的完整操作

启动后你会看到一个switch_root:/#提示符,说明已经进了 initramfs 的调试 shell。完整操作如下:

switch_root:/# mount -o remount,rw /sysroot switch_root:/# chroot /sysroot sh-5.1# passwd root Changing password for user root. New password: Retype new password: passwd: all authentication tokens updated successfully. sh-5.1# touch /.autorelabel sh-5.1# exit switch_root:/# exit

逐行解释一下。第一行mount -o remount,rw /sysroot把真实根分区从只读改成可写,不改这一步后面passwd写不进去。第二行chroot /sysroot把当前进程的根目录切换到真实根,提示符会从switch_root:/#变成sh-5.1#,这说明你现在操作的已经是硬盘上的系统,不是内存里的 initramfs。第三行passwd root改密码,按提示输两遍。第四行touch /.autorelabel在真实根上创建 SELinux 重标记标记文件。第五行exit退出 chroot,回到 initramfs。第六行再exit,initramfs 会继续执行switch_root,系统正常启动。

有时候第二次exit后系统不会立刻重启,而是继续启动流程,屏幕会滚动服务日志。如果卡住不动,可以reboot -f强制重启。reboot -f不会走正常关机流程,但在这个阶段一般没有未刷盘的数据,问题不大。稳妥一点的做法是先sync,再reboot -f。

2.4 参数与提示符背后的逻辑

很多人照着步骤做能成功,但换个环境就懵,原因是没理解/sysroot和/的关系。rd.break断在 initramfs 里,此时内存中运行的是一个小型 Linux 环境,它的/是 initramfs 的根,真实硬盘根分区被挂载在/sysroot。你直接在这个环境里执行passwd,改的是 initramfs 里的/etc/shadow,不是硬盘上的,重启就丢了。所以必须先chroot /sysroot,把“视角”切到硬盘根。

touch /.autorelabel也有讲究。在chroot之前执行,标记文件会建在 initramfs 的/上,重启后 systemd 根本看不到。必须在chroot之后执行,文件才会落在真实根的/下。这个细节很小,但漏了就会出现“密码改对了却登录不了”的 SELinux 问题。

exit两次的顺序也不能反。第一次退出 chroot,第二次退出 initramfs 的 shell。如果你在 chroot 里直接reboot,有时候能重启,有时候会因为 initramfs 的进程状态不干净而卡住。按标准流程走,最稳。

2.5 适用边界与注意事项

rd.break虽好,但不是万能。根分区如果是 LUKS 加密,启动过程中会先要求输入磁盘加密密码,输对了才进switch_root:/#。如果你连 LUKS 密码也不知道,这条路径走不通,得找加密密钥或者走其他恢复流程。根分区如果是网络存储、iSCSI 之类,initramfs 可能没有对应的激活逻辑,也会卡住。

还有几个实操细节值得记一下:

  • 如果mount -o remount,rw /sysroot报“mount point not mounted or bad option”,先执行mount | grep sysroot看看根分区到底挂在哪。有些定制镜像会把根挂到/sysroot之外。
  • 如果passwd报“BAD PASSWORD”,说明新密码没过pwquality策略。换一个长度 12 位以上、大小写字母加数字加符号的临时密码,进去后再改。
  • 如果passwd报“Authentication token manipulation error”,先检查/sysroot是不是真的可写,再检查磁盘是不是满了。df -h /sysroot看一眼。
  • 如果系统启用了faillock,之前多次输错密码可能把 root 锁了。重置密码不会自动解锁,进去后要执行faillock --user root --reset。
  • 如果 SELinux 处于disabled或permissive,touch /.autorelabel不是必须的,但加上也没坏处,下次启动会跳过或快速处理。

注意:全盘 relabel 会重写大量文件的扩展属性,磁盘 I/O 会很高。生产环境尽量安排在维护窗口,别在业务高峰做。relabel 过程中不要断电,否则可能出现部分文件标签不一致,虽然通常还能启动,但排查起来很烦。

3. 方式二:init=/bin/bash 直接拿一个 root shell

3.1 与 rd.break 的本质差异

init=/bin/bash是另一条经典路径,思路更“暴力”:让内核不启动 systemd,直接把/bin/bash当作 1 号进程。系统会完成switch_root,真实根就是/,但没有任何服务、没有登录管理器、没有 systemd 的依赖挂载。你拿到的是一个 root shell,提示符通常是bash-5.1#。

它和rd.break最大的区别在“断层位置”。rd.break断在 initramfs,真实根在/sysroot;init=/bin/bash已经切到真实根,真实根就是/。所以命令里的路径不一样:rd.break要chroot /sysroot,init=/bin/bash不用chroot,直接改/etc/shadow。但也因为 systemd 没起来,/proc、/sys、/dev可能不完整,某些命令会报错,需要手动挂载。

我一般什么时候用init=/bin/bash?两种情况:一是rd.break进不去,比如某些定制 initramfs 不认这个参数;二是我想少一次chroot,直接在真实根上操作。但它的副作用比rd.break多,新手更容易踩坑,所以我把rd.break排在前面。

3.2 操作步骤与只读根处理

GRUB 编辑方式和rd.break一样,找到linux行,在行尾加rw init=/bin/bash:

linux ($root)/vmlinuz-5.14.0-xxx root=/dev/mapper/rhel-root ro crashkernel=auto ... rhgb quiet rw init=/bin/bash

这里我建议加rw,因为init=/bin/bash已经切到真实根,加rw可以让根分区直接以可写方式挂载,省掉一次 remount。但有些系统即使加了rw,根分区仍然是只读,所以进系统后第一件事还是检查挂载状态:

bash-5.1# mount -o remount,rw / bash-5.1# passwd root Changing password for user root. New password: Retype new password: passwd: all authentication tokens updated successfully. bash-5.1# touch /.autorelabel bash-5.1# sync bash-5.1# reboot -f

如果mount -o remount,rw /报错,先mount | grep ' / '看根分区的实际挂载选项。XFS 根分区一般可以 remount rw,但如果底层有只读设备或者文件系统有错误,会 remount 失败。这时候要看内核日志,不要硬改。

3.3 伪文件系统与命令缺失

init=/bin/bash环境下,/proc可能没挂载,导致passwd在某些 PAM 配置下报错,reboot命令也可能找不到。可以手动挂载:

bash-5.1# mount -t proc proc /proc bash-5.1# mount -t sysfs sysfs /sys bash-5.1# mount -t devtmpfs devtmpfs /dev

挂载/dev要小心,如果/dev已经有内容,mount会覆盖或报错。先mount | grep /dev看一眼,已经挂了就别重复挂。/proc和/sys一般挂上没坏处,passwd、faillock、chage这些命令有时依赖它们。

如果reboot命令不存在,可以用sync后执行echo b > /proc/sysrq-trigger强制重启,但这需要/proc已挂载且sysrq没被禁用。更稳妥的做法是exec /sbin/init让 systemd 接管,但 systemd 在init=/bin/bash后启动可能会因为环境不完整而失败,所以我不常推荐。多数情况下sync; reboot -f就够了。

3.4 密码策略拦截与绕过思路

passwd不是单纯写文件,它会调用 PAM 的pam_pwquality模块检查密码复杂度。Red Hat 9.0 默认策略通常要求最小长度 8 位,还要检查字典、连续字符、用户名包含等。如果你设一个123456,会直接报:

BAD PASSWORD: The password is shorter than 8 characters

或者:

BAD PASSWORD: The password fails the dictionary check - it is too simplistic/systematic

我的建议是别跟策略较劲,临时密码设成Tmp#Rhel9!2024这种长度 14 位、大小写数字符号齐全的,进去后再改成团队密码库里的正式密码。如果你确实需要绕过策略,可以临时改/etc/security/pwquality.conf,但那会降低系统安全性,而且改完容易忘了改回来,不推荐。

还有一种情况是账户被锁定。shadow 第二字段以!或!!开头表示密码被锁,passwd通常会帮你解锁并设置新密码。但如果 PAM 的pam_faillock把账户锁了,passwd不一定能清掉失败计数。进系统后执行faillock --user root --reset,或者直接删除/var/run/faillock/root(重启后 tmpfs 会清空,但没重启前需要手动清)。

3.5 退出与重启的正确姿势

init=/bin/bash下没有 systemd 管关机流程,直接按电源键或者reboot都可能不干净。我的习惯是:

bash-5.1# sync bash-5.1# reboot -f

sync把脏页刷盘,reboot -f跳过正常关机流程直接重启。这个组合在 rescue 场景里够用。如果你不放心,可以执行mount -o remount,ro /再重启,但没必要,sync已经覆盖了主要风险。

重启后如果系统进入 emergency mode,先看屏幕提示。常见原因是/etc/fstab里有挂载项失败,或者 SELinux relabel 没完成。init=/bin/bash不会自动触发 relabel,你手动touch /.autorelabel后重启,systemd 才会做。如果忘了touch,登录时可能被 SELinux 拒绝,表现是输入正确密码后又被踢回登录界面。

4. 方式三:安装介质进救援模式

4.1 什么时候必须用介质

有些场景下,GRUB 编辑这条路径根本走不通:GRUB 被密码保护且密码丢失、GRUB 配置损坏导致菜单都出不来、initramfs 损坏、根分区文件系统错误无法挂载、系统盘被换到另一台机器上。这时候安装介质救援就是兜底方案。

你需要一个和当前系统版本相同或相近的安装 ISO。版本不一致不一定不行,但救援环境里的内核、存储驱动、LVM 工具可能和原系统有差异,尽量对齐。把 ISO 写到 U 盘或者挂到服务器的虚拟光驱里,从它引导。物理机进 BIOS/UEFI 改启动顺序,虚拟机在启动时按F12或对应快捷键选启动设备。

提示:救援模式不会自动改你的系统,它只是把原系统挂载到一个临时目录。真正改密码的动作仍然是你手动chroot后执行的。所以不用怕“进救援模式会把系统搞坏”,搞坏系统的是后面乱敲的命令。

4.2 进入救援环境并挂载原系统

从 ISO 引导后,选择Troubleshooting,再选Rescue a Red Hat Enterprise Linux system。系统会探测磁盘并提示:

1) Continue 2) Read-only mount 3) Skip to shell 4) Quit (Reboot)

一般选1,让救援环境自动挂载原系统到/mnt/sysroot。如果根分区是 LUKS 加密,会先提示输入加密密码。如果自动挂载失败,可以选3进 shell 手动挂载:

# 激活 LVM vgchange -ay # 查看逻辑卷 lvs # 挂载根分区 mount /dev/mapper/rhel-root /mnt/sysroot

如果是 LUKS 加密,先解锁:

cryptsetup luksOpen /dev/sda3 cryptroot vgchange -ay mount /dev/mapper/rhel-root /mnt/sysroot

如果是软 RAID,先组阵列:

mdadm --assemble --scan

这些命令不需要全记,救援环境里通常有lsblk、blkid、pvs、vgs、lvs,先用它们看清楚磁盘结构,再决定挂哪个设备。

4.3 chroot 重置密码与 SELinux 处理

原系统挂到/mnt/sysroot后,执行:

chroot /mnt/sysroot passwd root touch /.autorelabel exit reboot

和rd.break的逻辑一样:chroot进去改密码,touch /.autorelabel打 SELinux 标记,退出后重启。救援模式下passwd通常比rd.break更顺,因为/proc、/sys、/dev一般已经挂好,PAM 依赖齐全。

如果passwd报错说找不到用户或者读不了/etc/shadow,先确认/mnt/sysroot/etc/shadow是否存在,再确认挂载的是不是真正的根分区。有时候自动挂载挂的是/boot或者某个数据盘,chroot进去发现没有/etc,那就得手动重新挂。

4.4 LVM、LUKS、软 RAID 的处理

这三种存储结构在救援模式里很常见,处理原则是“先激活、再挂载”。LVM 用vgchange -ay激活卷组,lvs看逻辑卷路径;LUKS 用cryptsetup luksOpen解锁,解锁后通常会多出一个/dev/mapper/cryptroot设备,再在这个设备上找 LVM 或文件系统;软 RAID 用mdadm --assemble --scan扫描并组装。

一个容易忽略的点:如果根分区在 LVM 上,且卷组里有多个 PV,救援环境可能只识别到部分磁盘,导致卷组不完整。vgs会显示partial状态,这时候不要强行挂载,先确认磁盘是否都接好了。数据完整性比改密码重要,别为了救密码把文件系统搞坏。

4.5 修复引导的附加操作

有时候你进救援模式不只是为了改密码,而是 GRUB 也坏了。改完密码后可以顺手重建 GRUB 配置:

chroot /mnt/sysroot grub2-mkconfig -o /boot/grub2/grub.cfg

UEFI 环境下路径可能是:

grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

如果 GRUB 引导记录本身损坏,可能还需要grub2-install,但这个操作风险更高,UEFI 和 BIOS 的写法不一样,不确定的话不要乱执行。先把密码改回来、系统能启动,再处理引导问题。

5. 方式四:rescue.target / emergency.target 与单用户模式

5.1 RHEL 9 的单用户模式为什么经常“不好使”

很多老运维的习惯是“GRUB 里加个single或s进单用户模式”,这在旧版系统上很顺手。但 Red Hat 9.0 用 systemd 管理启动,single和s通常会被解析成rescue.target,而rescue.target启动后会执行sulogin,要求输入 root 密码。你本来就是忘记密码才来的,结果它让你输 root 密码,这就成了死循环。

所以严格说,传统的“单用户模式”在忘记 root 密码的场景里不是一条独立解法。它适合“密码知道,但系统服务起不来,需要进维护模式修配置”的情况。真正忘记密码时,还是得用rd.break或init=/bin/bash绕过sulogin。

5.2 rescue.target 的操作与密码门槛

如果你知道 root 密码,只是想进一个最小环境修东西,可以在 GRUB 的linux行末尾加:

systemd.unit=rescue.target

启动后会挂载本地文件系统,启动少量基础服务,然后提示输入 root 密码。输对后进入维护 shell。这个环境比init=/bin/bash完整,/proc、/sys、/dev都在,systemctl也能用,适合修 fstab、检查服务、看日志。

但它不适合忘记密码的场景。如果你不知道密码,进到sulogin提示时只能重启,换rd.break。有人会想“能不能在sulogin里用init=/bin/bash绕过”,可以,但那已经是第 3 节的方式二,不算 rescue.target 的功劳。

5.3 emergency.target 的差异

emergency.target比rescue.target更早、更小,只挂载根文件系统,几乎不启动其他服务。GRUB

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

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

立即咨询