☰
Linux密码破解揭秘:root密码重置原理与完整步骤
2026/10/9 10:44:17 网站建设 项目流程

Linux系统密码破解

半夜两点,机房温度比平时低两度,因为后背发凉的是我。刚接手的那台CentOS 7,负责交接的兄弟只留下一句话:"root密码……我当时改过,但记在哪个笔记里找不到了。"相信每个运维人都经历过这种瞬间。Linux系统密码破解,或者说密码恢复,一直是运维里最经典、也最容易被误会的技能——经典在于关键时刻真能救命,被误会在于很多人一听就想到黑客入侵。这篇文章我想系统聊聊,作为一个合法维护者,在自己有权限的机器上把root密码拿回来的完整思路:从认证机制的原理到单用户模式、live CD、chroot这些经典方案,再到加固环境下的应急规划和事后处理。通篇只讲一个原则,这些手段只用于你拥有权限的设备。

1. 先说清楚:"破解"在运维语境里到底指什么

1.1 什么样的场景才真正需要"密码恢复"

很多刚入行的朋友一听"Linux密码破解"就两眼放光,以为是像电影里那样开着命令行、跑着进度条把别人的密码解出来。实际工作中根本没那么戏剧化,我遇到的绝大多数"破解"需求,本质上是这几类场景中的一种。

第一类是典型的管理员自废武功。上一任运维走的时候没有完整交接,或者密码放在某个离职员工的个人文档里,服务器一重启就发现没人能登录。我在朋友公司就见过一台跑着数据库的Ubuntu,交接表上写着"密码已修改,见wiki",结果wiki的账号密码也跟系统密码一起丢了。第二类是连错密码锁到怀疑人生。你手里确实有密码,但怎么输都不对,可能是键盘布局切到了非英文状态,也可能是CapsLock和NumLock的组合把ua倒腾成了UA,输错太多导致账户被锁定。第三类是恢复被锁的测试环境。一个业务测试用的虚拟机,密码被自动化脚本换过但脚本日志早就没了,重新装一次系统成本又太高。

这种时候要的不是"暴力破解邻桌电脑"的冒烟镜头,而是把系统重新收归自己掌握的能力。

1.2 "破解"和"恢复"的分界线:能不能碰,心里要有数

我得把这条线画清楚:本文讲的所有方法,只适用于你有合法权限的电脑、服务器和虚拟机。自己公司的资产、自己买的树莓派、自己搭建的测试环境——这些是安全的操作对象;公司让你维护的服务器——这也是安全的操作对象;但你不该把这些技术用在别人的设备上,未经授权修改别人系统里的账户密码,在任何地区都属于明确的违法行为,这一点跟工具本身的能力无关。总有人说"我懂技术所以我只做技术判断",但我见过太多因为"好奇试一下"把自己送进修罗场的案例,这不是危言耸听,法律边界不是靠"我只用在自己机器上"就能覆盖的。

另外还有个常见误区要破除:很多人以为所谓"破解"就是把 /etc/shadow 文件里的加密hash拿来碰撞还原。但实际上,运维场景里解决"忘密码"的最佳路径从来不是去"解"那个hash,而是用系统自身提供的恢复通道重新生成一个新hash。换句话说,我们要的是"我有权进入系统,所以我能重置密码",而不是"我能从密文推出明文"。理解了这一点,你才能分清哪些操作是正规的应急手段,哪些是纯粹的越权行为。

2. 重置root密码前必须懂的认证机制:passwd、shadow与hash

2.1 用户信息都存在哪里

动手之前先花五分钟理解认证机制,不然你就不知道为什么有的命令要加 root、有的文件改了没效果,也理解不了为什么后续步骤里挂载方式差一个rw/Ro结果天差地别。Linux用户信息的核心载体是两个文件:/etc/passwd 和 /etc/shadow。

/etc/passwd 是全世界都能读的,里面存的是账户基础信息。典型的行格式长这样:

root:x:0:0:root:/root:/bin/bash

从左到右分别是用户名、密码占位符、UID、GID、注释信息、家目录、登录shell。老系统里这个x的位置直接放的是密码hash,后来为了安全把它挪走了,那个位置就留了个 x 占位符。真正有价值的是 /etc/shadow,权限默认是 root:root 并且 000 或 400,普通用户根本看不了。这里面每一行对应一个用户,字段用冒号分隔,最重要的就是第二个字段,密码hash。示例:

