ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

root密码重置全场景指南:Linux系统与数据库一次讲透

root密码重置全场景指南:Linux系统与数据库一次讲透 干运维这行我敢说三分之二的人迟早要搜一次“重置root密码”。我自己处理过不下五十次有帮客户救业务的有自己测试环境里故意搞挂又练手的还有一次凌晨三点被朋友电话叫醒他那台CentOS 7服务器root登不上去业务还挂着。root密码丢失这事从来不是“会不会发生”而是“什么时候发生”。所谓重置root密码本质上就是一句话在系统正常加载认证流程之前截住它让自己以root身份拿到一个shell然后把/etc/shadow里的密码改掉。但这句话落到不同发行版、不同虚拟化平台、不同数据库上操作路径千差万别踩坑点也五花八门。这篇文章我打算把CentOS/RHEL、Ubuntu/Debian、ESXi虚拟机、还有MySQL/MariaDB的root密码重置方法一次性讲透重点是那些教程里不会写的报错和失败场景。1. 从“长期没登录”到“锁死在门外”root密码丢失的典型场景1.1 最常见的丢失场景root密码最容易丢的场景翻来覆去就那么几个。服务器刚装完就被扔到机房或者云上之后一直用普通用户配sudo干活一两年没人碰root账户等真要用了密码早忘干净了。离职交接的时候文档里只写了IP和业务密码那一栏永远是空的。安全整改要求定期改密码改完新密码没人记录三个月后全员失忆。还有一个特别典型的有些人装CentOS 7时习惯直接禁止root远程SSH登录平时只在本地控制台用root。平时没事一旦机房断电重启、需要紧急维护你连本地登录这一关都过不去。这时候搜“重置root密码”就不是什么理论知识了是实实在在的救命操作。1.2 动手前先确认两件事第一你能不能进GRUB重置root密码的所有主流方案不管是单用户模式、rd.break还是init/bin/bash全都绕不开GRUB启动菜单。如果你用的是托管型服务器厂商锁了GRUB或者不允许改启动参数那本地重置这条路基本走不通只能靠云厂商的VNC控制台或工单通道。第二root所在文件系统是不是加密的如果整块磁盘做了LUKS全盘加密没有解密密钥的情况下rd.break也好、单用户也好全是白搭——initramfs根本没能力挂载真正的root分区。这种环境的密码找回只能靠你保存的密钥文件或密码技术手段绕不过强加密。还有一点心态上的准备别慌。重置root密码本身不破坏数据它改的只是认证信息。真正危险的是应急状态下乱敲命令把分区挂载状态搞乱或者在initramfs里对根分区做了不可逆操作。稳一点按步骤来基本不会出事。2. CentOS 7 / RHEL 7rd.break 应急重置全流程2.1 完整操作从GRUB编辑到改写passwordCentOS 7系是我处理过最多的系统因为存量实在太大了。它最靠谱的重置方法就是rd.break完整流程如下。第一步重启服务器。物理机重启后迅速按上下方向键锁定GRUB菜单虚拟机在控制台里重启同样在开机瞬间按方向键。CentOS 7的GRUB默认倒计时只有5秒手速要快没赶上就等它进系统然后再次重启。第二步在GRUB菜单上选中要启动的内核条目按e进入编辑模式。找到以linux16或linux开头的那行在行尾追加参数注意前面留一个空格rd.break enforcing0enforcing0的意思是本次启动临时关闭SELinux强制模式。加上它后面能省掉很多麻烦就算你想保持SELinux开门也不影响重启后自动恢复。第三步按CtrlX启动。系统会加载initramfs然后停在一个switch_root之前的紧急shell里提示符通常是switch_root:/#这时真正的root目录已经被挂载在/sysroot下但默认是只读。第四步把/sysroot重新挂载为可写mount -o remount,rw /sysroot第五步进入真正的root环境chroot /sysroot提示符变成bash-4.2#之类说明你现在就在原系统的根目录里。第六步修改root密码passwd root按提示输入两次新密码即可。如果想在脚本里批量操作CentOS 7支持这种方式echo 你的新密码 | passwd --stdin root不过我提醒一句这种方法会让明文密码短暂出现在内存和shell历史里生产环境还是老老实实交互输入吧。第七步重置SELinux标签这是很多人必漏的一步touch /.autorelabel创建一个空文件系统下次启动时会检测到它并对整个根文件系统做一次完整的SELinux重新标记。不做这一步在某些SELinux强制环境下你改完密码重启后会发现登录总是失败而且报错莫名其妙。第八步退出chroot并重启exit reboot -f先退出chroot回到switch_root环境然后强制重启。有些教程会让你连续exit两次让initramfs继续走完剩余启动流程直接进系统这在大部分CentOS 7上也行。我习惯直接reboot逻辑更清晰。等系统起来用新密码登录root任务完成。2.2 为什么rd.break能绕过密码边界在哪rd.break是dracut框架提供的内核启动参数。initramfs在把控制权交给真正的root文件系统之前会先做一系列准备加载驱动、组装md/LVM、解密LUKS、挂载根分区。rd.break就是在这些准备做了大概一半的时候插入一个紧急shell。关键点在于这个阶段系统根本没有进入正常的sysinit流程PAM、login、sshd全都没起来认证体系不存在你自然不需要密码就能操作root文件系统。它的边界也很清晰它只能帮你改“放在磁盘上”的东西。如果密码存在LDAP、AD这类外部认证体系里rd.break改本地/etc/shadow是没有用的因为系统根本不会查本地账户。碰到这种情况思路要从“改本机密码”转成“找回外部认证凭据”。另一个边界是版本。CentOS 7、RHEL 7、CentOS 8、Rocky Linux、AlmaLinux这套流程基本通用。CentOS 6是System V风格没有rd.break概念得用单用户模式加passwd。RHEL 9的GRUB默认隐藏菜单启动时连按Esc或方向键能把菜单调出来后面的操作一样。2.3 备选方案内核命令行加 init/bin/bash如果你对rd.break不熟或者它在你机器上报错可以改用另一种。还是编辑GRUB的linux16行把行里的ro改成rw然后在末尾追加init/bin/bash启动后系统直接以bash作为PID 1拉起不跑任何服务也不做认证。此时root分区已经以可写状态挂好直接执行passwd root输入新密码然后reboot -f重启。这里有个坑因为bash充当了init进程不能直接使用正常的reboot要用reboot -f强制重启或者先执行exec /sbin/init让服务拉起来再正常重启。两种方法各有适用场景我来做个对比对比项rd.breakinit/bin/bash适用版本CentOS 7/8/9、RHEL 7、Rocky、Alma几乎所有Linux发行版挂载方式root挂在/sysroot需手动remount启动时直接ro改rw正常挂载对普通用户友好度较高有明确提示较低容易忘remount遗留文件系统风险较低较高PID 1由bash充当我的推荐度首选备选相比之下我更推荐rd.break。init/bin/bash在某些系统上会导致后续文件系统状态不干净比如journald没跑、日志分区没正确挂载。生产环境别折腾除非你很清楚自己在干什么。3. Ubuntu / Debian恢复模式、单用户模式、还有 ESXi 控制台输入失效3.1 恢复模式操作Ubuntu/Debian系跟Red Hat系有个本质区别默认不允许root直接用密码登录root账户初始是未设置密码或者被锁定的。所以在Ubuntu上“重置root密码”有两种理解。一种是你知道sudo账户的密码只是单纯想给root设置或修改密码一条命令就行sudo passwd root如果你连sudo账户都进不去那就要走恢复模式了。Debian系的Kali、Ubuntu Server这些发行版流程基本一致只是默认账户名可能不同改密码时把用户名换成目标账户即可。第一步重启在GRUB菜单出现时按住Shift键BIOS启动或狂按Esc键UEFI启动调出菜单。第二步选择“Advanced options for Ubuntu”然后选择带“(recovery mode)”后缀的内核条目。第三步系统进入Recovery Menu选择“root - Drop to root shell”。第四步此时进入root shell但文件系统通常是只读挂载的。先执行mount -o remount,rw /注意这里是/不是/sysroot这是和CentOS最大的区别。第五步执行passwd root输入新密码然后reboot。这里补充一个细节Ubuntu里passwd root之后root账户就解锁了。如果只是临时维护维护完建议把它锁回去sudo passwd -l root-l参数把root锁定效果相当于删掉root密码避免机器上长期存在一个有效的root口令。3.2 单用户模式容易卡在“Give root password for maintenance”很多人照着老教程在GRUB里给内核参数加single结果开机后看到Give root password for maintenance (or press Control-D to continue):如果你不知道root密码就卡死在这里了。按CtrlD只会让系统继续正常启动起不到任何重置作用。为什么会这样因为single模式是让系统进入带root密码校验的单用户维护模式它默认还是走login认证的。而recovery模式里的root shell是预授权shell不校验密码。理解了这两者的原理你就明白为什么网上那么多人说“进不去”了——不是操作错了是这条路本身就设了密码门。所以要重置Ubuntu root密码别用single用 recovery mode 的root shell或者干脆用init/bin/bash。3.3 ESXi虚拟机里“CtrlD输入不了”的经典问题这个问题我在ESXi环境里实打实折腾过。场景是Ubuntu虚拟机在控制台里重启进入单用户模式/rescue模式屏幕停在Give root password for maintenance或者emergency mode提示符下键盘怎么点都没反应。先说根因。ESXi的Web控制台走的是HTML5客户端它对早期控制台的键盘捕获和键盘布局处理并不可靠特别是虚拟硬件里没配置USB键盘设备、只有PS/2的时候。再加上systemd切换vconsole时可能重新初始化键盘结果就是提示符在等输入但输入根本到不了虚拟机的控制台。踩过坑之后我的解决顺序是这样优先用VMware Remote ConsoleVMRC替代Web控制台。VMRC对键盘输入的模拟更完善大多数“输不进去”的问题换到VMRC就消失了。如果只能用网页端在提示符出现前先点一下虚拟机窗口给控制台焦点然后再输入。很多人其实是焦点丢了键盘事件全被浏览器吃掉了。实在不行放弃交互式救法用Ubuntu Server ISO引导进Live环境把系统盘挂载、chroot、改密码。在vSphere里给虚拟机挂载Ubuntu ISO从ISO启动选择“Try or Install Ubuntu”进入Live系统然后lsblk # 找出根分区假设是 /dev/sda3 mount /dev/sda3 /mnt mount --bind /dev /mnt/dev mount --bind /proc /mnt/proc mount --bind /sys /mnt/sys chroot /mnt passwd root exit reboot如果/boot是独立分区也把它挂到/mnt/boot。这套方法在ESXi里最稳因为Live环境是完整的系统键盘输入正常不受虚拟机厂商实现差异影响。我给朋友救ESXi里的Ubuntu最后基本都是这条路径收场。4. 重置路上的高频报错令牌操作错误与 root shell 打不开4.1 su: 鉴定令牌操作错误这个报错我见得太多了经常是重置root密码之后紧接着就遇到。现象是明明执行了passwd root系统也说密码更新成功但马上用su -切root报错su: 鉴定令牌操作错误或者英文环境下的su: Authentication token manipulation error。“鉴定令牌”是PAM翻译过来的说法指的就是/etc/shadow里那条密码哈希记录。这个报错绝大多数情况是passwd没能真正把新哈希写进shadow文件。排查顺序我来列一下先看文件系统是不是只读。在恢复模式里最容易犯这个错——你在root shell里直接执行passwd root但忘了先mount -o remount,rw /shadow文件只读当然写不进去passwd不会把“只读”直白告诉你就丢出这么个令牌错误。执行mount | grep / 看挂载状态如果是ro重新挂载rw再试。看SELinux。如果你在CentOS上重置完密码、重启后su和login全部失败日志里一堆avc denied八成是改密码过程中shadow/passwd的安全上下文标签被搞坏了。根治办法就是我前面说的touch /.autorelabel。急着恢复可以setenforce 0临时放行。检查shadow文件权限。执行ls -l /etc/shadow正常应该是root:shadow 0640或者root:root 0600。如果权限被改松了passwd出于安全策略会拒绝写操作这也是常见诱因。如果都没问题要考虑PAM配置是不是对root做了特殊限制比如/etc/pam.d/system-auth里显式调用了pam_deny或者系统接了域认证导致root被忽略。这种情况少见排查到了就是另一条线。4.2 starting with root... cant open root shell, try again... still not :(这个提示我在标准Linux服务器上没见过但在手机和嵌入式设备上很常见经常出现在一些root管理工具或者自定义脚本的输出里。字面意思很清楚脚本尝试以root身份打开一个shell打开失败重试还是失败。它出现的原因基本绕不开三样。一是su/sudo二进制不存在或者路径不对。很多精简过的rootfs只带busyboxbusybox里没有su命令或者功能被裁剪脚本一调用shell就失败。二是SELinux或dm-verity在限制root shell。像Android这类系统如果SELinux没被切到permissive是不允许最高权限进程随意fork出一个shell的表现就是“cant open root shell”。三是分区只读。嵌入式设备把system分区做成只读脚本想写临时文件或者换shell失败得毫无悬念。如果碰到的是这种环境先把“重置root密码”的通用套路放一放。你要做的是确认这台设备究竟有没有可用的root入口有没有串口调试口能不能进recoveryrecovery里有没有终端或文件管理器。嵌入式设备的救砖思路和服务器运维完全不同先定位入口再谈改密码不然很容易把系统搞得更糟。4.3 改完密码登录不上SELinux的坑一次说完这个坑我知道得特别深。CentOS 7上如果在rd.break里改了密码但既没加enforcing0也没touch /.autorelabel重启之后大概率出现这种情况root密码明明是对的但本地登录一直提示认证失败SSH登录也是反复拒绝。原因是你在initramfs阶段通过chroot改密码时SELinux标签体系是半初始化状态。passwd在那种环境下写入shadow文件文件的SELinux标签和正常启动阶段写入的不一致。重启后SELinux强制模式一开发现shadow文件的标签不对直接判定为异常访问禁止认证程序读取。日志里会看到大量的avc denied记录指向/usr/bin/passwd或unix_chkpwd对/etc/shadow的访问被拦截。解决方法就是我反复强调的那一条在chroot环境里touch /.autorelabel重启后系统会自动跑一次完整的文件标签修复并自动删除这个标志文件。如果你已经遇到登录失败的问题了还有救——用rd.break重新进一次touch之后再重启问题就消掉了。5. MySQL / MariaDB 的 root 密码重置跟系统 root 不是一回事5.1 error 1045 (28000) 到底在说什么数据库里的“root”也经常让人栽跟头。应用报错ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES)这里的root是数据库账户跟Linux系统root完全是两套东西重置方法也完全不同。error 1045的含义就是认证失败用户名、密码、客户端来源host、认证插件四个维度任何一个不匹配MySQL都会回这一句。有个特别常见的场景在云服务器上改完系统root密码突然发现应用连不上数据库了以为数据库密码也被改了。其实大概率是应用配置文件里写的连接用户就是root系统密码跟数据库密码混为一谈或者你之前设置过允许root远程登录后来又改了授权host。5.2 skip-grant-tables 重置全流程重置MySQL/MariaDB的root密码主流做法是让服务跳过权限认证表启动进去改密码再恢复。以CentOS 7上的MariaDB为例第一步停服务systemctl stop mariadb第二步以跳过权限表的方式启动。改配置最稳编辑/etc/my.cnf或/etc/my.cnf.d/server.cnf在[mysqld]段加一行skip-grant-tables然后启动systemctl start mariadb如果用mysqld_safe手动起放进后台时要确认没有残留的mysqld进程占着端口mysqld_safe --skip-grant-tables 第三步无密码登录mysql -u root如果socket路径不对加-S /var/lib/mysql/mysql.sock。第四步先让权限表生效。跳过grant表启动时MySQL默认只能跑一条特殊命令之后的GRANT/ALTER才会正常执行。第一件事FLUSH PRIVILEGES;第五步改密码。MariaDB和MySQL 5.7用ALTER USER rootlocalhost IDENTIFIED BY 新密码;老版本5.5、5.6用SET PASSWORD FOR rootlocalhost PASSWORD(新密码);第六步确认root的host范围。先看用户表SELECT user, host, plugin FROM mysql.user;正常会看到localhost和127.0.0.1可能还有%。%那条表示允许任意主机登录。如果你的应用连接的是root%你只改了rootlocalhost应用照样报1045。第七步退出并把配置文件里加的skip-grant-tables删掉重启服务systemctl restart mariadb最后验证mysql -u root -p整个过程如果哪个环节失败先看MariaDB日志/var/log/mariadb/mariadb.log。启动失败常见原因还包括残留的socket文件删掉/var/lib/mysql/mysql.sock再试。5.3 MySQL 8.0 与 MariaDB 的差异MySQL 8.0开始默认认证插件是caching_sha2_passwordMariaDB则还是mysql_native_password。如果你的服务器跑的是MySQL 8.0ALTER USER那一步要显式指定认证插件ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 新密码;更常见的坑是密码重置完全成功但老版本客户端连不上报Authentication plugin caching_sha2_password cannot be loaded这不是密码错是客户端不支持新插件。要么升级客户端或驱动要么把账户认证插件降级ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 新密码;另外提醒一句别用网上那些老教程直接执行UPDATE mysql.user SET passwordPASSWORD(xxx) WHERE userroot;这条在MariaDB 10.4以上已经废了因为用户表结构改了password字段被删除执行直接报错。统一用ALTER USER就好。6. 重置成功只是开始验证、收尾与“防再忘”措施6.1 重置完之后做一轮验证再宣布完成我见过太多次同事改完密码就跑了第二天客户反馈还是登不上。改密码不是目的能登、能跑业务才是。我每次重置完会按这个清单走一遍用新密码从本地控制台登录root确认能进。检查是否能SSH登录。若要允许root远程登录确认/etc/ssh/sshd_config里PermitRootLogin的配置改完systemctl restart sshd。数据库用新密码mysql -u root -p验证连接如果有应用挑一个依赖库的接口做冒烟测试。检查SELinux状态getenforce确认生产环境恢复Enforcing后一切正常。刚才用的enforcing0只是临时启动参数重启后会自动恢复。journalctl -b看启动日志。如果做过autorelabel第一次启动会慢一些属正常现象。把新密码放进团队密码库或安全凭证管理系统标注重置日期和经办人。6.2 GRUB密码加一把锁也留一把钥匙这里必须要提醒一个安全层面的问题重置root密码的代价是“只要有控制台权限就能改root密码”。任何能进GRUB的人理论上都能用rd.break改掉你的root密码。所以真重视安全的环境会给GRUB也设置密码。方法是在CentOS 7上执行grub2-setpassword它会生成/boot/grub2/user.cfg之后编辑启动参数前会要求输入GRUB用户名和密码。但这会引入新问题GRUB密码忘了重置起来比root密码还麻烦得进rescue环境重新安装GRUB。我的实际做法是GRUB密码和root密码分开存GRUB密码放物理上锁的密码本root密码放团队凭证库。真到了什么都不记得的那天至少还能去机房敲控制台从GRUB这层钥匙进门。6.3 减少下一次“重置”的发生频率最后说说我这些年攒下来的习惯。我经手的服务器root密码通常设置成高熵随机串日常操作用sudo绝不动不动就su -。sudoer权限按人配置visudo比如给某个用户开启免密sudoyourname ALL(ALL) NOPASSWD: ALL这样就算哪天我把root密码彻底忘了也不影响日常操作真正需要root的场景再做一次密码重置压力小很多。数据库侧root账户平时不外借给应用单独建只读或最小权限账号避免所有人共用一个数据库root这既防密码丢失也防误操作。“重置root密码”这件事本身真不难难的是在紧张状态下快速判断当前系统是什么发行版、什么挂载状态、什么认证体系然后选对路径。把这篇文章的操作在虚拟机里完整练两遍等真出事的时候你大概率会比旁边那些手忙脚乱翻博客的人冷静得多。
返回列表