☰
Linux root密码忘记怎么办?从系统到数据库的全套重置方案
2026/10/8 2:40:04 网站建设 项目流程

干了十几年运维,最怕半夜听到的一句话就是“root密码忘了”。这事不大,但足以让你在机房里对着屏幕发愣,或者在工单系统里跟甲方来回拉扯半小时。今天这篇东西,我就把自己这些年用过的root密码重置方案完整梳理一遍,从Linux系统本身的密码恢复,到MySQL、MariaDB这类数据库的root密码处理,全部是实测过、能直接落地的做法。

先说清楚一个边界:本文讲的“重置”和“破解”是两回事。所谓破解root密码,本质上是利用物理接触服务器的机会,绕过登录认证环节,直接改写系统里的密码哈希文件。它的前提是你对这台机器有硬件的访问权限(键盘、屏幕、或者带外管理口)。如果你是想在没有任何授权的情况下攻破一台不在你手里的服务器,那属于另一条赛道,本文所有方法都不适用,也不该适用。

另外,所有操作都会触发系统的安全机制,比如SELinux或者文件系统只读挂载,这些细节我会重点标注,因为它们才是实际操作中最容易翻车的地方。

1. 先想清楚:root密码重置的底层逻辑

1.1 一段正常的Linux登录流程长什么样

Linux系统的用户登录认证目前最主流的方案是PAM(Pluggable Authentication Modules)。当你在登录界面输入root和密码,系统的认证链路大致是:login或sshd进程收到输入,交给PAM模块去校验,PAM根据 /etc/passwd 里的用户条目找到root的UID和shell信息,再从 /etc/shadow 里取出加密后的密码哈希,和你刚才输入的明文做同一种哈希算法比对,一致就放行。

这里有一个关键点值得注意:/etc/passwd 里的密码字段历史上曾经是明文或弱哈希,现在基本都用一个x占位,真正的哈希全部挪到了 /etc/shadow。shadow文件默认只有root能读,普通用户连看都看不到,这就是为什么系统的密码数据库相对安全。

当我们忘记了root密码,常规登录这条路就被堵死了,但认证链路本身并没有被堵死。我们绕过登录这一步,直接进入一个有权限改写 /etc/shadow 的环境,把里面的哈希替换成新密码的哈希,就等于重新配了一把新锁。

1.2 为什么绕过启动流程就能改密码

Linux系统从按下电源键到出现登录界面,中间有一大段流程,而这段流程恰恰是我们可以介入的窗口期。

无论是GRUB引导菜单、内核启动参数、单用户模式还是rescue急救模式,它们的共同点是在系统尚未完成完整启动时,先给你一个shell环境。这个环境可能是精简的initramfs环境,也可能是完整的根文件系统,但只要能挂载根分区、能写入shadow文件、能执行passwd命令,整件事就走通了一大半。

所以你可以把root密码重置理解为“在合适的时间点,以合适的身份,进入合适的文件系统,完成一次安全的提权操作”。前后两个合适的权重都很高,哪个没做到,都可能出现改完密码重启后照样进不去的尴尬局面。

1.3 方案选型对照:不同场景用不同思路

在实际工作中,服务器环境五花八门,可能是物理机、虚拟机、云主机,也可能是装有双系统的笔记本,所以选型很重要。不同方案的适用场景和操作复杂度完全不同:

方案适用场景核心原理复杂度
GRUB菜单注入内核参数单用户模式最常见,适用于绝大多数RHEL/CentOS系让内核以单用户模式启动,跳过密码验证低
rd.break 断点进入initramfsCentOS 7/RHEL 7及以上,偶见Ubuntu在内核加载后、根切换前中断,进入dracut环境中
systemd.unit=rescue.target适用于部分较新系统以救援目标模式启动,要求文件系统可写低
安装介质/rescue模式物理机、系统GRUB损坏时从镜像启动,挂载硬盘后改写shadow中
拆盘挂载修改最极端的物理机场景把硬盘拆到另一台机器上改文件高

2. 手把手实操:CentOS/RHEL系root密码重置全流程

2.1 关键步骤一:从GRUB菜单修改内核引导参数

这套方法我用的频率最高,基本上每两三个月就会碰到一次,适用于绝大多数RHEL家族系统。

第一步,重启服务器。在GRUB菜单出现时,按键盘的e键进入编辑模式。如果你的机器上有多个内核,选中你平时正常启动的那个版本就行,不用特意选旧内核。

第二步,找到以linux或linux16开头的那一行,它后面跟的是内核引导参数。这里要注意,不要改错行。有些系统里会同时有linux和linuxefi两行,选择当前引导模式对应的一行即可,但绝大多数BIOS启动的系统是linux16。