root:$6$rounds=656000$qmH1xVQD$Gm5X...:19001:0:99999:7:::

这行第二个字段可以明显看到 $6$ 这种前缀,后面跟着一大串看似随机的字符。这一段就是加密后的口令摘要。

2.2 shadow里的hash为什么不能"解"出来

这个hash采取了加盐的单向散列算法。前缀不同,算法也不同,常见的有这几种:

前缀含义典型长度/特点
$1$MD5短,已过时,速度极快
$5$SHA-256中等长度,旧系统
$6$SHA-512长,CentOS 7/RHEL 7默认
$y$yescrypt长,更新更强,新版Debian/Ubuntu用

"单向"的意思是,算法本身设计出来就不是让你从摘要还原明文的。你输入一个密码,系统算出hash再跟shadow里的比对,匹配就算通过;但反过来,给你一串hash让你反推原始密码,在数学上不可行。所谓"跑字典"不是从hash反推出密码,而是把可能性较大的候选密码挨个算一遍hash,看哪个跟目标hash一致——本质上是在猜,不是真的"解出"。而像 $6$ 这类算法还带iteration轮数,像示例里 rounds=656000 就是让计算故意变慢,普通CPU一秒只能算几千次;$y$ 算法还要求大内存,GPU并行也被压得很惨。所以面对一个强密码,撞库的成本高到离谱。

这也就解释了一个现象:为什么网上一堆"在线破解Linux密码"的网站基本没用——他们也只能跑字典,碰上复杂密码就是听个响。

2.3 为什么"重置"比"破解"靠谱

既然反推不可行,正路就是"重置":以系统特权身份直接给指定用户生成一个新密码的hash,覆盖shadow里的旧hash。这个操作的效率比起字典碰撞高到不可同日而语,而且你根本不需要知道旧密码是什么。

在正常的已登录系统里,一条 passwd root 就能完成;可问题恰恰是我们没法登录。所以全部恢复思路都围绕一件事:想办法拿到一个可以修改系统文件的shell,哪怕只是临时的、不完整的root权限。rd.break、live CD加chroot、init=/bin/bash,这三条路本质都是在做同一件事——在系统认为"哦这是root用户在操作"的时机,进入它的工作环境,然后安安稳稳地改密码。

3. 不改一行文件:单用户模式与rd.break下的root密码重置

3.1 适用条件与环境判断

单用户模式是最经典的重置方案,在大多数物理机和虚拟机上都好用。它本质上是通过GRUB启动菜单干扰内核启动参数,让系统在启动初期进入一个带root权限的shell。适用条件不难判断:你有物理控制台或虚拟机的显示器/键盘访问权限,能看到GRUB菜单,系统没有开启GRUB密码保护,并且根文件系统没有做LUKS全盘加密(或者你至少知道加密盘的passphrase)。

这里提醒一句:在云服务器上,GRUB菜单通常一闪而过,而且平台控制台对键盘交互支持也很有限,传统单用户模式非常难操作。云服务器请直接走云平台的"重置密码/救援模式",别在这上面耗时间。

3.2 CentOS/RHEL 7/8/9的rd.break完整步骤

CentOS系是我最常用的环境,rd.break这套流程我几乎每个月都会在测试机上过一遍。完整步骤如下。

第一步,重启机器。如果是物理机就按重启键,如果是KVM/VMware就在控制台里发送重启指令。等开机画面出现,看到GRUB菜单时迅速按一下键盘上的 e 键,进入编辑模式。

第二步,找到以 linux 开头的行,一般长这样(旧版可能是 linux16):

linux16 /vmlinuz-3.10.0-1160.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto ...

在这一行的末尾敲一个空格,然后追加:

rd.break console=tty0

rd.break 是关键参数,它告诉dracut在initramfs阶段挂载完根文件系统之后立刻中断,进入一个root shell。console=tty0 是预防某些系统里输出重定向失效后画面全黑的问题。

第三步,按 Ctrl+X 或 F10 启动。系统会在非常早期的阶段停下来,你会看到一个类似 switch_root:/# 的提示符。

第四步,先查看一下挂载状态,然后重新以可写方式挂载根目录:

