ARTICLE DETAIL

资讯详情

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

Linux root密码忘记怎么办?从系统到数据库的全套重置方案

Linux root密码忘记怎么办?从系统到数据库的全套重置方案 干了十几年运维最怕半夜听到的一句话就是“root密码忘了”。这事不大但足以让你在机房里对着屏幕发愣或者在工单系统里跟甲方来回拉扯半小时。今天这篇东西我就把自己这些年用过的root密码重置方案完整梳理一遍从Linux系统本身的密码恢复到MySQL、MariaDB这类数据库的root密码处理全部是实测过、能直接落地的做法。先说清楚一个边界本文讲的“重置”和“破解”是两回事。所谓破解root密码本质上是利用物理接触服务器的机会绕过登录认证环节直接改写系统里的密码哈希文件。它的前提是你对这台机器有硬件的访问权限键盘、屏幕、或者带外管理口。如果你是想在没有任何授权的情况下攻破一台不在你手里的服务器那属于另一条赛道本文所有方法都不适用也不该适用。另外所有操作都会触发系统的安全机制比如SELinux或者文件系统只读挂载这些细节我会重点标注因为它们才是实际操作中最容易翻车的地方。1. 先想清楚root密码重置的底层逻辑1.1 一段正常的Linux登录流程长什么样Linux系统的用户登录认证目前最主流的方案是PAMPluggable 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.unitrescue.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 /然后修改用户密码。假设你的用户名叫opspasswd 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 rootlocalhost (using password: YES)看到这个错误不要急着操作先冷静分析一下。它有三种常见情况密码确实记错了密码正确但root账户的host限定导致匹配不上账号被锁或密码过期策略导致认证失败。对于第一种情况最经典的处理方法是用skip-grant-tables参数跳过授权表进入数据库内部改密码。接下来的操作以MariaDB和MySQL 5.7为例这两个是目前存量最大的版本。4.2 skip-grant-tables 模式下的完整密码修改过程第一步停止数据库服务。用systemd管理的系统执行systemctl stop mysqldMariaDB的服务名则可能是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_stringPASSWORD(新密码) WHERE userroot AND hostlocalhost; FLUSH PRIVILEGES;MySQL 5.7.6之前支持PASSWORD()函数5.7.6之后这个函数被标记为废弃但短期内仍可用。MariaDB用户则还可以使用SET PASSWORD FOR rootlocalhost PASSWORD(新密码);对于MySQL 8.0以及较新的MariaDB版本推荐直接用ALTER USERALTER USER rootlocalhost 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 userroot;确保自己修改的是实际登录时命中的那条记录。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开头的行即可别死盯linux16passwd报“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。最后再送一个小技巧如果你手边没有带外管理而且服务器重启会产生很大的业务影响别急着在业务高峰期去动这台机器。可以先找一个业务低峰期提前演练一遍流程确认每个操作步骤的耗时减少真正出现问题时的慌乱。另外密码重置完成后记得立刻把新密码记录到团队共享的密码管理工具里避免过两个月又打一次同样的工。
返回列表