第三步,把这行参数的尾部的rhgb quiet删掉,替换成下面几个之一:

  • single:最经典的写法,内核会直接以单用户模式启动,等价于早期的“single”选项。
  • 1:很多时候和single等价。
  • init=/bin/bash:跳过init进程,直接拉起一个bash shell,非常粗暴直接。

第四步,按Ctrl-X或者F10启动。系统会进入一个命令行环境,可能有几种表现。如果进去之后发现文件系统是只读的,先手动重新挂载:

mount -o remount,rw /

如果不执行这一步,后面passwd命令会报错,告诉你无法写shadow文件。这里踩坑的人很多,我遇到过不止一个同事在只读环境下跑passwd,折腾半天一无所获。

第五步,执行passwd命令设置新密码:

passwd root

输入两次新密码,看到successfully字样就完成了。

第六步,如果之前启用了SELinux,强烈建议在根目录创建自动重标文件:

touch /.autorelabel

这个文件告诉SELinux在下次启动时对所有文件重新打标签,避免因为shadow文件的安全上下文错乱导致系统异常。然后执行重启:

exec /sbin/init

或者直接按组合键重启,也可以reboot -f。

2.2 关键步骤二:rd.break 断点重置的完整讲解

rd.break是RHEL7、CentOS 7系列里很经典的技巧。它的原理是让dracut创建的initramfs在根目录切换(switch_root)之前停下来,给我们一个环境。这个环境里的根文件系统挂载在 /sysroot 下,我们需要手动切过去。

操作路径如下。开机在GRUB菜单按e,同样找到linux16行,在末尾加上rd.break。按Ctrl-X启动。进入shell后,屏幕提示符通常是switch_root:/#,这个时候我们先检查挂载情况:

mount | grep sysroot

正常情况下 /sysroot 是只读挂载,需要先重新挂载成可写:

mount -o remount,rw /sysroot

把根目录切进去:

chroot /sysroot

现在你已经站在完整的根文件系统里了。执行passwd root,设置新密码。退出chroot环境,然后重启:

exit exit reboot

两次exit分别是退出chroot和退出临时shell。如果你不想麻烦,也可以在chroot里直接修改shadow文件,但用passwd命令是更安全、更不容易出错的方式,它会自动处理密码哈希的生成。

2.3 避坑指南:SELinux上下文与文件系统权限

这一小块内容非常重要,很多人改完密码重启后依旧无法登录,问题大概率出在这里。

SELinux开启时,每一个文件都有自己的安全上下文标签。/etc/shadow 属于 shadow_t 类型。当我们通过rd.break进入dracut环境,这个环境里的SELinux策略可能没有完全加载,在chroot之后修改的shadow文件,其安全上下文很可能被标记成了默认的etc_t或者其他类型。这种上下文错乱会导致下次启动时PAM模块尝试读取shadow,但被SELinux拦截,最终表现为密码验证失败或者登录异常。

解决办法就是我上面提过两次的:

touch /.autorelabel

这一步会让系统在下次启动时自动重新标记整个文件系统,虽然会增加一次重启时间,但能彻底解决上下文的隐患。如果你非常着急重启,可以不用autorelabel,而是手动纠正上下文:

chcon --reference=/etc/shadow /etc/shadow

但说实话,除非你非常确定自己在做什么,否则首选autorelabel。

另一个容易忽略的问题在虚拟机场景。如果你用的是云主机或者虚拟机,记得在修改GRUB之前,先确保通过VNC或者Web控制台能连接到这台机器的显示输出。因为这套操作全程需要可视化交互,如果连不到屏幕,后面的步骤根本没法操作。

3. Ubuntu/Debian系系统:recovery模式与root密码恢复

3.1 Recovery模式的操作差异

Ubuntu和Debian系在默认配置上和RHEL系有些区别,但重置root密码的思路基本一致。Ubuntu现在默认不允许root直接登录,安装时也没有设置root密码,登录用的都是sudo用户的密码。如果你忘了这个sudo用户的密码,或者真的需要恢复root密码,可以这样操作。

开机时按住Shift键不松,直到GRUB菜单出现。Ubuntu的GRUB菜单里有一个Advanced options for Ubuntu子菜单,进入后能看到带(recovery mode)字样的条目。选它启动,系统会进入一个recovery菜单,里面有一项是root,选中并回车。

这里有个细节:recovery模式的根文件系统默认也是只读的,所以第一件事依然是:

mount -o remount,rw /

然后修改用户密码。假设你的用户名叫ops:

passwd ops

如果你想同时给root设置密码并允许root登录,在Debian系上可以做,但要记得检查 /etc/ssh/sshd_config 里的PermitRootLogin配置,大多数情况下root默认是被禁止SSH登录的。

3.2 Debian/Ubuntu下用init=/bin/bash的技巧