mount | grep sysroot mount -o remount,rw /sysroot chroot /sysroot

为什么要重新挂载?因为initramfs阶段为了安全,把 /sysroot 挂成了只读。如果直接chroot进去跑 passwd,会报"cannot change password: Authentication token manipulation error",折腾半天全是白费。先 remount 成rw才能写shadow。

第五步,在chroot环境里直接改密码:

passwd root

输入两遍新密码。看到 "all authentication tokens updated successfully" 就说明写进去了。

第六步,处理SELinux标签。CentOS 7/8默认开启SELinux,chroot之后我们修改过的 /etc/shadow 和 /etc/passwd 文件,它们的SELinux上下文可能不对,导致重启后系统拒绝读取这些文件。最稳妥的办法是执行:

touch /.autorelabel

这个标记会让系统在下次启动时自动重新为所有文件应用正确的SELinux上下文。这一步省略的话,我踩过很多次坑,现象是密码明明改对了,但登录的时候系统各种报错,日志里全是SELinux denial。

第七步,退出并重启。注意得退两次:第一次 exit 退出chroot,回到switch_root环境;第二次 exit 退出中断环境,让initramfs继续走完剩余的启动流程,直到系统重启。然后取出光盘或U盘,等系统正常起来,用新密码登录root。

3.3 其它发行版怎么处理

Ubuntu/Debian 默认没有dracut,但思路一样,只是参数不同。在GRUB编辑界面找到 linux 行,把行尾的 ro 改成 rw 并追加 init=/bin/bash:

linux /vmlinuz-... ro quiet splash init=/bin/bash

按 Ctrl+X 启动后,你会直接进入一个bash命令行。因为 Grub 参数里有 rw,此时根文件系统已经是可写状态,直接执行:

passwd root

保存后重启。Ubuntu如果没有启用SELinux,不需要autorelabel这一步,但如果你装了SELinux或者用的是CentOS,记得按上面那套来。

还有一类是用 systemd 的发行版,比如新版Fedora/openSUSE。它们可以用 systemd.unit=emergency.target 或 rescue.target 进入紧急模式,流程类似,进入后先确认根目录挂载为rw,再passwd。个人经验是紧急模式在网络和依赖上比rd.break更"干净",但前提是能顺利触发。

整个单用户模式的操作有一个最低要求:能摸到机器控制台。在实体机上加个显示器键盘就能干活,在虚拟化平台上打开控制台窗口就行。只要满足这一点,五到十分钟内就能恢复root访问权限,而且全程不用动任何现有数据和配置文件。

4. 不在手边的系统怎么救:live CD加chroot的完整重置流程

4.1 准备工作

有些环境的GRUB被隐藏了,或者引导菜单被锁死,按e之后根本没有编辑入口;还有些是系统已经被引导到了 grub rescue> 之类的地方,菜单都丢了。这时候单用户模式进不去,就得靠另一条路:用外部的live系统启动机器,然后挂载硬盘上的文件系统,chroot进去改密码。

第一步是做启动U盘。找一台能上网的电脑,到发行版官网下ISO镜像,然后用 dd 或 Rufus 写入U盘。Linux下写入命令是:

dd if=ubuntu-22.04.3-desktop-amd64.iso of=/dev/sdb bs=4M status=progress

注意 of= 后面的设备名一定要确认是对的,别把数据盘写掉了。我不止一次因为设备名写错把同机另一块盘干废,先 lsblk 或者 fdisk -l 看清楚再动手。

启动介质准备好后,插到目标机器,进BIOS/UEFI把U盘设为第一启动项。不同的机器按键不同,F11、F12、Esc都常见,开机时留意屏幕提示。

4.2 挂载与chroot步骤

live环境起来以后(选择"Try"或者"Rescue"模式),先用 lsblk 看目标磁盘的分区结构:

lsblk -f

假设你看到的是 /dev/sda1 是 /boot,/dev/sda2 是根分区,那挂载思路如下。先建挂载目录,然后挂根分区:

mkdir -p /mnt/root mount /dev/sda2 /mnt/root mount /dev/sda1 /mnt/root/boot

如果机器用了LVM卷组(CentOS安装器默认就是),挂载路径要换成逻辑卷路径。用 lvs 或 vgdisplay 查卷组名,比如卷组叫 centos,根逻辑卷叫 root,那就挂:

