⚠️ 提示:本站 AI 助手使用博主个人 API Token,没事别特么瞎用。
运维 · · 约 23 分钟阅读

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 -f

3.2 操作详解

  1. 进 GRUB 编辑:开机在 GRUB 选择菜单高亮你的内核,按 e。若有密码会先提示输入。

  2. 改内核行:找到以 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
  3. 启动:Ctrl+X 或 F10。几秒后会出现 bash-5.1# 提示符,你已经是 root。

  4. 重挂载根分区可写(即使已在参数里写了 rw,这一步也稳):

    mount -o remount,rw /
  5. 改密码:

    passwd root
    # 输入两次新密码,要求符合 PAM 复杂度策略
  6. SELinux 系统必须做的一步(CentOS/RHEL/Rocky/Fedora),否则 /etc/shadow 上下文错误,重启后无法登录:

    touch /.autorelabel
    # 重启后系统会自动重打 SELinux 标签,首次启动会多花几十秒
  7. 重启:

    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
reboot

5.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 EC2EC2 控制台 → 实例 → 连接 → EC2 Serial Console通过串口进单用户模式
GCP Compute实例 → 编辑元数据 → startup-script 注入 useradd启动脚本加 sudo 用户
Azure VM支持和故障排除 → 重置密码VMAccess 扩展
华为云 / 火山引擎控制台实例 → 重置密码agent 修改

云主机也能跑方法一:用控制台的 VNC 连接重启进 GRUB,再用 init=/bin/bash。方法三在云上通常不可行(无法插入 Live ISO,除非用自定义镜像启动)。


七、改完密码必须做的收尾

很多人改完密码直接 reboot,结果重启登录不上或留安全隐患。按顺序做:

  1. SELinux 重打标签(CentOS/RHEL 系):touch /.autorelabel,或重启后 restorecon -Rv /etc/shadow /etc/passwd。
  2. 确认 /etc/passwd 的 root 行 shell 字段:必须是 /bin/bash(或 /sbin/nologin 之外的可登录 shell)。检查:grep ^root /etc/passwd。
  3. 检查 PAM 策略:/etc/security/faillock.conf 或 pam_faillock.so 的 deny 次数——之前试错太多可能把账号锁了,解锁:
    faillock --user root --reset          # RHEL 8+
    pam_tally2 --user root --reset        # 旧版
  4. SSH 登录验证:先用 ssh root@主机(若允许)或普通用户 + sudo -i 验证密码。
  5. 审计日志:如果这台机器之前可能被别人碰过,查一下异常:
    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/passwd root 行的 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 登录 shellgrep ^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 是否有后门账号
问问 AI