不是每个Ubuntu版本都能顺利看到recovery mode菜单,特别是某些定制版或OEM系统,GRUB菜单可能被简化了。这个时候我们可以直接沿用前面CentOS的方法,在GRUB编辑界面给linux行尾部追加init=/bin/bash。

进入后的处理流程和RHEL系基本一样:

mount -o remount,rw / passwd root touch /.autorelabel exec /sbin/init

有一点需要注意:Ubuntu默认的root账户在 /etc/shadow 里通常被设置成不可登录状态,哈希字段是!或者*。即使你重置了密码,如果这个标志不被正确清除,依然无法登录。passwd命令会正确处理这种情况,它会用新哈希替换掉原来失效的字段。但如果你选择手动编辑shadow文件,务必确保第三个字段(哈希字段)不是!开头。

3.3 关于麒麟、统信等国产系统的兼容情况

近几年国产操作系统在政企环境里部署量很大,像麒麟、统信UOS这些系统,底层都是基于Linux内核的,有的是基于Debian、有的基于CentOS衍生的。使用前面讲的GRUB编辑内核参数和init=/bin/bash方法,在绝大多数情况下都能兼容。

具体操作时,个别版本可能对GRUB的编辑界面做了一些定制封装,但内核引导参数的修改逻辑是通用的。遇到问题时,先别急着怀疑系统不兼容,多数情况反而是GRUB菜单被隐藏了或者需要先按某个快捷键才能进入。这事我在一些政务内网的机器上实操过,方法完全可行。

4. 数据库root密码重置:MySQL和MariaDB实战

4.1 看到error 1045不慌张,先定位问题

数据库的root密码忘记,是运维日常里的另一个高频翻车点。典型报错长这样:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

看到这个错误,不要急着操作,先冷静分析一下。它有三种常见情况:密码确实记错了;密码正确但root账户的host限定导致匹配不上;账号被锁或密码过期策略导致认证失败。

对于第一种情况,最经典的处理方法是用skip-grant-tables参数跳过授权表,进入数据库内部改密码。接下来的操作以MariaDB和MySQL 5.7为例,这两个是目前存量最大的版本。

4.2 skip-grant-tables 模式下的完整密码修改过程

第一步,停止数据库服务。用systemd管理的系统执行:

systemctl stop mysqld

MariaDB的服务名则可能是mariadb,建议先用systemctl list-units | grep -i -E 'mysql|maria'确认一下服务名。

第二步,用跳过授权表的方式启动数据库:

mysqld_safe --skip-grant-tables --skip-networking &

这里重点提醒一下:加--skip-networking参数非常重要,它的作用是让数据库只接受本机socket连接,不监听TCP端口。因为跳过授权表等于完全没有认证机制,如果监听外网端口,那就相当于把数据库裸奔在网络上。内网也不能大意,这个参数一定要加。

第三步,用root身份免密进入数据库:

mysql -uroot

进入后,第一步执行:

FLUSH PRIVILEGES;

为什么要先执行这条指令?因为跳过授权表启动时,MySQL的权限模块其实没有正常加载,直接去UPDATE相关系统表经常会因为权限缓存加载不全而报错。先刷新一次,让权限系统重新初始化,再执行修改密码的命令。

修改密码的具体写法取决于版本。MySQL 5.5/5.7和MariaDB的老版本可以用UPDATE方式:

UPDATE mysql.user SET authentication_string=PASSWORD('新密码') WHERE user='root' AND host='localhost'; FLUSH PRIVILEGES;

MySQL 5.7.6之前支持PASSWORD()函数,5.7.6之后这个函数被标记为废弃,但短期内仍可用。MariaDB用户则还可以使用:

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('新密码');

对于MySQL 8.0以及较新的MariaDB版本,推荐直接用ALTER USER:

ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'; FLUSH PRIVILEGES;

第四步,退出数据库,停掉基于skip-grant-tables启动的进程,再以正常方式启动数据库:

mysqladmin -uroot -p shutdown systemctl start mysqld

然后正常登录验证。

4.3 MySQL 8.0与MariaDB的差异化坑点

MySQL 8.0把默认认证插件换成了caching_sha2_password,这一点在实际操作中有两个坑值得单独说。

第一个坑是如果你用老版本的客户端连接MySQL 8,即使密码设置正确,依然会报认证插件不支持的错误。解决办法是重新创建一个使用mysql_native_password插件的账户,或者在配置文件中调整default_authentication_plugin。

第二个坑出现在skip-grant-tables模式下。如果你跳过授权表启动后直接ALTER USER,有些版本会报异常,此时需要严格按照上面写的顺序:先FLUSH PRIVILEGES,再ALTER USER。此外,MySQL 8.0的root账户host字段往往不止localhost一个值,记得先查一下:

SELECT user, host FROM mysql.user WHERE user='root';

确保自己修改的是实际登录时命中的那条记录。

MariaDB的坑则在于它的一些版本默认没有my.cnf里的socket路径,或者skip-grant-tables启用后socket文件位置变了,导致mysql -uroot连不上。这种情况加上--socket=/var/lib/mysql/mysql.sock指定一下即可。

5. 常见问题与排查技巧实录

5.1 问题速查表

把这个问题拆开来看,绝大多数失败案例都能归到下面这几类,我把它整理成速查表,方便对照排查:

现象根因分析解决办法
按e进入GRUB编辑后找不到linux开头行系统使用UEFI方式引导,可能显示的是linuxefi或vmlinuz前缀不同找以linux或linuxefi开头的行即可,别死盯linux16
passwd报“permission denied”文件系统以只读方式挂载执行mount -o remount,rw /
改完密码重启后依旧登录失败SELinux上下文错乱重启前touch /.autorelabel,强制重标一次
rd.break后找不到root文件系统dracut环境和实际根分区挂载点不同先确认 /sysroot 是否挂载,没有就先mount它
重启后进入不了GRUB菜单GRUB菜单被隐藏或超时极短开机时连按Shift或多次按Esc(不同固件按键不同)
SSH无法用新的root密码登录sshd_config禁止root远程登录修改PermitRootLogin yes并重启sshd
数据库改完密码后服务无法启动残留了skip-grant-tables进程在/tmp、/var/lib/mysql下查pid文件,清理旧进程后重启

5.2 重置完密码之后的收尾工作

改完密码不是结束,后续的收尾同样重要,否则容易留下隐患。我常说一句话:每次紧急密码重置,都是一次安全审计的契机,就看你想不想接住这个彩蛋。

首先,检查一下这台机器上原本是否有其他用root密码的服务,比如cron脚本里写死数据库密码、备份脚本里明文存了系统密码。重置完root密码后,这些脚本会立刻失效。与其到时候被报警电话吵醒,不如现在就全部改一遍。

其次是登录历史的清理。如果你在编辑GRUB时顺手把内核参数改了,或者临时修改过shadow文件,这些操作会留在shell历史上。保险起见,执行一次:

history -c

如果是在chroot环境里操作,退出后也可以在正常环境里清一遍。

然后是密码策略检查。既然都进到系统里了,顺手看一眼/etc/login.defs里的PASS_MAX_DAYS和PASS_MIN_LEN,以及/etc/security/pwquality.conf里对密码强度的要求,确保新密码符合公司内部的密码规范。

最后想提一个长期方案。单台服务器靠人记密码本身就是不靠谱的,应对这种问题的根治办法是把密码交给集中身份认证管理。无论是搭建FreeIPA、微软AD,还是轻量级的LDAP认证,都比一台台机器单独维护root密码省心得多。服务器再配合上带外管理口(IPMI/iDRAC),就算密码全部失联,你依然能从带外通道进入BIOS和引导界面,走完一遍前面讲的重置流程。

6. 实测心得:一次典型的CentOS 7密码恢复完整记录

分享一次我自己处理的典型过程,把前面讲的方法串起来。场景是一台内网CentOS 7服务器,root密码在某次密码策略调整后彻底记不清了,业务方催得急,我先通过带外管理口拿到了服务器屏幕。

开机进入GRUB后,按e进入编辑界面,在linux16开头的行尾追加了rd.break,保存启动。系统进入switch_root环境后,我按照顺序执行了mount -o remount,rw /sysroot、chroot /sysroot、passwd root。因为知道这台机器开了SELinux,所以我在退出前touch了/.autorelabel,然后连续两个exit回到引导流程。

重启后这台机器在重标文件系统时多花了两分钟左右,完成后正常进入了登录界面,用新密码成功登入。整个操作从开机到登入,大概花了十五分钟,真正动手的时间不超过三分钟。

整个过程中最关键的一步其实是touch /.autorelabel。我第一次处理这种问题是很多年前,当时没有这个操作,改完密码重启后怎么都登录不了,卡在PAM认证失败,最后只能再走一遍流程,这次才意识到是SELinux上下文的问题。从那以后,只要是SELinux enforcing环境的机器,这个文件我一定会touch。

最后再送一个小技巧:如果你手边没有带外管理,而且服务器重启会产生很大的业务影响,别急着在业务高峰期去动这台机器。可以先找一个业务低峰期,提前演练一遍流程,确认每个操作步骤的耗时,减少真正出现问题时的慌乱。另外,密码重置完成后,记得立刻把新密码记录到团队共享的密码管理工具里,避免过两个月又打一次同样的工。

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

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

立即咨询