Linux root密码忘记了?详解grub单用户、rd.break方法
root密码忘了这大概是Linux运维里最经典也最常翻车的故障之一。十个运维老手八个都撞上过剩下那两个是还没来得及撞上。这种时刻的处境很特殊服务器上服务还跑着业务也没断可你手里就是没有一把能进系统的钥匙所有需要提权的操作全部卡死那种“系统明明活着却由不得你”的感觉确实难受。不过说句公道话这属于完全可修复的故障不是要重装系统的绝症。Linux的密码本身不是明文存储也拿不回来只能重置。重置的思路是绕过登录校验、进入特权环境然后重新生成密码。这篇就把主流路径完整理一遍grub菜单进单用户模式、rd.break、Live CD再补上新版发行版、麒麟这类国产系统、甚至嵌入式Linux的特殊处理。不管是虚拟机里的实验环境还是机房里的生产服务器这套方法论基本都适用。不需要多深的背景跟着步骤走就能操作。1. 先搞清楚一件事密码重置到底在重置什么1.1 为什么密码“找不回来”只能“改掉”Linux的用户密码存在 /etc/shadow 文件里root 用户那一行是这种格式root:$6$randomsalt$hashingresult:19000:0:99999:7:::第二个字段是密码哈希以 $6$ 开头表示 SHA-512 算法现在新系统还有 $y$yescrypt。这个哈希是把明文密码加上随机盐做单向计算得到的计算过程不可逆。所以“找回密码”这种事在Linux上从技术角度就不存在——你能做的只有生成一个新密码覆盖旧的哈希。明白了这一点再看后面的操作就不会觉得奇怪所有方法本质上前两步都是“想办法在一个不需要密码的环境里拿到root shell”第三步是“执行passwd覆盖哈希”。1.2 三条主流路径选哪条看现场条件每次遇到这种问题我习惯先按现场条件选出最合适的一条路而不是盲目照搬教程方案适用场景门槛风险点grub菜单进单用户/紧急模式本机能重启、能进grub菜单低部分系统单用户模式也要密码rd.break重置RHEL/CentOS系grub可用中SELinux、sysroot挂载概念绕人Live CD / 救援U盘grub进不去、引导损坏、全盘加密中需要额外介质流程稍长我的经验是能进grub就优先用grub路线其中RHEL系直接上rd.break最省心Debian/Ubuntu系走recovery mode如果连grub菜单都看不到再掏出Live CD。下面从最常用的路径开始拆解。2. 最核心的一招grub编辑启动项进入单用户或紧急模式2.1 怎么进grub菜单一次说清不同固件的按键这一步卡住的人最多。grub菜单通常在开机自检后出现几秒不进则直接引导系统。要在菜单出现时按下对应按键BIOS传统模式开机时快速按 Shift甚至可以在按下电源键后就不停点Shift直到菜单出现UEFI模式连按 Esc 或 Delete不同主板逻辑不同虚拟机里VMware Workstation、VirtualBox 通常能直接在启动画面看到倒计时不需要按键停留时间足够还有个容易忽略的坑如果系统管理员把 grub 超时时间改成了 0GRUB_TIMEOUT0菜单就一闪而过甚至根本不显示。这种情况开机时同样靠按 Shift/Esc 强留但如果连这都进不去就直接跳去看后面的 Live CD 方案。2.2 systemd时代的标准操作CentOS 7/8、Debian系通用主流发行版现在都跑systemd启动流程统一了重置步骤其实大同小异。以 CentOS 7/8 为基准Debian、Ubuntu 照做就行只是启动行名字有细微差别。第一步在grub菜单里选中你的内核不要按回车直接按字母 e 进入编辑模式。找到以 linux16CentOS 7或 linuxCentOS 8/9、Debian、Ubuntu开头的那一行把里面的ro改成rw然后在行尾追加systemd.unitemergency.target改完之后按 CtrlX 启动。系统会直接进入紧急模式基本上是一个root shell但文件系统可能还挂在只读状态。先手动确认一下mount -o remount,rw / passwd root touch /.autorelabel reboot这里每一步都有讲究。ro改成rw是告诉内核挂载根分区时直接以读写方式挂载如果不改进紧急模式后 /etc/shadow 是只读的passwd 会报Authentication token manipulation error。行尾那个systemd.unitemergency.target是让 systemd 绕过正常的 multi-user 启动流程不加载各种服务直接只起一个 shell自然也不会有密码校验。touch /.autorelabel是SELinux相关后面专门讲。2.3 单用户模式被密码锁住怎么办很多教程让你直接在启动行加single或数字1进入单用户模式再改密码。这个说法在老系统上成立但在不少新发行版上有个隐患单用户模式启动后systemd 会调 sulogin要求输入 root 密码才能继续。如果你就是忘了root密码这一步就直接被卡死了。所以我的默认选择是emergency.target或 rd.break而不是单纯的single。如果真的只有 single 模式可用并且提示需要密码别死磕两台机器之间来回切换太浪费时间直接用后面的 rd.break 方案原理上一脉相承但绕过了这套校验。2.4 老系统也别慌SysV init时代从kernel行加参数CentOS 6、Debian 7 这类用 SysV init 的老系统grub 通常还是第二代甚至第一代。操作逻辑更简单grub菜单选中内核按 e 进入编辑在kernel那一行末尾追加single或数字1然后按 b 启动。系统会直接进入单用户shell没有密码询问直接passwd root完事。这个原理是init 1 只挂载最基础的文件系统、不启动任何服务也无需求助登录认证模块所以跳过了密码校验。反过来也能看出来为什么很多人查资料时会看到“single模式”这个说法——它确实是老一代系统最标准的恢复路径。3. 两条稳妥的后备方案rd.break和Live CD3.1 rd.breakRHEL/CentOS系最值得掌握的一招在 RHEL 系机器上我遇到紧急修改需求时最常用的是 rd.break因为它停在内核加载后的早期阶段绕过了绝大多数可能的拦截。操作步骤grub菜单按e编辑依旧把ro改成rw在linux16或linux行尾追加rd.break enforce0按 CtrlX 启动。系统会停在一个提示符面前通常是switch_root:/#。这个环境来自 initramfs临时根文件系统此时你的真实根分区其实挂载在 /sysroot 目录下而且这个目录还是只读挂载的。依次执行mount -o remount,rw /sysroot chroot /sysroot passwd root touch /.autorelabel exit exit reboot第一次 exit 离开 chroot 环境回到 switch_root第二次 exit 会继续走完剩余启动流程然后自动重启。为什么这个方案稳rd.break 在 systemd 接管前就停了下来根本没有登录校验的阶段不管单用户模式有没有设密码锁都拦不到你。enforce0是临时把SELinux切到宽容模式避免后续操作被安全策略打扰。3.2 和rd.break配套的SELinux自动打标签RHEL/CentOS 系重置完密码重启时偶尔会卡在一个奇怪的界面或者登录后各种服务起不来大概率是SELinux上下文出了问题。这也是我为什么每次都在 chroot 环境里顺手执行touch /.autorelabel的原因。SELinux给每个文件维护一个安全上下文存在文件系统的扩展属性里。一般我们自己改密码、改配置文件不会动这个属性但有些操作会改变文件的 inode 元数据导致上下文错乱。touch /.autorelabel是在 / 下留一个标记文件重启后SELinux会自动对整盘重新打标签把上下文恢复正常。代价只是重启多等几分钟换来的是不会在登录环节遇到玄学问题这笔账值得算。3.3 Live CD / 救援U盘grub进不去时的万能兜底grub菜单坏掉、引导直接损坏、或机器上有 LUKS 全盘加密需要先解锁那就得上 Live CD。准备一个启动U盘里面放任何带图形界面的 Linux 发行版 ISO 就行Ubuntu 桌面版、官方 minimal 镜像都可以。启动后打开终端lsblk先看清楚磁盘分区结构确认哪个分区是真正的根分区。然后挂载它mount /dev/sda2 /mnt mount --bind /dev /mnt/dev mount --bind /proc /mnt/proc mount --bind /sys /mnt/sys chroot /mnt passwd root挂在 /proc、/dev、/sys 是因为 chroot 之后 passwd 这些基础命令要跟内核交交互缺了会报一些奇怪的错。如果根分区是 LVM 逻辑卷先执行lvscan看卷名vgchange -ay激活卷组再挂载对应路径。如果是 LUKS 加密分区需要先cryptsetup luksOpen /dev/sda2 luksroot之后挂载 /dev/mapper/luksroot。进入 chroot 环境之前强烈建议先把 /etc/shadow 备份一份cp /etc/shadow /etc/shadow.bak万一操作失误至少还能把原文件拷回来。这个习惯让我避免过至少两次大麻烦。4. 不同发行版和特殊环境的差异处理4.1 Debian/Ubunturecovery mode其实是捷径Debian 和 Ubuntu 的 grub 菜单里自带一个「Advanced options for ...」子菜单展开后能看到带(recovery mode)字样的内核条目。选进去之后会进入一个文本菜单里面有一项叫root通常显示为 Drop to root shell prompt。按回车确认后会得到一个 root shell。需要注意Ubuntu 的恢复模式默认会把根分区挂成只读进去之后先执行mount -o remount,rw /再改密码。另外 Ubuntu 20.04 之后如果开了全盘加密选择 recovery mode 后会先要求解锁 LUKS 分区解密成功才能进入 root shell这一步需要的是 LUKS 密码而不是root密码别搞混。还有一种在 Debian/Ubuntu 上也很管用的方法grub编辑启动行把ro quiet splash从命令行里删掉或替换成rw init/bin/bashCtrlX 启动后会直接掉进一个 bash shell。这个环境不需要登录文件系统就是读写状态直接passwd root即可。这里的关键是启动参数里必须带rw否则 shell 起来后文件系统还是只读改不了 shadow。4.2 麒麟这类国产系统操作同源别紧张银河麒麟、中标麒麟这些国产Linux桌面和服务器系统大多数底层还是由 Ubuntu 或 CentOS 的包体系衍生而来。收到这类机器的重置需求时不要先入为主觉得“国产系统都不一样”——实际上键盘上按的操作逻辑基本一致。桌面板通常走 grub 的 recovery mode字段和 Ubuntu 一样linux行末尾追加systemd.unitrescue.target也能进紧急模式。服务器版继承了 RHEL 系的风格直接用rd.break就行。真正需要注意的只是不同版本对linux16和linux的命名差异老版本可能还会走旧的 grub 编辑方式但总体判断方法一样先看grub.cfg里内核条目是什么写法再决定改哪一行。遇到精简掉 recovery 菜单的定制版直接在启动行加init/bin/bash也经常可行。4.3 嵌入式Linuxu-boot和busybox环境下怎么处理跑在开发板、交换路由类设备上的嵌入式Linux启动引导一般不是grub而是 u-boot。重置密码的思路是在 u-boot 倒计时阶段按任意键打断启动进入 u-boot 命令行然后修改 bootargs 让内核以单用户方式启动setenv bootargs consolettyS0,115200 root/dev/mmcblk0p2 rw init/bin/sh boot串口终端会直接得到一个 sh。嵌入式环境多半是 busybox命令集非常精简但通常保留了 mount、passwd。依次执行mount -o remount,rw / passwd root如果这套系统精简到连 passwd 命令都没有另一个备选是直接改 /etc/shadow。把 root 行的第二个字段密码哈希清空变成root::0:0:root:/root:/bin/sh然后重启root 无密码登录。但这里我必须提醒一句清空密码这个操作在常规Linux上容易踩出大坑不少发行版在 PAM 配置里会直接拒绝空密码的 root 登录你反而把系统锁得更死。所以只在嵌入式或确有把握的现场才会这么干正常系统一律老老实实用 passwd 生成新哈希。5. 重置之后千万不要直接下单走人5.1 先确认SELinux状态再谈重启RHEL系机器如果走的是 rd.break 方案我前面专门说过touch /.autorelabel。这块值得再强调一次不要抱有侥幸心理跳过它。虽然大部分情况下纯改密码不动SELinux上下文但如果你用 Live CD 改过 shadow、或者在 chroot 里做过额外操作上下文的异常就可能在重启后才浮现表现是系统启动到一半卡在Failed to load SELinux policy或者服务大批量启动失败。真到那一步又得切回单用户模式补上 autorelabel白白花两趟时间。确认SELinux当前是 enforcing 还是 disabled也是排查环节该做的事getenforce如果显示 Disabled说明系统本来就没开SELinux那 autorelabel 也不会执行不必担心。5.2 换个合规又够强的密码别给后面留雷用 passwd 改密码时fedora系和多数现代发行版都装了 pam_pwquality 或 pam_cracklib密码太简单会直接被拒掉提示BAD PASSWORD。这其实是个保护机制但很多人不知道以为自己操作有问题反反复复改同一个弱密码每次都被打回。正确做法是换一个有大小写、数字、符号的密码长度至少12位。重置完成先别急着重启建议当场用新密码重新登录一次确认能收到 shell。如果这台机器是线上服务器开了 SSH 远程登录还要额外注意一点sshd_config 里默认是PermitRootLogin prohibit-password意思是不允许用密码直接 SSH 登录 root只接受密钥。这种情况下即使密码重置成功远程用密码也登不进去不代表操作失败是策略在挡。要放行密码登录得改这一行并重启 sshd但更好的做法本来是保持密钥登录、永远不开放 root 密码远程登录。5.3 重置完顺手做一次安全检查密码丢失本身有几种可能自己忘了、交接时没人告诉你、或者机器被入侵后别人改掉了密码。如果是最后一种光重置密码远远不够。进系统后先看最近谁登录过last lastb重点检查 /root/.ssh/authorized_keys 里有没有陌生的公钥再翻一遍 /etc/passwd 里有没有新增的uid为0的账号。被入侵的机器攻击者通常会在这几个位置留后门。排完雷才值得把密码收进密码管理器之后定期轮换。6. 常见问题速查和踩坑实录6.1 一页纸上列清楚的问题排查表现场现象可能原因解决办法开机grub菜单一闪而过超时被改成了0开机时快速点按Shift或Esc强留编辑启动行后按CtrlX没反应键盘没被grub识别BIOS里开启Legacy USB支持换USB 2.0口试试单用户模式仍提示输入密码sulogin需要root认证改用 rd.break 或 Live CDpasswd命令报token manipulation error根分区只读挂载执行 mount -o remount,rw / 再试改完密码重启卡在SELinux阶段上下文异常或autorelabel缺失进紧急模式执行 touch /.autorelabel新密码明明对登录却说认证失败密码策略拒绝了弱密码用至少12位的强密码组合重试能搜到设备但就是连不上SSHroot默认禁止密码登录核查PermitRootLogin本地登录后调整sshdLive CD chroot后命令找不到没有挂载proc/dev/sys补齐 mount --bind /dev /proc /sysLVM根分区挂载不上卷组没激活执行 vgchange -ay 后重挂载LUKS加密分区不解锁根分区密文无法读取cryptsetup luksOpen 后挂载 mapper设备6.2 三个踩过的真实坑第一次用rd.break的时候我漏改了ro到rw进入 switch_root 环境后照着网上的命令一路执行到 passwd结果报权限错误。排查半天才发现真正问题/sysroot 虽然是挂载状态但只读chroot 进去之后 /etc/shadow 只读所有写操作全被拒绝。加上mount -o remount,rw /sysroot之后立竿见影。这个顺序我后来一直没变过。还有一次在一台CentOS 7上我图省事用 Live CD 直接改 shadow 文件重启后系统卡在 SELinux 初始化。那次的问题出在我挂载到 /mnt 后用 sed 直接替换了 shadow 内容额外改动触发了文件上下文异常。补上 autorelabel 并重启自动打标签后才恢复。从那以后只要碰 RHEL 系机器我必做 autorelabel就算没异常也求个安心。第三个坑是遥远的CentOS 6时代当时改完密码准备重启输入 reboot 之后系统直接卡住不响应。后来才知道 chroot 环境或者单用户模式下直接 reboot 可能走到错误的 target应该先用sync把缓存落盘再reboot -f强制重启。这个经验在 SysV init 老系统上尤其关键。还有个小乌龙值得提一下网上搜“root密码忘了”的不少其实是在找 MySQL 的 root 账号密码。MySQL 也报ERROR 1045 (28000): Access denied for user rootlocalhost但那是数据库应用层的账号跟系统 root 没关系重置路径要另走 skip-grant-tables。想想要是拿这篇的 grub 操作去救数据库方向就完全跑偏了。最后说点实在的这类故障处理多了我的体会是重置密码本身不难难的是现场心态和执行细节。按e找对行、ro改rw、rd.break之后不慌、touch /.autorelabel 别跳——每一条都是拿实际翻车换来的经验。另外一个平时就该养成的习惯是在机器硬件上留一把“物理钥匙”——一块始终带在身边、能启动 LiveCD 的小U盘。真哪天grub坏了、密码没了、引导崩了插上U盘十五分钟就能把系统捞回来。再就是把 root 密码收进密码管理器开了 SSH 密钥登录之后基本也只有服务器初始化和排障才用得上了。准备好这套应对方案root失联就不再是深夜刺穿心脏的那声报警只是一次按着清单走完的标准操作。