忘密码这事,放在物理机上大概率就是重装系统,但在虚拟机里,情况完全不同——你可以用比物理机丰富得多的手段把密码改回来。我帮客户处理过不少VMware Workstation、VirtualBox、ESXi上跑着的Windows Server和Ubuntu、CentOS虚拟机,一半以上的场景都是“密码过期”“管理员离职没交接”“自己手滑把root密码改了然后忘了”。这类问题的核心思路其实就一句话:虚拟机本质是一堆磁盘文件,只要还能挂载、还能进单用户模式,密码就永远有救。
先说个最容易踩的坑:很多人一忘密码就想着重装系统或者删虚拟机重建,这其实是下策。虚拟机有快照、有磁盘镜像,改密码这件事在虚拟化环境里远比物理机灵活,甚至可以从外部直接操作磁盘文件。这篇文章我把Windows和Linux两大方向的密码修改思路都拆开讲,配合实操命令和踩坑记录,覆盖VMware、VirtualBox、KVM等主流平台,适合虚拟化运维、个人开发者和刚接触虚拟机的新手参考。
1. 为什么虚拟机改密码比物理机“多一条命”
1.1 虚拟机的“可挂载”特性是核心前提
物理机的系统盘焊死在主机上,你忘了密码,除了用安装盘引导、借助PE工具之外,几乎没有别的路径。虚拟机不一样,它的整个“硬盘”就是宿主机上的一个文件,比如VMware的vmdk、VirtualBox的vdi、KVM的qcow2。这意味着你可以把这个磁盘文件当作一块普通的移动硬盘,挂载到另一台可用的虚拟机里,绕过原系统的登录鉴权,直接修改密码相关文件。
这个思路我在帮人远程处理vCenter上的Linux虚拟机时用得最多。虚拟机起不来、单用户模式也进不去的时候,干脆把它的vmdk摘下来,附加到一台正常运行的CentOS虚拟机上,mount到本地目录,然后修改/etc/shadow。整个过程不需要任何图形界面,SSH进去就能操作,相当省事。
另外,“快照”也是虚拟机独有的救命稻草。如果你在忘记密码之前打过快照,理论上可以直接回滚到快照状态,密码自然回到当时的状态。但这里有个前提:快照会丢掉之后的所有改动,如果系统里有新数据、新配置,回滚的代价可能比改密码还大。所以快照是“最后的保险丝”,不是常规手段。
1.2 虚拟化平台的密码重置逻辑差异
不同虚拟化平台,切入密码重置的方式不同。VMware Workstation是桌面级产品,虚拟机的vmdk可以直接通过“编辑设置”挂载新磁盘;VirtualBox同理,界面操作更直白;ESXi和KVM这类服务器级平台,则更多依赖命令行的vmkfstools、qemu-img或virsh来操作磁盘。
实操中我发现,很多人卡在第一步:不知道自己的虚拟机到底存在哪个目录、磁盘文件是什么格式。这里给个速查:VMware Workstation默认把虚拟机放在C:\Users\用户名\Documents\Virtual Machines\下,VirtualBox放在C:\Users\用户名\VirtualBox VMs\下,ESXi的虚拟机在/vmfs/volumes/datastore1/,目录里能看到vmdk文件。KVM的qcow2镜像一般在/var/lib/libvirt/images/。找到磁盘文件,你就掌握了主动权。
还有一种更省事的思路:直接用Live CD。很多发行版的安装ISO本身就带“试用系统”模式(比如Ubuntu Desktop的Try Ubuntu),把ISO挂载到虚拟机光驱,从ISO启动进入Live环境,然后把原系统盘挂载起来修改密码。这种方式不依赖grub,也不依赖另一台虚拟机,一台机器就能完成自救。
2. Windows虚拟机密码修改:离线SAM处理是主流
2.1 理解Windows密码存储原理
Windows的本地账户密码不是放在某个普通文件里,而是以哈希形式存储在注册表配置单元中,具体路径是C:\Windows\System32\config\SAM。SAM文件在系统运行时会锁定,所以必须离线操作——正好,虚拟机可以把磁盘拆出来给另一台机器挂载,这就给了我们很大的操作空间。
修改思路主要有三种:用chntpw工具清空密码;用PE工具启动后调用“命令提示符”改密;把SAM文件复制出来后用注册表编辑器离线修改。我实际用得最多的是chntpw,因为它轻量、命令行明确、很少出错。PE方案适合Windows 10/11的新虚拟机,因为系统版本新,SAM结构复杂,chntpw虽然也能处理,但WinPE里直接改更直观。
2.2 chntpw离线清空密码实操
chntpw是一个开源工具,在Kali、SystemRescue等Linux发行版里自带,也可以单独下载编译版。它的作用很简单:直接操作SAM文件,把指定用户的密码清空,或者重新设置一个哈希密码。
操作流程大概是这样的:
- 把目标Windows虚拟机的vmdk/vdi磁盘,挂载到一台可用的Linux虚拟机上(或者直接用WinPE启动目标虚拟机)。
- 挂载NTFS分区,比如mount到
/mnt/windows。注意如果Windows有快速启动或者不正常关机,NTFS分区可能处于脏状态,挂载时加-o remove_hiberfile选项清掉休眠文件。 - 进入
/mnt/windows/Windows/System32/config/目录,执行:
chntpw -u Administrator SAM交互界面里会出现几个选项:
1清空密码(blank user password)2设置新密码3提升用户为管理员q退出
我一般选
1,因为清空后Windows登录界面会直接要求输入新密码,方便现场设置。选2也可以,但需要注意chntpw写哈希用的算法对Windows 10 1809以后的版本可能不兼容,曾经遇到过设置了密码却登录不上的情况。写完后卸载分区,把磁盘重新挂回原虚拟机,开机即可。
这里有一个重点:chntpw改密码的原理是“清空”,不是预测。它把SAM里对应账户的NTLM哈希置为空值,Windows登录时发现该账户密码为空,会自动进入“设置新密码”的流程。所以不用担心清空后无法登录。
2.3 WinPE修改路径及实战注意点
另一条路更适合Windows 10/11:用微PE或优启通这类工具制作一个可启动ISO,挂载到虚拟机光驱,从ISO引导进入PE。PE里自带密码修改工具,图形界面点点点就行。对于不习惯命令行的朋友,这条路更友好。
实际操作时有一个细节:PE启动后,目标系统盘的盘符可能不是C盘,需要在“我的电脑”里确认,比如显示为D盘或者E盘。改完密码后,不要急着重启,先检查C:\Windows\System32\config\下的SAM文件大小是否变化,如果有备份工具提示“SAM写入成功”,才算稳妥。
另外提一嘴:热词里有个“diskgenius转虚拟机为u盘”,这个思路在Windows密码重置场景里也有价值。DiskGenius可以把虚拟机磁盘直接转换成物理U盘镜像,或者反过来把物理U盘做成虚拟机磁盘。如果Windows虚拟机完全无法启动,可以先用DiskGenius把vmdk转成普通镜像,挂到物理机上用WinPE离线改密码,处理完再转回去。这个方法适合“虚拟机起不来+宿主机是Windows”的情况。
3. Linux虚拟机密码修改:grub入口是最便捷的通道
3.1 单用户模式为什么能绕过登录
Linux的密码存在/etc/shadow文件里,而这个文件只有root能读写。正常登录时,系统通过PAM模块校验密码,校验不通过就拒绝进入。单用户模式不一样,它跳过了多用户运行级别,直接以root身份启动一个shell,相当于系统对你说:“你是管理员,进来修东西吧。”
默认情况下,进入单用户模式需要物理接触终端,并且在grub菜单里编辑启动参数。物理机这样做没问题,但虚拟机用户往往会卡在“grub菜单一闪而过”这个问题上。VMware Workstation默认的虚拟机BIOS启动非常快,很多系统不显示grub菜单,直接进系统。解决办法是开机时狂按Shift(Ubuntu)或Esc(CentOS/RHEL),也可以在grub配置文件里把GRUB_TIMEOUT改成5或10,重新生成grub配置。
3.2 CentOS/RHEL系:rd.break救急大法
CentOS 7/8、RHEL、Rocky Linux这些系统,Systemd时代最稳妥的密码重置方式是用rd.break参数。这个参数会让systemd在切换根文件系统前停下来,进入一个临时的ramdisk shell环境,此时真正的root文件系统被挂载在/sysroot下,而且是只读的。
具体步骤:
- 开机进入grub菜单,选中内核启动项,按
e进入编辑模式。 - 找到以
linux16或linux开头的那一行(包含/boot/vmlinuz和root=参数),在行尾加一个空格,输入:
rd.break- 按
Ctrl+x或F10启动。 - 进入shell后,执行:
mount -o remount,rw /sysroot chroot /sysroot passwd root- 设置完新密码后,如果系统开启了SELinux,需要执行:
touch /.autorelabel- 连续两次
exit,系统会自动重启,用新密码登录即可。
为什么需要touch /.autorelabel?因为通过chroot方式修改密码后,SELinux的文件安全上下文中,/etc/shadow的标记可能没有更新。如果不重新标记,第一次重启会特别慢(SELinux会对整个文件系统重新打标),甚至有概率卡在启动阶段。touch /.autorelabel就是告诉系统“下次开机会自动重新标记”,代价是启动时间变长,但安全可靠。
我踩过的坑是:很多人在rd.break环境里以为chroot /sysroot之后就直接可以改密码,结果发现/etc/shadow是只读的,其实就是漏了第一步mount -o remount,rw /sysroot。只读状态下passwd会提示“cannot lock /etc/passwd”,别慌,重新挂载成读写即可。
3.3 Ubuntu/Debian系:init=/bin/bash的实用变体
Ubuntu Server、Debian这些系统,grub编辑时在linux行末尾加init=/bin/bash也能进入root shell。但与rd.break不同,这种模式下根文件系统同样是只读的,需要先重新挂载:
mount -o remount,rw / passwd rootUbuntu默认不允许root直接登录(ssh里PermitRootLogin禁止),但本地控制台登录root不受影响,前提是你确实改了root密码。如果忘了的是普通用户密码,那就需要进单用户模式后用root身份改其他用户:
passwd username这里有个小坑:Ubuntu 18.04以后的grub默认隐藏菜单,但虚拟机的图形控制台里其实能看到“Press esc for menu”之类的提示。如果按Shift没反应,可以试试在VMware Workstation的vmx配置里加一行bios.bootDelay = "5000",让BIOS启动等待5秒,这样grub菜单就能稳定出现。
3.4 MBR、UEFI和grub版本带来的差异
虚拟机创建的分区方式不同,grub界面和启动参数传递方式也有差异。比如使用UEFI启动的Ubuntu,grub编辑时按e后,启动参数行以linux开头,内容里带有root=UUID=...;而传统BIOS启动的CentOS 7,行首是linux16。不要机械照搬,核心就是在以linux开头的那一行加参数。
另外,Grup2和Grup1的交互方式不大一样:Grup2环境下按e进去直接改,Ctrl+x启动;Grup1则是按a追加参数再回车。现在主流系统的虚拟机上基本都是Grup2,在VMware Workstation 17和VirtualBox 7这些较新版本里,只有极老的模板镜像才用Grup1。
4. 离线改shadow:当grub也进不去时的备选方案
4.1 把磁盘挂到另一台Linux虚拟机
grub进不去的情况确实存在,比如grub被误写坏、启动项里根本没有可用的内核、虚拟机因为某次异常断电直接卡在引导界面。这时候还有一个办法:把出问题的磁盘(vmdk/vdi)挂载为另一台正常Linux虚拟机的第二块硬盘。
以VMware Workstation为例,操作路径是:编辑虚拟机设置 -> 添加硬盘 -> 选择“使用现有磁盘” -> 选择出问题虚拟机的vmdk文件。注意,如果原虚拟机有快照,一个vmdk会对应多个子文件,选择最原始的-flat.vmdk可能会触发“该磁盘已被使用”的提示,正确的选择是选中虚拟机目录下那个不带-s的、通常容量等于虚拟磁盘总大小的描述文件。
挂载成功后,在正常虚拟机里执行:
lsblk找到刚添加的磁盘(通常是/dev/sdb或/dev/vdb),然后:
mount /dev/sdb2 /mnt/linux这里有个细节:Linux虚拟机根分区未必是sdb1,有时候/boot是独立分区,根分区可能是sdb2甚至sdb3。先fdisk -l /dev/sdb看分区表,再用blkid确认哪个是根分区。我的经验是:Ubuntu默认LVM布局时,根分区藏在/dev/mapper/ubuntu--vg-ubuntu--lv里,需要先vgchange -ay激活卷组再挂载。
挂在起来之后:
chroot /mnt/linux passwd root exit这个方法等于是把目标系统“借壳复活”,和单用户模式殊途同归。如果目标系统的SELinux是Enforcing,同样记得touch /.autorelabel。
4.2 shadow文件格式与手动生成密码哈希
有时候chroot进了目标系统却发现passwd命令报错,或者用户密码被人为锁定(shadow里的哈希以!开头),这时可以手动编辑shadow文件。很多人不知道/etc/shadow的每个字段到底什么意思,这里拆开讲一下:
用户名:密码哈希:最近修改时间:最小修改间隔:最大修改间隔:提醒天数:宽限天数:过期时间:保留字段
最重要的是第二个字段,也就是密码哈希。如果它以!或*开头,表示账户被锁定,无法登录。手动修改时可以用openssl passwd生成新哈希:
openssl passwd -6 -salt xyz123 你的新密码-6表示使用SHA-512算法,-salt后面跟随机字符串(比如8位字母数字),输出一串$6$xyz123$...,把它替换到shadow文件第二个字段即可。
手动编辑shadow要非常小心格式,别丢掉字段分隔符冒号。我习惯先把原shadow备份一份:cp shadow shadow.bak,改完以后用vim -c 'set fileformat=unix' shadow强制保持Unix换行格式,避免因为编码问题导致系统启动后认不出这个文件。
4.3 LUKS加密磁盘的特殊处理
如果创建虚拟机时开启了磁盘加密,最典型的就是Ubuntu安装时的LUKS特性、CentOS的LUKS分区,情况会复杂很多。无论是grub单用户还是挂载到另一台虚拟机,最终都需要先解锁LUKS分区。在grub的rd.break环境里,系统其实会自动尝试你输入的加密口令;在那一步卡住的朋友,往往是输入的口令和创建时的键盘布局对不上。
如果只是普通的分区加密,挂载时需要手动使用cryptsetup luksOpen /dev/sdb2 luks-root,然后输入加密口令,再挂载/dev/mapper/luks-root。这要求你至少还记得LUKS解密口令,这个口令和系统密码不是一回事。如果连这个都忘了,那就真的只能恢复到快照或者放弃数据了——这个情况我在文章最后会再提一下。
5. 常见问题与排查技巧实录
5.1 密码改了但登录仍然失败的几个原因
改完密码,进入系统时却发现登录不上,这是最常见的后遗症。根据我的排查经验,原因基本集中在几个地方:
第一,键盘布局变化。虚拟机控制台的默认键盘布局可能和物理机不一致,比如你设置密码时敲@,实际出的是",导致密码永远不对。这个在chntpw和单用户模式里都有可能发生,因为这两个环境里初始加载的键盘映射和你平时用的不一样。处理办法:登录失败别死磕,直接回到单用户模式,用passwd设置一个纯数字加字母的密码,避免特殊字符。
第二,系统里启用了LDAP、SSSD等集中认证,/etc/shadow根本不管本地账户密码。这类环境多见于企业模板克隆出来的虚拟机,用户账户实际是“域账户”,Linux本地密码不影响登录。判断方式:看登录界面是否有“未列出”选项、getent passwd能否拉出远端用户。这种场景下直接改本地密码是没用的,要么改域密码,要么把/etc/nsswitch.conf里的认证顺序调整为先本地后域。
第三,改完密码后自动登录或桌面环境缓存了旧凭据。Gnome的Keyring、KDE的KWallet里面存的密码不会自动失效,用新密码解锁不了钥匙环就会出现“密码错误”的假象。处理办法:在登录界面点击账户,选择“忘记密码”,让它重新初始化钥匙环,或者干脆用命令行rm -rf ~/.local/share/keyrings清掉旧钥匙环数据。
5.2 VMware Workstation和VirtualBox的差异速查
很多新手混淆了“修改虚拟机密码”和“修改虚拟化软件设置”的区别。这里列一个我常用的平台差异速查表,帮助大家少走弯路:
| 操作项 | VMware Workstation | VirtualBox | 备注 |
|---|---|---|---|
| 显示grub菜单 | 开机时按Shift,或修改vmx的bios.bootDelay | 开机时按Shift,或在BIOS里调整启动延时 | 都依赖VM的固件设置 |
| 挂载现有磁盘 | 编辑设置 -> 添加硬盘 -> 使用现有磁盘 | 设置 -> 存储 -> 添加虚拟盘 | 注意选择正确的描述文件 |
| 快照回滚 | 快照管理器,可分支操作 | 快照查看器,单线操作 | 回滚丢数据,慎用 |
| 从ISO启动 | 设置光驱 -> 选择ISO文件 | 设置 -> 存储 -> 光驱 | 需要设置固件启动顺序 |
关于VMware Workstation连接不上的问题,我额外多说一句:很多人反馈“vmware workstation 无法连接到虚拟机。请确保您有权运行该程序、访问该程序使用”,这种情况大概率是VMware的授权服务没启动。Windows下按Win+R输入services.msc,找到VMware Authorization Service并启动,再打开Workstation就正常了。这类问题跟密码修改本身无关,但经常在虚拟机开不了机时被误判为密码问题。
5.3 修改密码后不能立即重启的检查清单
在我的实操流程里,每次改完密码不急着点“重启”,都会先过一遍这个清单:
- /etc/shadow文件是否确实是新哈希,第二字段有没有以
!开头 - SELinux场景下是否执行了
touch /.autorelabel - 是否无意中改了/etc/passwd里的shell字段为
/bin/false或/sbin/nologin(我曾经手滑改错,导致密码正确却登录不了,排查了半小时) - Windows场景下SAM是否写回成功,磁盘有没有处于脏状态
- 磁盘加密场景下LUKS口令是否已解锁
- 登录界面是否启用了“只允许特定用户”的策略(如
/etc/securetty或GDM配置)
另外强烈建议:改完密码以后,立刻用新密码在虚拟机的图形控制台上登录一次,确认成功后再进行下一步。远程SSH工具可能会因为旧连接、密钥缓存而干扰判断,控制台登录的结果最干净。
5.4 关于VNC和显示环境的小结
热词里提到“vnc viewer 虚拟机鼠标变成一个点没反应”,这其实也和密码修改有一点关系。VNC连接时鼠标异常,多半是因为虚拟机的显示驱动或桌面环境配置被改过,导致输入事件没有正确映射。遇到这种情况,建议先用虚拟机自带的控制台(VMware的Tab、VirtualBox的预览窗口)登录完成密码修改,再回到VNC环境。因为改密码这个动作本身不依赖GUI,控制台里操作反而比VNC稳定得多。
如果一定要在VNC里操作,可以在VNC会话里按下Ctrl+Alt+Del打开安全选项,或直接切换到终端(Ctrl+Alt+F3到F6),用命令行完成修改,再切回图形界面。鼠标异常不影响键盘输入,盲操作虽然不快,但能救急。
6. 一些实际项目里的经验沉淀
最后再分享几个我长期处理虚拟机密码问题时沉淀下来的习惯。
我会在每次为虚拟机做重大调整之前,先拍一个“干净快照”,快照描述里写清楚当前状态和密码,然后基于这个快照做后续操作。这样做的好处是,一旦密码重置过程中把系统搞坏,可以直接回滚到快照,而不是推倒重来。快照不是万能的,它占空间、影响性能,但作为保险丝,性价比极高。
还有一点,很多人改完密码后就不管密码库了,几个月后再次忘记,又来找我重置。我现在给客户处理完密码,都会顺手把新密码写进团队的密码管理工具,或者至少在虚拟机的备注里注明“最后修改时间:某年某月”。虚拟机的描述字段、VMware的Annotation、VirtualBox的描述信息,都是放这些备注的好地方。
另外,如果是由模板或云镜像批量克隆出来的虚拟机,需要注意cloud-init的覆盖机制。Ubuntu Cloud Image第一次启动时,cloud-init会执行用户数据脚本,如果你在用户数据里指定了chpasswd,那么机器每次重置都会把密码改回去。遇到“改了密码,下次重启又变回原样”的怪现象,先查/etc/cloud/cloud.cfg.d/下的配置文件,把chpasswd相关配置禁用掉。
密码重置的本质不是“记住密码”,而是“有办法重新拿回控制权”。虚拟机的磁盘可挂载、grub可编辑、快照可回滚,这三件事的组合,决定了绝大多数密码问题都能在半小时内解决。把这个能力练熟,比到处找破解工具靠谱得多。希望这篇文章能帮你省下下一次重装系统的时间。