拿到一台新服务器,第一件事就是改root密码。听起来就是个passwd敲两下回车的事,但真在生产环境里操作过的人都知道,这里面坑多得超乎想象——单用户模式进不去、SELinux 导致重置失效、改了密码 SSH 反而连不上了、被 PAM 策略拦下来……每一条我都踩过。
这篇文章不是教你敲那三行命令,而是把“修改root密码”这个动作拆开揉碎,覆盖三种常见场景:还记得旧密码的常规修改、忘记密码的应急恢复、改完之后的权限与安全校验。同时把不同发行版(CentOS、Ubuntu、Rocky)之间的差异也讲清楚,基本上看完你就能独立处理公司服务器、自己实验环境里的各种改密问题。
1. 常规修改流程:记住旧密码时的标准操作
大部分情况下修改root密码都是主动行为,比如新服务器初始化、定期安全加固、离职人员交接。这时候你有当前密码,操作路径非常明确。
1.1 直接改密:passwd 命令的用法与输出解析
root身份下执行passwd,系统会提示输入两次新密码,然后更新/etc/shadow文件。如果你是非root用户,想改自己的密码,直接敲passwd也会进入修改流程,但会先验证当前密码。
# root用户直接修改自己的密码 passwd # 普通用户修改自己的密码,会先验证当前密码 passwd # root强制修改某个用户的密码,不需要知道该用户的旧密码 passwd username # 查看密码状态,包括最后修改日期、过期时间等 passwd -S username看到passwd: all authentication tokens updated successfully这行输出就代表修改成功。这里有个容易忽略的参数:passwd -l是锁定密码,passwd -u是解锁。我见过有人误操作把root锁了,然后一脸懵地来找我说服务器登不上了。
修改root密码时,系统对密码强度有基本校验。如果你的密码太简单,比如123456、password,系统会直接拒绝并提示密码太短、与用户名相同或者过于简单。但root执行的密码修改,即使系统给出警告也通常会写入成功,这取决于 PAM 配置——后面讲安全策略的时候我再细说。
1.2 非交互式改密的三种姿势
脚本化操作服务器时,纯交互式的passwd就没法用了。这里分享三个替代方案:
# 方法一:使用 chpasswd,最推荐的方式 echo "root:你的新密码" | chpasswd # 方法二:使用管道传给 passwd --stdin(CentOS/RHEL系支持) echo "你的新密码" | passwd --stdin root # 方法三:使用 expect 自动交互(适用于无法用 --stdin 的系统) /usr/bin/expect <<EOF spawn passwd root expect "New password:" send "你的新密码\r" expect "Retype new password:" send "你的新密码\r" expect eof EOFchpasswd是我最推荐的方式,因为它在所有主流发行版上都可用,而且语法最简单。--stdin在 Ubuntu 系统上不支持,但chpasswd是通用的。
这里要特别提醒:用脚本改密后,务必检查命令是否有明文密码记录在 shell history 里。我用过的最稳妥的办法是改完后执行history -c或者把命令写成交互式输入变量的形式。
2. 忘记root密码的应急恢复:三种模式实操
这是真正的重头戏。网上讲忘记root密码的文章很多,但大部分只说了一种方法,而且经常没讲清楚适用系统版本,导致读者跟着操作到一半就卡死了。以下内容同时覆盖 RHEL/CentOS 7/8/9、Rocky Linux、Ubuntu 20.04/22.04,按实际情况区分处理。
2.1 单用户模式:最经典也最容易出意外的方法
单用户模式的原理是:在系统启动早期(内核已加载但尚未进入完整多用户状态时),通过修改 GRUB 引导参数进入一个只有 root shell 的最小运行环境,在这个环境里直接重置密码。
具体操作步骤:
- 重启服务器,在 GRUB 菜单界面(通常是开机后第一个出现的文本菜单)高亮选择要进入的内核版本,按
e键进入编辑模式。 - 找到以
linux开头的那一行(不同系统可能是linux16),在行尾追加single或1(数字1),然后按Ctrl + X或F10启动。 - 系统会进入一个带
#提示符的根 shell。直接执行passwd root设置新密码。 - 执行
reboot重启服务器。
说起来简单,实际执行时会有几个坑。最严重的一个坑是:在 RHEL/CentOS 7/8/9 系列系统中,进入单用户模式后/sysroot目录(根文件系统实际挂载点)可能是只读状态。直接执行passwd会报Authentication token manipulation error。
正确的姿势是:
# 在单用户模式的shell里依次执行 mount -o remount,rw /sysroot chroot /sysroot passwd root # 如果改了SELinux策略或需要重启时重新打标签,执行以下两条 touch /.autorelabel exit reboot第二步chroot /sysroot很多人会漏掉。不 chroot 直接改密码,修改的是内存根文件系统的/etc/shadow,重启后系统还是用原来的密码,白忙活一场。另外,如果系统启用了 SELinux(CentOS/RHEL默认启用),在 chroot 后最好执行touch /.autorelabel,否则可能出现密码已改但重启后仍然认证失败的情况。加上这行后重启时系统会对所有文件重新打 SELinux 标签,耗时取决于磁盘大小,但能避免诡异的权限问题。
2.2 紧急模式与 rd.break:RHEL系更干净的应急路径
RHEL/CentOS 7及后续版本中,还有一个更可控的方法:通过给内核传递rd.break参数,在内核加载完、根文件系统切换前中断启动过程,直接进入内存中的初始 ramdisk 环境(initramfs)。这个方法比单用户模式更底层,适合单用户模式因为各种原因进不去的情况。
操作步骤:
- 重启进入 GRUB 菜单,按
e编辑内核参数行(linux开头那行)。 - 在行尾追加
rd.break,按Ctrl + X启动。 - 系统启动会中断在一个 shell 界面,提示符类似
switch_root:/#。 - 此时根文件系统尚未挂载,需要手动操作:
# 重新以读写方式挂载根文件系统 mount -o remount,rw /sysroot # 切换到真实的根分区环境 chroot /sysroot # 修改密码 passwd root # 如果SELinux处于启用状态,执行自动重打标签 touch /.autorelabel # 退出chroot并重启 exit rebootrd.break和单用户模式的关键区别在于:前者在 root 文件系统挂载之前介入,后者在系统进入 init 进程前后介入。两种方式都可以完成密码重置,但rd.break对启动流程的破坏性更小,错误风险也相对低一些。如果单用户模式进不去,优先试这个。
2.3 Ubuntu/Debian 的恢复模式:grub 编辑与 recovery 菜单
Ubuntu 20.04/22.04 桌面版默认有一个 recovery 菜单入口,在 GRUB 菜单里选择Advanced options for Ubuntu,选择带(recovery mode)后缀的内核项,然后选择root下拉到命令行。这个模式下根分区通常已经是读写状态,直接passwd root就行。
如果 recovery 菜单不可用(一些云服务器或精简安装的 Ubuntu 没有这个菜单),手动编辑 GRUB 参数的方式也适用:
- 在 GRUB 菜单按
e进入编辑。 - 找到
linux开头的那一行,把ro改为rw(重要,否则根分区只读),行尾追加init=/bin/bash。 - 按
Ctrl + X启动,会直接进入 root shell。 - 执行
passwd root修改密码。 - 执行
exec /sbin/init或直接reboot重启。
这里有个 Ubuntu 特有的细节:直接把ro改为rw比先进入 shell 再mount -o remount,rw /更干脆利落,因为 init 进程都没启动,直接以读写方式挂载根分区不会触发各种依赖 init 的服务报错。设置完密码后重启进系统,一切正常。
2.4 恢复模式的横向对比与选型建议
| 方法 | 适用系统 | 介入时机 | 复杂程度 | 文件系统只读风险 | 推荐场景 |
|---|---|---|---|---|---|
| 单用户模式 | RHEL系/CentOS 6及以下 | init系统启动前 | 低 | CentOS 7+需手动remount | 快速应急 |
| rd.break | RHEL系/CentOS 7+ | initramfs阶段 | 中 | 需手动remount | 单用户模式进不去时 |
| Ubuntu recovery根shell | Ubuntu桌面版 | init系统启动前 | 低 | 低 | 桌面环境 |
| init=/bin/bash | Ubuntu/Debian | init系统启动前 | 低 | 需改ro为rw | 云服务器/精简环境 |
选哪个不重要,关键是你要知道手上这台机器更适合哪条路。我的习惯是:CentOS/RHEL 系列优先单用户模式,进不去再换 rd.break;Ubuntu 优先 recovery,没有 recovery 菜单就编辑 GRUB。
3. 改完密码之后的连锁反应:安全性与权限校验
密码改完了,重启了,能登录了——但事情没完。我见过太多人改完密码就以为万事大吉,结果过两天发现:改了密码的账号被第三方工具锁定了、SSH 登录突然要密码而不是密钥了、某个服务静默失败。这些往往都和密码修改后的系统行为有关。
3.1 密码策略与 PAM 配置的干预逻辑
修改密码时看起来只是写入/etc/shadow,实际上整个过程受 PAM(可插拔认证模块)控制。系统中有三个关键文件决定了密码是否可以修改、修改后多久过期、复杂度要求是什么:
# 密码有效期策略 /etc/login.defs # PAM密码质量校验配置(RHEL系) /etc/security/pwquality.conf # PAM密码模块配置 /etc/pam.d/passwd/etc/login.defs里的关键参数:
PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 PASS_MIN_LEN 5 PASS_WARN_AGE 7如果你们公司的安全策略要求密码90天强制更换、最短使用3天、提前7天提醒,对应的修改是:
PASS_MAX_DAYS 90 PASS_MIN_DAYS 3 PASS_WARN_AGE 7注意:PASS_MIN_DAYS设置为大于0时,用户改完密码的当天再想改会被拒绝,因为系统认为“密码刚设置过,还没到允许修改的时间”。这个参数在生产环境里经常被误配置,导致用户改不了密码,报错信息还不直观。
RHEL系系统还有pwquality.conf中的复杂度设置:
minlen = 12 # 最小长度 dcredit = -1 # 至少包含1个数字 ucredit = -1 # 至少包含1个大写字母 lcredit = -1 # 至少包含1个小写字母 ocredit = -1 # 至少包含1个特殊字符把这些参数设置成负数,表示“至少需要多少个”。如果设成正数,表示“允许最多出现多少个”,语义容易混淆。我第一次配的时候就把dcredit = 1理解为“至少1个数字”,实际效果完全相反,导致怎么设置密码都被拒。
3.2 SSH 登录校验与 PermitRootLogin 的影响
改完root密码后,紧接着要确认 SSH 登录行为是否符合预期。/etc/ssh/sshd_config里有几个关键项:
PermitRootLogin yes # 允许root通过SSH登录 PasswordAuthentication yes # 允许密码认证如果你修改了root密码,但PermitRootLogin被设成no或prohibit-password(只允许密钥),那你用密码登录SSH会直接报Permission denied (publickey),看似是认证失败,实际上是配置层面的限制。
常见的安全实践是:PermitRootLogin no,日常用普通用户登录,有需要时再su -切换到root。如果你们也采用这种方式,那改完root密码后不用重启SSH服务,因为root的SSH登录本来就被禁止了,密码只对本地控制台登录或su切换生效。
反之,如果确实需要允许root密码登录,改完密码后要执行:
systemctl restart sshd重启SSH服务前先跑一下sshd -t校验配置语法,避免参数写错导致SSH服务起不来,把自己锁在门外。这个步骤我用惨痛经历验证过——一次在云服务器上改配置没经过校验直接重启SSH,结果连接被断开,服务也没起来,只能通过VNC控制台进去修复。
3.3 重置密码后的身份验证测试清单
无论用哪种方式改完密码,建议做一套完整的验证流程,检查是否真的改成功了。我的习惯是:
- 重启后以root身份在控制台本地登录,确认密码生效。
- 使用SSH密钥方式登录一次,确认密钥认证没有受到干扰。
- 如果用密码认证,在另一台机器上执行
ssh root@服务器IP,输入新密码,确认能登录。 - 执行
whoami确认当前用户身份是root。 - 检查
/var/log/secure(RHEL系)或/var/log/auth.log(Ubuntu系),确认没有异常的认证失败记录。
如果修改密码后一切正常但SSH仍然无法登录,优先检查:
# 查看认证日志,定位失败原因 tail -50 /var/log/secure tail -50 /var/log/auth.log # 检查防火墙是否放行了22端口 firewall-cmd --list-all ufw status有一次我帮同事排查一个“改完密码无法登录”的问题,折腾半小时后发现是云平台安全组没放行22端口的入方向规则,跟密码完全无关。所以排查问题要按层次来:网络层 → 认证层 → 权限层,不要一上来就钻进密码细节里。
4. 常见问题与排查技巧实录
这一部分整理的是我这些年实际踩过、以及帮别人排查过的典型问题。每一条都有真实场景,不是网上抄来的理论堆砌。
4.1 单用户模式密码重置失效的根因分析
最典型的现象是:在单用户模式里执行passwd成功了,也提示 update successful,但重启后密码还是旧的。
排查方向依次是:
- 是否忘记执行
chroot /sysroot。如果不 chroot,修改的是 initramfs 内存文件系统里的/etc/shadow,真实分区的 shadow 文件根本没动。 - 根文件系统是否以只读方式挂载。
mount -o remount,rw /sysroot必须执行,否则密码写入会报错或部分写入。 - SELinux 上下文是否正确。如果
getenforce返回Enforcing,建议在 chroot 后执行touch /.autorelabel。SELinux 保护的/etc/shadow如果安全上下文不对,会导致系统启动时拒绝读取新密码信息。
完整的自检命令序列:
# 在单用户shell里 mount | grep sysroot # 如果显示 ro 或 rw 不明确,执行 mount -o remount,rw /sysroot chroot /sysroot getenforce # 如果是 Enforcing,执行 touch /.autorelabel passwd root exit reboot4.2 修改密码时报“Authentication token manipulation error”
这个报错是密码修改失败时最常见的提示,涉及的原因有好几种,按出现概率从高到低依次是:
- 根文件系统只读:最常见。用
mount -o remount,rw /或重新挂载对应分区。 /etc/shadow文件属性被锁定:执行lsattr /etc/shadow查看,如果出现i属性(不可修改),执行chattr -i /etc/shadow解锁再改。- PAM 密码复杂度不满足:在单用户模式里改密码也可能触发 PAM 校验,如果执行的是
passwd而不是chpasswd。设置一个足够复杂的密码即可规避。 - 磁盘空间满:
df -h看看/的可用空间是否为0。空间满时密码写入会静默失败,报错也经常是这个。
排查时可以按这个顺序一条条过,基本上每次都找得到原因。
4.3 云平台服务器密码恢复与救援模式建议
云服务器和物理机的应急改密有一点本质区别:云平台通常提供“救援模式”或“VNC登录”,这是最安全可靠的兜底方式。任何在系统启动阶段的操作(单用户模式、rd.break)都存在操作不当导致系统无法启动的风险,而救援模式是平台层面的独立入口,再折腾也不会把系统玩坏。
以我实际用过的经验来说:
- 先去控制台尝试 VNC 登录,很多云平台即使系统还没完全启动也能看到GRUB菜单和启动日志。
- 如果VNC能进GRUB,优先用 rd.break 或单用户模式。
- VNC进不了GRUB(比如启动卡死),使用救援模式:将系统盘挂载到一台临时实例上,在临时实例上修改原系统盘的
/etc/shadow文件来重置密码。 - 修改 shadow 文件时可以不用
passwd命令,直接用 Python 或openssl passwd生成密码哈希。比如:
openssl passwd -6 -salt mysalt 你的新密码这里-6表示生成 SHA-512 加密的密码哈希,-salt后面可以跟任意字符串(用于固定哈希结果,避免每次生成不同值)。把输出的哈希值替换/etc/shadow中 root 对应的第二个冒号字段即可。
4.4 常见故障速查表
| 故障现象 | 可能原因 | 解决动作 |
|---|---|---|
| 改完密码登录报错 | PermitRootLogin设为no或prohibit-password | 默认禁止root密码登录,改用普通用户+su切换 |
| 单用户模式改完重启密码还是旧 | 未chroot /sysroot | 执行chroot后再passwd |
| 单用户模式passwd报token error | 根分区只读 | mount -o remount,rw /sysroot |
| 改完密码后SELinux拒绝认证 | 安全上下文错误 | 执行touch /.autorelabel后重启 |
| 忘记密码但单用户模式进不去 | 引导器损坏或GRUB未加载 | 使用云控制台救援模式或VNC |
| passwd改密报crrypt错误 | /etc/shadow被chattr+i锁定 | chattr -i /etc/shadow |
| 所有密码都对但SSH连不上 | 防火墙或安全组规则 | 检查firewalld/ufw/安全组放行22端口 |
| 为新用户设置密码总是被拒 | pwquality策略过严 | 临时调整/etc/security/pwquality.conf |
5. 密码维护的长期策略与管理心得
密码改完、验证全部通过,这只是起点。作为一个管过上百台服务器的运维,我最后想分享几个关于root密码管理的长效建议。
5.1 密码过期机制与定期轮换的实践
不要等到密码被攻击了才想起来换。系统自带的密码过期机制就是一个很实用的工具,配置好后完全自动运行:
# 设置root密码90天后过期,过期前7天提醒 chage -M 90 -W 7 root # 查看当前策略 chage -l root输出示例:
Last password change : Mar 10, 2025 Password expires : Jun 08, 2025 Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 90 Number of days of warning before password expires : 7如果公司有合规要求(比如等保之类的),密码过期策略是最基础的一条。别忘了把/etc/login.defs里的默认参数也改掉,因为chage只对单个用户生效,新创建的账号还是要靠/etc/login.defs的默认值。
5.2 root密码vs sudo权限:一个常被忽略的安全权衡
我在带新人时反复强调一个观点:root 密码越少人知道越好。生产环境的日常操作,能不用root就不用root。团队协作时,更稳妥的做法是给每个管理员分配普通账号,通过 sudo 授权特定命令。
sudo 的日志记录比 root 直接登录完整得多。/var/log/secure里能看到哪个用户通过 sudo 执行了哪些命令,root 登录反而像个黑洞,出了事查不到是谁干的。另外,sudo 授权可以在不需要时随时收回,root 密码一旦传出去,换密码的成本就高了。
如果你的环境确实需要多人维护,我的建议是:
# 创建管理员组 groupadd admins # 允许这个组的成员执行任何命令,但需要输入密码 %admins ALL=(ALL) ALL # 为某个新管理员添加sudo权限 usermod -aG admins 用户名这样 root 密码可以锁起来只有一两个人知道,其余管理员全部走 sudo。密码泄露的面就小很多,审计也有迹可循。
5.3 密码文件备份与恢复的注意事项
/etc/shadow是系统里最敏感的文件之一,但也是最容易被忽略备份的。系统备份时,shadow 文件通常会被备份工具自动包含。单独做密码文件备份的意义在于:当密码被锁、被误改、或者用户不想找回历史密码时,你可以通过恢复 shadow 文件快速回到之前的认证状态。
实际操作中可以定期将 shadow 文件备份到加密存储:
# 备份shadow文件,权限设为仅root可读 cp /etc/shadow /root/shadow.backup.$(date +%F) chmod 600 /root/shadow.backup.*恢复时注意:shadow 文件权限必须是000(等等,实际上是640或600,不同发行版有细微差别),如果你用chmod把权限改错了,所有用户登录都会报错。稳妥的做法是恢复后执行:
chown root:shadow /etc/shadow chmod 640 /etc/shadow一些 Ubuntu 系系统上shadow组不存在,那就用chmod 600。不同发行版对 shadow 文件的权限要求有差异,最保险的方式是备份时直接用ls -l /etc/shadow记下原始权限,恢复时原样还原。
我个人在实际使用中还有个习惯:每次重置密码后,把新密码的哈希值用保险库或密码管理工具单独保存,而不是直接把明文写在笔记里。这样既保证密码只有维护者自己知道,又不会因为忘记密码再折腾一次单用户模式。几年下来,这个习惯帮我省了很多半夜跑机房的麻烦。