vgchange -ay mount /dev/mapper/centos-root /mnt/root mount /dev/sda1 /mnt/root/boot

vgchange -ay 是激活卷组的操作,不执行这一步逻辑卷不会被系统识别。挂载完成后,进入chroot环境:

chroot /mnt/root

chroot的作用是把当前进程的根目录切换成 /mnt/root,于是接下来的命令都仿佛运行在目标系统的文件系统内部。在这个环境里执行 passwd root 就是在给目标系统改密码了:

passwd root

如果目标系统启用了SELinux,chroot里同样最好 touch /.autorelabel。

改完之后退出chroot:

exit

然后解除挂载。这里有个我踩过的坑:不要在 /mnt/root 目录内直接 umount,会报 "target is busy"。正确做法是先退出chroot,再按从内到外的顺序卸载:

umount /mnt/root/boot umount /mnt/root

确认输出里没有 "target is busy" 之类的错误,再重启。重启时记得把U盘拔掉或者把启动顺序改回硬盘。

4.3 SELinux的善后问题

live CD方案和单用户模式有一个共同的细节——.autorelabel到底是干嘛的。chroot之后你改了shadow文件,但文件原有的SELinux标签还留在那里,不会自动变。如果只是简单修改其中的内容,标签一般不会变(比如 etc_t),但某些环境下创建出的标记文件或者文件属性变化可能导致登录和SSH异常。

