Linux root 密码重置与应急恢复完全指南
忘记自己服务器的 root 密码、接手一台旧机器没凭据,怎么合法地把管理权限拿回来?从单用户模式、systemd 救援、Live CD 到云控制台,本文讲清所有恢复路径,并给出防止别人重置你密码的加固清单。
Linux root 密码重置与应急恢复完全指南
适用:遗忘自己服务器的 root 密码,或合法接手一台旧机器时恢复管理权限。 定位:系统管理员的标准应急操作。任何方法都只能作用于你拥有物理接触或控制台控制权的机器,对未授权系统使用均属违法行为。
一、先看清前提:root 密码到底存在哪
Linux 不存密码明文,存的是哈希。理解存储结构,才能理解每种恢复方法的本质。
flowchart LR
A["用户输入密码"] --> B["pam_unix 取算法 + 盐"]
B --> C["crypt() 计算哈希"]
C --> D["与 /etc/shadow 中记录比对"]
D -->|匹配| E["登录成功"]
D -->|不匹配| F["拒绝"]
G["/etc/shadow<br/>root: \$6\$salt\$hash:…"] -.-> D/etc/shadow存的是算法ID$盐$哈希。算法$1$=MD5、$5$=SHA-256、$6$=SHA-512、$y$=yescrypt(Debian 11+ 默认)。- 哈希是单向的,重置而非解密:把 shadow 里那一行哈希替换成”已知明文”对应的哈希即可。
- 所有”忘记密码”恢复方法,本质都是:想办法以 root 或等价身份进入系统 → 直接改写 /etc/shadow 或调用 passwd。
⚠️ 安全声明:以下操作要求你对该机器拥有合法所有权或控制台控制权(物理键盘、IPMI/iDRAC、云厂商 VNC 等)。在他人系统上执行属非法侵入。
二、四种恢复路径的决策树
按你能拿到的”控制级别”从高到低选:
flowchart TD
Q1{"能否拿到<br/>物理键盘 / 远程控制台<br/>(IPMI/VNC/云控制台)?"}
Q1 -->|能| Q2{"能启动到<br/>GRUB 菜单吗?"}
Q2 -->|能| M1["方法一:GRUB 编辑内核参数<br/>init=/bin/bash 或 systemd.unit="]
Q2 -->|不能(GRUB 加了密码)| Q3{"能用 Live 介质启动吗?"}
Q1 -->|不能(纯 SSH 进不去)| Q4{"有云厂商账号吗?"}
Q4 -->|有| M4["方法四:云控制台重置密码<br/>(阿里云/腾讯云/AWS/GCP/Azure…)"]
Q4 -->|没有| HARD["❌ 没有任何合法控制通道<br/>只能联系机房 / 走厂商工单"]
Q3 -->|能| M3["方法三:Live CD/USB 挂载原根分区<br/>chroot 改密"]
Q3 -->|不能| Q5{"能否进 BIOS/UEFI 改启动顺序?"}
Q5 -->|能| M3
Q5 -->|不能| M2["方法二:systemd emergency<br/>前提:root 密码或救援 shell 未锁"]- 方法一最常用,前提:GRUB 菜单没锁、或你知道 GRUB 密码。
- 方法二救急,但前提苛刻(多数发行版默认 root 没有密码时 emergency shell 直接禁用)。
- 方法三最通用,只要能换启动介质就一定能成;缺点是需要物理接触或虚拟控制台。
- 方法四对云服务器最省事,直接在控制台点”重置密码”。
三、方法一:GRUB 内核参数注入(init=/bin/bash)
适合:GRUB 能进入编辑界面(无密码或你知道密码)的物理机 / 带 VNC 的云主机。
3.1 步骤
sequenceDiagram
participant B as 开机
participant G as GRUB 菜单
participant K as 内核启动
participant S as Shell
B->>G: 按 e 进入编辑
G->>G: 找到 linux / linux16 那一行
G->>G: 行尾追加 init=/bin/bash<br/>(或替换 ro 为 rw init=/bin/sh)
G->>K: Ctrl+X 或 F10 启动
K->>S: 直接进入 bash(不启动 systemd、不挂 /etc/fstab)
S->>S: mount -o remount,rw /
S->>S: passwd root
S->>S: touch /.autorelabel (SELinux 系统)
S->>S: exec /sbin/init 或 reboot -f3.2 操作详解
进 GRUB 编辑:开机在 GRUB 选择菜单高亮你的内核,按
e。若有密码会先提示输入。改内核行:找到以
linux(UEFI)或linux16(BIOS)开头的那一行,Ctrl+e跳到行尾,把ro改成rw并追加init=/bin/bash:# 改前 linux /vmlinuz-6.1 root=/dev/sda2 ro quiet splash # 改后 linux /vmlinuz-6.1 root=/dev/sda2 rw init=/bin/bash启动:
Ctrl+X或F10。几秒后会出现bash-5.1#提示符,你已经是 root。重挂载根分区可写(即使已在参数里写了 rw,这一步也稳):
mount -o remount,rw /改密码:
passwd root # 输入两次新密码,要求符合 PAM 复杂度策略SELinux 系统必须做的一步(CentOS/RHEL/Rocky/Fedora),否则
/etc/shadow上下文错误,重启后无法登录:touch /.autorelabel # 重启后系统会自动重打 SELinux 标签,首次启动会多花几十秒重启:
exec /sbin/init # 最干净,让 systemd 接管 # 或 reboot -f # 强制重启
3.3 Ubuntu / Debian 的”recovery mode”变体
Debian 系 GRUB 默认有 Advanced options → 选 (recovery mode) 内核,它会进入一个 root shell 菜单,直接选 root 即可。注意:Ubuntu 从 16.04 起若 root 没有密码(默认用 sudo),recovery mode 的 root shell 会直接登录——这就是为什么物理接触 Ubuntu 等于拿到 root。
3.4 适用与局限
| 项 | 说明 |
|---|---|
| 速度 | 最快,1~2 分钟 |
| 前提 | GRUB 菜单无密码 / 你知道密码 / 能用 e 编辑 |
| 局限 | GRUB 加了密码且你不知道 → 进不去编辑 |
| 风险 | 极低,只改 /etc/shadow |
四、方法二:systemd emergency / rescue shell
适合:能进 GRUB 但不想改 init,或想用更”正规”的 systemd 救援模式。
# 在 GRUB 的 linux 行尾追加
systemd.unit=emergency.target # 最极端,几乎不挂任何东西,要 root 密码
systemd.unit=rescue.target # 单用户模式,要 root 密码前提:root 必须有已知密码才能进 emergency/rescue。Ubuntu 默认 root 无密码,会直接放行;CentOS/RHEL 若 root 有密码但你忘了,这条路走不通,回到方法一或方法三。
五、方法三:Live CD/USB 挂载原根分区 + chroot
最通用的方法:用任意 Linux Live 介质(Ubuntu Live、SystemRescue、Kali、RHEL 安装盘的”挽救系统”)启动,挂载原系统根分区,chroot 进去改密。
5.1 流程
flowchart LR
A["用 Live ISO 启动"] --> B["识别原系统根分区<br/>lsblk / fdisk -l"]
B --> C["挂载根分区到 /mnt/sysroot<br/>mount /dev/sda2 /mnt/sysroot"]
C --> D["挂载伪文件系统<br/>/proc /sys /dev /dev/pts"]
D --> E["chroot 进入原系统"]
E --> F["passwd root"]
F --> G["exit; 卸载; reboot"]5.2 完整命令
# 1. 找到原系统根分区(看挂载点 / 或 LVM 名)
lsblk -f
# 假设根分区是 /dev/sda2,或 LVM:/dev/mapper/centos-root
# 2. 挂载
mkdir -p /mnt/sysroot
mount /dev/sda2 /mnt/sysroot # 普通分区
# 或 LVM:
# mount /dev/mapper/centos-root /mnt/sysroot
# 3. 如果原系统用了独立的 /boot、/usr、/var、/home 分区,依次挂上
# mount /dev/sda1 /mnt/sysroot/boot
# mount /dev/mapper/vg-usr /mnt/sysroot/usr
# 4. 挂载伪文件系统(让 chroot 内的 passwd、PAM、loginctl 能工作)
mount -t proc proc /mnt/sysroot/proc
mount -t sysfs sys /mnt/sysroot/sys
mount -o bind /dev /mnt/sysroot/dev
mount -o bind /dev/pts /mnt/sysroot/dev/pts
# 5. chroot
chroot /mnt/sysroot /bin/bash
# 6. 改密码(此时就是原系统的 root shell)
passwd root
# 7. SELinux 系统重打标签(CentOS/RHEL/Rocky)
touch /.autorelabel
# 8. 退出并清理
exit
umount -R /mnt/sysroot
reboot5.3 Btrfs / ZFS / 加密分区的额外步骤
- Btrfs:
mount -o subvol=@ /dev/sda2 /mnt/sysroot(子卷名看btrfs subvol list /dev/sda2)。 - ZFS:
zpool import -f rpool,再zfs mount rpool/ROOT/ubuntu。 - LUKS 加密:先
cryptsetup luksOpen /dev/sda2 rootfs解密,再挂载 mapper 设备。全盘加密的机器,没有解密口令谁都救不了——包括你自己。
5.4 适用与局限
| 项 | 说明 |
|---|---|
| 通用性 | 最强,几乎所有情况都能用 |
| 前提 | 能换启动介质(物理键盘 + 可启动 U 盘,或 IPMI 虚拟介质) |
| 局限 | LUKS 全盘加密需要解密口令;云主机无控制台换不了介质 |
六、方法四:云厂商控制台重置
云上的服务器基本都提供”一键重置密码”,不用折腾 GRUB/Live CD:
| 云厂商 | 路径 | 原理 |
|---|---|---|
| 阿里云 | ECS 控制台 → 实例 → 重置实例密码 | 内部 agent 修改 shadow |
| 腾讯云 | CVM 控制台 → 重置密码 | 同上 |
| AWS EC2 | EC2 控制台 → 实例 → 连接 → EC2 Serial Console | 通过串口进单用户模式 |
| GCP Compute | 实例 → 编辑元数据 → startup-script 注入 useradd | 启动脚本加 sudo 用户 |
| Azure VM | 支持和故障排除 → 重置密码 | VMAccess 扩展 |
| 华为云 / 火山引擎 | 控制台实例 → 重置密码 | agent 修改 |
云主机也能跑方法一:用控制台的 VNC 连接重启进 GRUB,再用 init=/bin/bash。方法三在云上通常不可行(无法插入 Live ISO,除非用自定义镜像启动)。
七、改完密码必须做的收尾
很多人改完密码直接 reboot,结果重启登录不上或留安全隐患。按顺序做:
- SELinux 重打标签(CentOS/RHEL 系):
touch /.autorelabel,或重启后restorecon -Rv /etc/shadow /etc/passwd。 - 确认
/etc/passwd的 root 行 shell 字段:必须是/bin/bash(或/sbin/nologin之外的可登录 shell)。检查:grep ^root /etc/passwd。 - 检查 PAM 策略:
/etc/security/faillock.conf或pam_faillock.so的 deny 次数——之前试错太多可能把账号锁了,解锁:faillock --user root --reset # RHEL 8+ pam_tally2 --user root --reset # 旧版 - SSH 登录验证:先用
ssh root@主机(若允许)或普通用户 +sudo -i验证密码。 - 审计日志:如果这台机器之前可能被别人碰过,查一下异常:
last -20 | head # 最近登录 lastb -20 | head # 最近失败登录 journalctl -u sshd --since "7 days ago" | grep -i 'failed\|accepted' grep -i 'sudo' /var/log/secure # RHEL 系
八、各发行版差异速查
| 发行版 | 默认 root 状态 | GRUB 救援 | recovery mode | 备注 |
|---|---|---|---|---|
| CentOS 7 | 有密码 | init=/bin/bash + /.autorelabel | 可用 | XFS + SELinux,必须 autorelabel |
| Rocky/Alma 8/9 | 有密码 | 同上 | 可用 | 用 faillock,不是 pam_tally2 |
| RHEL 8/9 | 有密码 | 同上 | 可用 | 同 Rocky |
| Ubuntu 20.04/22.04 | 无密码(用 sudo) | Advanced → recovery → root | 可用 | recovery root shell 直接进;root 无密码时 GRUB 救援也直接放行 |
| Debian 11/12 | 安装时可选 | Advanced → recovery | 可用 | 默认 yescrypt 哈希 |
| Fedora 39+ | 有密码 | init=/bin/bash | 可用 | Btrfs 默认子卷 |
| openSUSE | 有密码 | init=/bin/bash | 可用 | Snapper 快照系统 |
九、反向防御:如何防止别人重置你的 root 密码
前面所有方法都有一个共同前提——物理接触或控制台控制权。所以加固的核心是”锁死启动链路”。
9.1 启动链加固清单
flowchart TB
A["BIOS/UEFI"] -->|设管理员密码| B["禁止 U 盘/网络启动<br/>Secure Boot 开启"]
B --> C["GRUB"]
C -->|设 GRUB 超级用户密码| D["编辑菜单需密码<br/>禁用 recovery 项"]
D --> E["全盘加密 LUKS"]
E -->|解锁口令独立| F["即使拿到硬盘也读不出数据"]
F --> G["系统层"]
G --> G1["SSH: PermitRootLogin no<br/>PasswordAuthentication no<br/>只允许密钥"]
G --> G2["sudo 配置<br/>NOPASSWD 项最小化"]
G --> G3["审计: auditd + AIDE"]9.2 具体操作
① BIOS/UEFI 密码:进 BIOS(开机按 Del/F2/F10),设 Supervisor Password,把 Boot Mode 里的 USB/Network/CD 启动项禁掉。这样别人插 U 盘启动不了。
② GRUB 密码:CentOS/RHEL 系:
# 生成密码哈希
grub2-setpassword # RHEL 8+,交互输入
# 或:
grub2-mkpasswd-pbkdf2 # RHEL 系输出哈希;Debian/Ubuntu 用 grub-mkpasswd-pbkdf2然后在 /etc/grub.d/40_custom 里加:
set superusers="root"
password_pbkdf2 root grub.pbkdf2.sha512.10000.<哈希>重新生成配置:
grub2-mkconfig -o /boot/grub2/grub.cfg # BIOS
grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg # UEFI此后按 e 编辑 GRUB 会要求输入密码,recovery mode 也被保护。
③ 全盘加密 LUKS:安装系统时选”加密 LVM”,或事后给非根分区加密。效果:即使别人拔走硬盘、用 Live CD 启动,没有解密口令也读不出任何数据——包括 /etc/shadow。这是物理安全的终极手段,代价是每次开机要输口令、云主机通常不支持。
④ SSH 加固(/etc/ssh/sshd_config):
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers opsuser
MaxAuthTries 3这保证即使有人知道普通用户密码,也不能远程爆破 root。
⑤ sudo 最小化:
- 不要给日常账号
NOPASSWD: ALL。 - 把需要免密的命令写成精确白名单:
opsuser ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx。
9.3 加固效果对照表
| 攻击场景 | 只做 SSH 加固 | + GRUB 密码 | + BIOS 密码 + 禁 USB | + LUKS 全盘加密 |
|---|---|---|---|---|
| 远程爆破 root 密码 | ✅ 防住 | ✅ | ✅ | ✅ |
| 远程提权(有普通账号) | ❌ | ❌ | ❌ | ❌(需应用层防护) |
| 物理接触 + GRUB 编辑 | ❌ | ✅ 防住 | ✅ | ✅ |
| 物理接触 + U 盘 Live 启动 | ❌ | ❌ | ✅ 防住 | ✅ |
| 直接拔走硬盘读数据 | ❌ | ❌ | ❌ | ✅ 防住 |
📌 物理安全是兜底:对数据中心托管的机器,机房门禁 + 机柜锁 + 远程控制台(IPMI)密码强度同样关键,软件层再硬也扛不住有人拔硬盘。
十、常见问题(FAQ)
Q1:改完密码重启后还是登不上?
- 90% 是 SELinux 标签问题(CentOS 系):进 GRUB 再
init=/bin/bash,touch /.autorelabel后重启,等自动重标完成。 - 10% 是
/etc/passwdroot 行的 shell 字段被改成/sbin/nologin,改成/bin/bash。
Q2:GRUB 按 e 提示要密码,但我也忘了?
- 用 Live CD 方法三,挂载原分区后改
/etc/grub.d/40_custom删掉superusers行,再grub2-mkconfig。
Q3:LUKS 加密的机器忘了口令怎么办?
- 无解。除非有备份的 header(
cryptsetup luksHeaderBackup)或恢复密钥。全盘加密的意义就是连你自己都救不了——做好密钥备份。
Q4:云主机既不知道密码、也没有控制台 VNC 权限怎么办?
- 走云厂商工单,提供账号所有权证明(实名/手机/邮箱)后厂商可以帮你重置。
Q5:Ubuntu recovery mode 进去后 root shell 提示”按 Enter 维护”但回车没反应?
- 这是新版 systemd 把 recovery shell 改成要密码。回到方法一,直接
init=/bin/bash。
Q6:用 passwd 时提示”passwd: Authentication token manipulation error”?
- 根分区没挂成可写:
mount -o remount,rw /再试;或/etc/shadow文件只读,chattr -i /etc/shadow。
十一、命令速查表
| 目的 | 命令 |
|---|---|
| 看 root 那行哈希算法 | grep ^root /etc/shadow |
| 解锁被 faillock 锁的账号 | faillock --user root --reset |
| 检查 root 登录 shell | grep ^root /etc/passwd |
| 重打 SELinux shadow 标签 | restorecon -v /etc/shadow |
| 生成 GRUB 密码哈希 | grub2-setpassword 或 grub-mkpasswd-pbkdf2 |
| 重新生成 GRUB 配置 | grub2-mkconfig -o /boot/grub2/grub.cfg |
| 看最近登录 | last -20 |
| 看最近失败登录 | lastb -20 |
| LUKS 解密挂载 | cryptsetup luksOpen /dev/sda2 rootfs |
| 云控制台重置 | 各厂商控制台实例 → 重置密码 |
附录:自检清单
重置密码后,确认以下项再宣布恢复成功:
- 能用新密码在本地终端
login: root登录 - 能用新密码
ssh root@主机(若允许)或sudo -i -
grep ^root /etc/passwd的 shell 是/bin/bash -
faillock --user root无锁定记录 - SELinux 标签已重打(CentOS 系):
ls -Z /etc/shadow显示shadow_t -
journalctl -u sshd最近无异常登录尝试 - 若这台机器曾被他人接触过:检查
/etc/sudoers、~/.ssh/authorized_keys、crontab、/etc/passwd是否有后门账号