ARTICLE DETAIL

资讯详情

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

Ubuntu忘记root密码?恢复模式与init=/bin/bash破解指南

Ubuntu忘记root密码?恢复模式与init=/bin/bash破解指南 凌晨两点你刚在服务器上改完sshd配置手一抖把会话断了重新登录却发现密码怎么输都不对——再一查root密码好像也被你忘得一干二净。这种时刻我经历过不止一次我的第一反应曾经是“完了只能重装系统”但后来自从搞懂了Ubuntu的root密码机制才发现根本不用走到那一步。这篇文章就专门聊Ubuntu下root密码忘了该怎么处理哪些情况其实不用重置密码、恢复模式和init/bin/bash两种快捷方案的完整操作、Live USB兜底改法的步骤以及改完密码之后必须处理的一堆收尾细节。无论你是服务器运维、刚转Linux的开发还是自己折腾Ubuntu桌面机的爱好者这套流程都适用。1. 动手之前先分清你忘的到底是哪个密码1.1 Ubuntu默认没有root密码这是设计不是坑很多从CentOS、Windows转过来的朋友都会在Ubuntu上卡第一个跟头装系统的时候根本没让设置root密码只设置了一个普通用户然后装完发现su -输啥都不对。这不是你记错了是Ubuntu默认就把root账户锁死了。安装过程中创建的那个用户密码只对那个用户有效root那边压根就没有可用密码——/etc/shadow里root那一行是!开头意为锁定。这个设计和Debian一脉相承日常管理用sudoroot身份通过sudo临时获得避免长时间用root在系统里裸奔。所以你“忘记root密码”时先不要急着去改东西先问自己一个问题我平时真的是用root登录吗如果答案是否那你需要的可能不是“重置root密码”而是“重置那个sudo用户的密码”——两者操作路径完全不同下文会分开讲。顺带一提热搜里经常看到“linux把普通用户变成root”其实指的就是把普通用户加入sudo组usermod -aG sudo 用户名这跟“忘记root密码”是两码事别混。1.2 三种常见“密码失效”场景的自查方法我列一下实际工作中最常见的三种情况你可以对号入座。场景现象需要的操作sudo用户密码忘了登录时输密码进不去或sudo提示输密码总报错进恢复模式用root权限重置普通用户密码root密码忘了/未设置su - 提示认证失败但普通用户还能登录进恢复模式passwd root即可密码过期被锁登录后强制要求改密码或提示account is expired用chage重置过期时间而不是单纯改密码这里特别说一下第三种。很多人以为“密码过期”和“密码错误”是一回事其实两个概念。Ubuntu的密码策略在/etc/login.defs里配置如果PASS_MAX_DAYS被改小了或者有人手动用chage设置了密码有效期到期后账户就会强制你改密码。SSH登录时遇到Your password has expired属于这种情况交互式界面会引导你改密码但如果你用自动化脚本或某些客户端连上去可能直接卡死。判断方法是登录后看chage -l 用户名输出的“Password expires”字段。如果你能登录普通用户只是sudo输密码不对那基本没救因为sudo要密码sudo passwd 用户名这条路也被堵死。如果手里还留着一个root shell会话什么都好说如果会话也断了那就老老实实走下面的恢复流程别想着绕。2. 首选方案从GRUB恢复菜单重置密码2.1 怎样顺利进入GRUB菜单这一步是整个流程里最容易翻车的地方很多人栽在“进不去恢复菜单”上。原因是Ubuntu默认单系统安装时GRUB菜单在引导时根本不显示黑屏一闪就进系统了。我的经验是开机后盯着屏幕在BIOS自检画面那段快速连按Shift键传统BIOS机型或者狂按Esc/左侧ShiftUEFI机型——具体哪个键跟主板固件有关可以都试。时机大概在“固件logo消失、内核开始加载”之前那个窗口期。如果你装的是Ubuntu和Windows双系统GRUB菜单默认会出现反倒不用纠结。还有一个土办法如果你实在掌握不好时机可以在Ubuntu里先用sudo systemctl reboot --firmware-setup进BIOS把启动模式或启动顺序调整一下让GRUB多停留一会儿或者重启时按住Shift不放从开机一直按到GRUB菜单出现总有一个时刻能拦住。UEFI的Secure Boot目前一般不影响这个操作但如果你开了记住恢复模式下某些第三方驱动可能加载不了这不影响passwd。2.2 进入root shell后的关键操作GRUB菜单出来后选择Advanced options for Ubuntu高级选项在展开的列表里挑一个带(recovery mode)字样的内核条目进入恢复菜单后选root - Drop to root shell prompt跳到root shell此时你已经有了root权限但文件系统以只读方式挂载这里有个关键点恢复模式的root shell默认把根文件系统以只读方式挂载。直接跑passwd root大概率报错因为passwd需要写/etc/shadow。所以第一步一定先执行mount -o remount,rw /然后再改密码passwd root如果你要重置的是普通用户比如忘了ubuntu这个用户的密码passwd ubuntu改完直接reboot重启新密码立即生效不需要额外操作。整个过程大概一分钟是我处理这类问题时的首选方案。2.3 为什么文件系统是只读的以及不处理会怎样我第一次用恢复模式时直接输passwd root然后看到passwd: Authentication token manipulation error当时完全懵。后来想明白恢复模式只读挂载是为了在系统异常时保护文件系统不被意外写坏——你就想成一个外科医生做手术前先把患者固定好防止操作时乱动。如果你忘了remount这一步系统会明确告诉你操作失败/etc/shadow里写不进内容但不会损坏什么东西所以不用慌。要注意mount -o remount,rw /只对当前根分区有效。如果你的/boot或其他关键分区是独立挂载的通常不影响passwd因为shadow文件在根分区上。还有一个细节恢复模式下/proc这些虚拟文件系统一般已经挂好了passwd的PAM认证流程基本能跑通。但如果你在那个shell里发现各种奇怪的报错比如passwd: PAM authentication failure先检查mount | grep /proc如果没有输出就补一句mount -t proc proc /proc这个问题在后面的init/bin/bash方案里更常见恢复模式下一般碰不到但知道了就能快速定位。3. 恢复菜单失灵时的备选内核参数init/bin/bash3.1 手动编辑GRUB启动项的具体操作有时候恢复模式会出幺蛾子菜单能进但选了root - Drop to root shell prompt之后直接黑屏、卡死或者shell起不来。这种时候我一般改用内核参数大法。启动时在GRUB菜单界面按e进入编辑模式。找到以linux开头的那一行UEFI的老版本里可能是linuxefi这一行很长包含很多内核参数比如quiet splash之类。把光标移到行尾先删掉可能引起麻烦的quiet splash这两个参数只是隐藏启动日志不删也没事然后在行尾加init/bin/bash按CtrlX或F10启动系统会跳过正常的init流程直接给你一个真正的bash。这个bash是root身份没有密码拦截相当于直接拿到了系统最高权限。3.2 进入bash后的完整命令序列这个bash环境和恢复模式不一样它非常“裸”——文件系统只读、没有网络、没有正常服务虚拟文件系统也没挂。所以命令顺序很重要我踩过坑按下面这个顺序来基本不会翻车mount -o remount,rw / mount -t proc proc /proc mount -t sysfs sysfs /sys passwd root在只读状态下passwd会报错这个前面说过。挂/proc是因为passwd走的PAM模块需要读取系统信息不挂可能会有诡异报错虽然有时不挂也能跑但既然都进到这里了顺手挂上不亏。改完密码后直接reboot不一定行因为正常关机流程被跳过了我遇到过reboot命令没反应的情况。稳妥做法是exec /sbin/init这条命令会恢复正常启动流程让系统带着改好的shadow文件正常起来。如果exec /sbin/init也卡住那只能长按电源键强制重启再开机一般没问题毕竟密码已经落盘了。3.3 这个方案的差异与限制两者本质都是拿root shell但差异很实在对比项恢复模式init/bin/bash环境完整度迷你服务环境/proc /sys已挂极简环境需手动挂载适用场景系统能启动GRUB正常恢复模式起不来、菜单异常操作风险低参数现成中手动编辑内核参数对加密盘仍需LUKS密码仍需LUKS密码init/bin/bash方案有个大前提你的系统盘没有整盘加密。如果装了LUKS全盘加密进GRUB编辑界面后、内核真正加载前系统会先要求你输入密码解锁硬盘。如果这个密码也忘了那上面所有方案全部失效只能走Live USB方案并且在Live环境里同样需要LUKS密码才能解开——如果连LUKS密码都没了那真的只能格式化重装了这个要有心理准备。另外如果系统装了SELinuxUbuntu默认是AppArmor基本不受影响从init/bin/bash环境改完密码后SELinux文件标签可能错乱需要额外做touch /.autorelabel再重启。Ubuntu用户不用管这个但如果你曾经手动换过SELinux或者用的是其他发行版这个坑要记住。4. 最稳妥的兜底Live USB chroot改密码4.1 用U盘进Live环境的准备工作前面两种方案都依赖GRUB和内核能正常启动。如果GRUB坏到连菜单都出不来或者系统完全开不了机就该动用最后手段用另一台电脑做一个Ubuntu Live启动盘从U盘启动系统然后在Live环境里把硬盘挂载起来chroot进去改密码。做启动盘很简单到Ubuntu官网下载对应版本的ISO用dd写入U盘Windows上可以用Rufus、balenaEtcher。注意Live环境的版本最好和硬盘里的系统大版本一致比如硬盘是20.04就用20.04的Live盘避免因为版本差异带来不必要的变量。从U盘启动后选择“Try Ubuntu”进入Live桌面。打开终端第一件事是看清硬盘分区sudo lsblk -f对比分区列表里的文件系统类型和大小找到你的根分区。常见的命名/dev/sda1、/dev/nvme0n1p2之类。如果你的系统是LUKS加密的lsblk里会看到一个叫crypt或LUKS的设备需要先解密sudo cryptsetup luksOpen /dev/sda2 cryptroot会提示输入LUKS密码输入后生成/dev/mapper/cryptroot这就是逻辑上的根分区后面mount都对这个设备操作。4.2 chroot环境下的密码重置与账户解锁找到根分区后按顺序执行sudo mount /dev/sda2 /mnt sudo mount --bind /dev /mnt/dev sudo mount --bind /proc /mnt/proc sudo mount --bind /sys /mnt/sys sudo chroot /mnt/dev、/proc、/sys这三个bind mount是重中之重。chroot进去之后如果不挂这些目录很多命令会直接失败。我的理解是chroot只是把根目录换了但内核提供的设备节点、进程信息、系统状态接口还在原来的全局位置上bind mount把它们“搬”到新根目录里让程序以为自己在正常系统里运行。进入chroot后就是熟悉的操作passwd root如果要改普通用户passwd ubuntu还可以顺手检查root账户锁定状态passwd -S root输出里P表示有密码可用L表示锁定NP表示没有密码。如果确认是锁定的用passwd -u root解锁。完成后退出来exit sudo umount -R /mnt sudo reboot整个过程中最容易被忽略的是如果你之前用桌面文件管理器打开过硬盘分区系统可能已经自动挂载了再mount到/mnt会报already mounted先sudo umount /dev/sda2让系统松手再重新挂。这类“顺手连error都懒得看”的小问题比我预想中更容易卡住新手。4.3 遇到“设备忙”和设备名搞错的处理chroot方案最常卡在两个地方。一是umount时报target is busy。多半是终端当前工作目录还留在/mnt里先cd /退出去再卸载。或者你chroot进去之后忘了exit另开了一个终端窗口在操作所有相关终端都关掉再卸。实在卸不掉就sudo umount -l /mnt强制延迟卸载反正要重启没事。二是搞错设备名。现在很多新机器是NVMe固态设备名是/dev/nvme0n1p1这种而不是老式的/dev/sda1。千万别凭印象猜lsblk -f会列出所有分区的UUID、文件系统类型和大小按输出选准没错。如果挂错了分区比如把/boot挂成了根分区进去后可能看到一堆内核文件而不是/etc/shadow这种情况立刻umount重新选。三条路线到这里就齐了。真遇到问题我的选择顺序是恢复模式优先其次init/bin/bash最后Live USB。前面两个快但依赖环境完好Live USB慢但胜在什么都能救包括顺手备份数据。5. 密码改好后的收尾与日常防坑5.1 顺手把root账户的锁定状态理清楚既然费了这么大劲拿到root shell我建议除了重置密码顺便看一眼root账户的整体状态避免下次再出毛病。passwd -S root chage -l root如果之前root一直被锁定你这次passwd root设了新密码后账户会自动变成“有密码”状态也就是解锁了。如果你平时根本不打算用root登录只是为了让sudo正常工作其实sudo正常工作跟root是否有密码完全无关那可以在改完密码后再次锁定rootpasswd -l root这样操作之后root的密码就变成一个无效的锁定标记su -无法登录但系统里所有需要root权限的服务、sudo流程都不受影响。我的习惯是服务器上root必须锁定只有sudo用户能干活偶尔需要root shell就用sudo -i。桌面机上同理。这样即使账户密码泄露攻击者也无法直接以root身份登录。如果你恰恰相反——公司审计要求root可以直连登录那记得同时改一下/etc/ssh/sshd_config里的PermitRootLogin选项光改密码不改SSH配置的话root照样连不上SSH很多人会忽略这一点。改完配置要systemctl restart sshd才生效。5.2 sudo用户密码忘了的替代解法上面所有方案里重置普通用户密码用的是passwd 用户名。但有一种特殊情况这个普通用户在/etc/shadow里被设置了expiry时间密码改完登录还是提示过期。这时在恢复shell或chroot环境里执行chage -d 0 用户名这条命令把“最后一次修改密码日期”设为0强制用户下次登录时先改密码。注意如果普通用户密码是“强制过期”状态passwd 用户名改完可能立不住要配合chage一起用才稳。我帮人远程处理过好几回“改了密码还是登不进去”十有八九就是卡在这个过期标志上。顺便说一句如果手头有root shell想把某个普通用户提升为管理员就是前面提过的usermod -aG sudo 用户名这个操作和改密码没关系但既然进恢复模式了一次把事情办完省得下次再进。5.3 密码过期策略与提醒配置前面提到密码过期这里展开一下。我见过不止一个运维同事因为密码过期被锁在门外尤其是那种“半年才登一次”的备份服务器。查看账户的过期信息chage -l 用户名把过期时间永久化chage -E -1 -M 99999 用户名其中-E -1表示账户永不过期-M 99999表示密码最长使用天数接近无限。全局策略在/etc/login.defs里改PASS_MAX_DAYS、PASS_MIN_DAYS、PASS_WARN_AGE三个参数分别对应最大天数、最小天数、提前警告天数。如果要设提醒把PASS_WARN_AGE设成7到期前一周用户登录就会看到警告。这个对root同样有效设置后记得通过chage或实际登录验证一遍别改完就以为万事大吉。进阶一点的做法是给密钥登录的账户设置统一策略比如所有用SSH key登录的账户把密码过期设成99999避免哪天策略扫描工具把一堆“长期未改密”的账户标红然后又有人半夜打电话问你“root密码怎么又登不上”。这种问题预防的成本远低于事后救火。5.4 别把数据库root和系统root搞混最后提醒一个非常常见的乌龙很多同学在Ubuntu上装了MySQL或MariaDB连数据库的时候提示类似ERROR 1045 (28000): Access denied for user rootlocalhost第一反应是“我又忘了root密码”然后跑到恢复模式里一通改改完还是连不上——因为你改的是系统账户密码数据库的root密码完全是另一个东西存在MySQL自己的用户表里。数据库root密码重置不需要动系统方法是在MySQL配置文件里加skip-grant-tables跳过权限验证重启服务后进入MySQL用ALTER USER重置密码再把配置删掉重启。这个操作和系统root密码重置是两套流程千万别混在一起。判断依据很简单如果能正常登录系统、正常sudo只是mysql -u root登录失败那就是数据库问题跟系统账户无关。我在实际处理这类问题时还有一个经验如果是给客户或同事远程处理动手前一定先确认对方说的“root密码”指哪个root。多问一句“你现在能不能正常登录系统”能省掉后面所有弯路。
返回列表