我在RHEL 8上做过一次严格测试:用live CD改了密码,没有做autorelabel,重启后SSH服务直接拒绝连接,控制台登录却正常。原因就是 /etc/shadow 和 /etc/ssh/* 的标签没在正确范围内,sshd 隔离了这些文件。怎么解决?两步,第一步重新进入live环境或者单用户环境,第二步 chroot 后执行 touch /.autorelabel 并重启。这个过程会让系统在启动时把所有文件重新打标签,慢的话要等几分钟到十几分钟,属正常现象。

5. 加了防护的系统怎么办:grub密码、磁盘加密下的应急思路

5.1 GRUB密码加固后如何规划恢复通道

好一点的运维环境不会让你随随便便按e就能改启动参数,因为rd.break这种操作本质上等于拿到控制台的任何人都能接管系统。为此系统提供了GRUB密码保护。在CentOS/RHEL上设置方式很简单:

grub2-setpassword

执行后会提示输入密码,生成 /boot/grub2/user.cfg。之后每次启动想进入GRUB编辑界面,都要先输入这个密码才能继续。

但问题来了:如果GRUB密码也忘了,传统rd.break路径就完全封死了,因为编辑界面你都进不去。这时候作为合法维护者,正确的做法不是去尝试绕过GRUB的保护,而是提前设计好受控的恢复方案。我的习惯是,在设置GRUB密码的当天就把密码写进团队密码保险箱,同时保留一份存放在机柜钥匙锁着的管理信封里。没有这个预案,最后只能走重装系统或者联系硬件厂商协助的极端路径。与其这样,不如事先就建立一条"高权限但可审计"的应急通道。

5.2 LUKS加密下的现实情况

如果根分区做了LUKS全盘加密,情况又复杂一级。系统开机时首先会要求输入LUKS的passphrase,解密磁盘之后才会继续挂载根文件系统。rd.break发生在解密之后的initramfs阶段,所以只要你有LUKS的passphrase,单用户模式和live CD的流程照样能用,因为文件系统已经在内存中解密了;怕就怕LUKS密码同样忘光。

这种情况下正常途径基本无解。数据层面唯一的机会是当时是否生成过恢复密钥文件,比如:

cryptsetup luksAddKey /dev/sda2 recovery.key

如果你手里还有原来的passphrase或者recovery.key,可以在live系统里执行 cryptsetup luksAddKey 或 luksChangeKey;如果连密钥文件和passphrase都丢了,普通技术手段无法访问加密数据,只能从备份恢复。所以我一直建议,做LUKS加密的机器必须把恢复密钥离线保存,甚至可以打印成纸质文件锁进保险柜。这不是老古董的做派,是加密系统本来就需要你给予同等强度的密钥管理。

5.3 云服务器直接走控制台,别绕弯路

如果你面对的是阿里云、腾讯云、AWS这类的云服务器,真的要恭喜你,因为云平台通常已经做好了密码重置的入口。登录网页控制台,在实例详情里找"重置密码",按提示操作即可,有些平台还会强制你在重置后重启实例才能生效。整个过程不需要你手动进GRUB,也不需要live CD,而且完全符合平台的安全策略。

有人可能会问,那如果机器是自定义镜像、连重置入口都不好用呢?那就看平台提供的救援模式或者实例恢复。阿里云有"SSH密钥对"绑定,AWS可以用EC2的救援实例把根卷挂载到一台辅助实例上,然后像live CD一样改文件再换回来。这类操作有平台特定的文档,照着做就行。总之云平台的恢复逻辑和物理机不同,优先相信平台的应急能力,别拿着单用户模式在云端死磕。

6. 重置之后的不善后:SELinux、日志、口令策略一起处理

6.1 SELinux恢复与重启验证

密码改完、系统能登录,很多人的处理就到此为止了,但我的经验是重活在后头。

第一步是验证SELinux状态。如果做了 .autorelabel,重启之后你会看到系统在启动阶段花了不少时间重新打标签,日志里可能提示 "Relabeling the filesystem in the future" 之类的信息。用 getenforce 确认状态是 Enforcing 而不是 Disabled。如果之前因为标签错乱临时设置过 permissive,记得调回 Enforcing 并再验证一次SSH能正常登录。

第二步是验证重启后能否真正登录。这里有个细节,如果服务器配置了SSH公钥认证,你重置root密码后,SSH登录其实是用密钥走的,不需要密码,但为了确认密码是有效的,建议在物理控制台或虚拟控制台上用密码登录一次。别只在SSH上敲一遍新密码就说成功——万一PAM配置错了,密码只在控制台生效,SSH会提交新密码也一样被拒。

6.2 日志与系统安全检查

密码被重置往往意味着之前有一段时间没人能合法进入系统,甚至可能有一段"密码丢失"的窗口期。这个窗口期内系统是不是被搞过,必须查。

查登录历史,重点看这些位置:

last lastb journalctl _COMM=sshd --since "30 days ago" | grep Accepted grep -i "Accepted" /var/log/secure

逐项检查 root 的 /root/.ssh/authorized_keys,看看里面有没有不认识的公钥;检查 /var/spool/cron/root 和 /etc/cron.d/ 下有没有陌生定时任务。这些都是"系统疑似失联期间被接管"的最常见痕迹。我碰到过一次"忘记了root密码"的服务器,费劲重置后发现cron里被人加了一条curl回传脚本,从时间看正好是密码失效那段时间。所以重置密码之后的检查不是走形式,是真的能救命的。

6.3 制定"遗忘密码"的事前预案

最后再说说长期方案。密码丢失这件事,本质上不是技术问题,而是管理问题。我见过很多团队把root密码记在个人的微信收藏里,人一走,密码和人也一起走了。我的建议是成立一个团队级的密码管理库,至少要把 root 密码、GRUB密码、LUKS恢复密钥这三样东西放进去,并且规定轮换周期。对于关键系统,每季度做一次"忘记密码"演练——从重启机器开始,实测一下当前环境里恢复流程还能不能走通。你以为你记得怎么改,但谁会记得今年新装的这台机器是不是加了SecureBoot限制、是不是换了LUKS卷?只有演练过才知道。

还应该把恢复流程写进运维手册,作为一个标准操作流程。不要靠脑子记,因为凌晨三点的时候脑子基本靠不住。手册里哪怕只有几十行字,也比那时再去翻论坛找教程强得多。

写到这里,我想说个最朴素的体会:Linux系统的可靠,来源之一是它把恢复能力放在了一个有边界的位置。rd.break、live CD、chroot——这些手段不是用来绕过别人的系统的,而是为了让真正拥有这台设备的人,在忘记密码时还有一条体面的路回家。我这些年用过最稳的策略不是把密码记在哪个角落,而是把"忘记密码后的操作步骤"也当成一种资产,写进团队的故障手册里,并且真的演练过。这样真到了凌晨,你不会像我当年一样后背发凉,只会淡淡地想:哦,这步我演练过三遍了。

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

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

立即咨询