Ubuntu VPS 如何更改 root 密码并恢复 SSH 登录
使用 passwd、chpasswd 和 chage 修改 Ubuntu VPS 的 root 或用户密码,验证新密码,并在 SSH 连接或 root 密码丢失时重新登录。
如何在 Ubuntu 上更改 VPS 的 root 密码
要在 Ubuntu 上更改 VPS(虚拟专用服务器)的 root 密码,请以能够运行 sudo 的用户身份打开 SSH(安全 Shell)会话,然后运行 sudo passwd root。系统会要求您输入两次新密码,但不会要求输入旧密码,因为 sudo 已经验证了您的身份。若要更改您自己的登录密码,请在不带参数的情况下运行 passwd。系统会先要求您输入当前密码。
passwd # your own password
sudo passwd deploy # another user's password
sudo passwd root # root's password这就是完整的操作流程。下面介绍容易出错的部分:在失去可用于修复问题的会话之前,验证新密码是否有效;从脚本设置密码;主动使密码过期;以及在密码已经丢失时重新登录。
修改密码前先打开第二个会话
现在打开第二个 SSH 会话,并保持连接。只要还有一个已通过身份验证的 Shell 会话处于活动状态,本指南中几乎所有故障都能在两分钟内修复;如果最后一个会话关闭,通常就需要通过控制台处理。
已经打开的 Shell 会话在您修改、锁定或使其所属账户过期后仍会继续工作,因为 SSH 只在登录时检查凭据,之后不会再次检查。例外情况是 sudo。它的时间戳过期后,会通过 PAM(可插拔认证模块)重新检查密码。默认情况下,时间戳会在上次提示输入密码后 15 分钟过期。因此,新密码第一次真正接受测试,是在下次 sudo 要求输入密码时,而不是登录时。
在第一个会话保持打开的情况下,在第二个会话中测试新密码。
使用 passwd 修改自己的密码
passwdChanging password for deploy.
Current password:
New password:
Retype new password:
passwd: password updated successfully只有 passwd: password updated successfully 表示 /etc/shadow 中的哈希已被替换。其他任何输出都表示旧密码仍然有效。
这里可能出现两种失败。passwd: Authentication token manipulation error 后紧跟 passwd: password unchanged,表示您输入的当前密码错误,或者存放 /etc/shadow 的文件系统不可写;在恢复模式下,后一种情况很常见。You must choose a longer password. 来自 /etc/pam.d/common-password 中的 pam_unix,该检查会对普通用户应用长度和相似度限制。
在大多数 VPS 镜像中,默认账户(ubuntu,或您的服务商提供的其他账户名)根本没有密码,只有 SSH 密钥。passwd 没有可供验证的当前密码,因此无法通过第一个提示。请改用 sudo passwd $USER,因为该账户的 sudoers drop-in 文件允许其免密码运行 sudo。
使用 sudo passwd 修改其他用户的密码
sudo passwd deployroot 不会被要求输入旧密码,而且 pam_unix 会跳过针对普通用户执行的密码强度检查,因此 root 可以为用户设置一个该用户无法自行设置的密码。
锁定密码是单独的操作。sudo passwd -l deploy 会在存储的哈希值前添加 !,因此任何密码都无法匹配该哈希值。sudo passwd -u deploy 会移除它。使用 sudo passwd -S deploy 读取当前状态。
锁定密码不会阻止该用户登录。用户 ~/.ssh/authorized_keys 中的任何密钥仍然有效,因为公钥身份验证不会读取 /etc/shadow。若要完全停止账户登录,请使账户过期:
sudo usermod --expiredate 1 deploy这会将账户过期日期设置为 1970 年,因此无论提供哪种凭据,sshd 都会拒绝登录。使用 sudo usermod --expiredate '' deploy 撤销该设置。
不要使用 passwd -d。它会设置空密码,而不是锁定密码;在仍将 nullok 保留在 PAM 堆栈中的旧版本中,任何人都可以使用空密码。
VPS 上的 root 需要密码吗?
Ubuntu 默认锁定 root。/etc/shadow 中保存的是 !,而 sudo passwd -S root 会输出以 root L 开头的行。在设置密码前,任何人都无法使用密码以 root 身份登录,这也是镜像改为提供一个具备 sudo 权限的用户的原因。应保持使用 VPS 上的最小权限用户账户,而不是直接使用 root。
设置 root 密码只能带来一个特定用途:通过服务商控制台访问系统。该控制台连接到网络栈下层的虚拟机,因此即使 sshd 配置错误或防火墙规则有误,它仍可正常工作。但这也会带来代价。root 设置密码后,GRUB 恢复菜单中的 root shell 会要求输入该密码。因此,用于重置遗忘密码的工具现在也受同一个密码保护。
设置 root 密码不会允许 root 通过 SSH 登录。Ubuntu 默认使用 PermitRootLogin prohibit-password,也就是仅允许使用密钥。请检查服务器实际使用的配置:
sudo sshd -T | grep -i permitrootlogin在解析每个 Include 行后,sshd -T 会输出生效配置。因此,当 /etc/ssh/sshd_config.d/ 包含 drop-in 文件时,它是唯一可靠的答案。
使用 chpasswd 在脚本中设置密码
passwd 从终端读取输入,无法由脚本驱动。chpasswd 从标准输入读取 user:password 对,每行一对。
printf '%s:%s\n' 'deploy' "$NEW_PASSWORD" | sudo chpasswd该方法可用,但会将明文密码写入 shell 历史记录和 CI(持续集成)日志。请先对密码进行哈希处理:
HASH=$(openssl passwd -6)
printf '%s:%s\n' 'deploy' "$HASH" | sudo chpasswd -eopenssl passwd -6 会在不回显输入的情况下提示输入两次密码,然后输出以 $6$ 开头的 SHA-512 crypt 哈希值。-e 告诉 chpasswd 第二个字段已经是哈希值,因此会原样将其复制到 /etc/shadow 中。该哈希值可以安全地存储在代码仓库或 CI 变量中,明文密码不会离开输入它的那台计算机。
Ubuntu 24.04 在 passwd 设置新密码时使用 yescrypt($y$)进行哈希处理,而 openssl passwd -6 使用 SHA-512。两种格式都能在登录时通过验证,因为 libxcrypt 可以读取这两种格式。混用它们没有问题,而且 openssl passwd -6 在每个 Ubuntu LTS 版本中的行为都相同;chpasswd -c YESCRYPT 则不是这样:20.04 中较旧的 shadow 软件包不识别该方法名称。
如何确认密码确实已更改?
先检查元数据,再通过登录进行验证。
sudo passwd -S deploydeploy P 08/01/2026 0 99999 7 -1第二个字段表示状态:可用密码为 P,已锁定为 L,完全没有密码为 NP。日期表示密码上次更改的时间,因此应显示为今天。后面的数字是下文介绍的密码有效期字段。
最安全的实时测试是直接使用 sudo。sudo -k 会丢弃缓存的时间戳,sudo -v 会强制重新提示输入密码。如果新密码在那里被接受,说明 PAM 已接受该密码,并且当前会话没有发生任何变化。
sudo -k && sudo -v要测试其他账户,请在非特权 shell 中运行 su - deploy。不要运行 sudo su - deploy,因为 root 不会被要求输入密码,这样的测试无法证明任何问题。密码错误时会显示 su: Authentication failure。
真正的测试是从笔记本电脑发起新的 SSH 登录,同时保持当前工作会话处于打开状态:
ssh -o PubkeyAuthentication=no deploy@203.0.113.10这里的 Permission denied (publickey). 表示服务器从未提供密码身份验证,因此更改密码也无法通过这种方式登录。Permission denied, please try again. 表示服务器确实提供了密码身份验证,但拒绝了您输入的密码。
在下次登录时使用 chage 强制修改密码
sudo chage -d 0 deploy-d 0 将上次修改日期设置为 epoch,因此 PAM 会将密码视为已过期。下次进行交互式登录时,系统会先要求输入当前密码,再要求设置新密码,然后才提供 shell。sudo passwd -e deploy 完全相同。
仅对使用密码进行交互式登录的账户执行此操作。密码过期也会影响基于密钥的登录,因为即使身份验证使用的是密钥,sshd 仍会运行 PAM account 阶段。脚本中的 ssh deploy@203.0.113.10 'systemctl restart app' 会因以下错误失败并停止:
Password change required but no TTY available.该行之后的内容都不会执行,并且任务只报告非零退出码。
密码老化字段的含义
sudo chage -l deployLast password change : Aug 01, 2026
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7这些数字是该用户在 /etc/shadow 中对应行的第 4 到第 8 个字段。最短天数(chage -m)表示用户再次修改密码前必须等待的时间,可防止用户在被强制修改密码后立即改回旧密码。最长天数(chage -M)表示密码保持有效的时间。警告天数(chage -W)表示登录时开始显示警告的时间。非活动天数(chage -I)表示密码过期后仍可使用的宽限期,超过该期限后密码将完全无法接受。账户过期时间(chage -E)是一个固定日期,与密码独立。
sudo chage -M 90 -W 14 deploy仅在策略要求时设置该字段。NIST(美国国家标准与技术研究院)自 2017 年起就不建议例行设置密码过期,因为这会促使用户对同一个密码采用可预测的变体;NIST 建议在有证据表明密码已泄露时强制修改密码。使用密码管理器保存的长且唯一的密码,再配合基于密钥的 SSH,比每 90 天修改一次密码更安全。
忘记 root 密码时的处理方法
如果服务器上的任一账户都可以运行 sudo,就无需恢复密码:sudo passwd root 会设置新密码。最棘手的情况是完全无法登录。
以下操作都需要使用服务商控制台。大多数面板将其列为 VNC(虚拟网络计算)或串行控制台。它直接连接到网络协议栈下方的虚拟机,因此 sshd 设置和防火墙规则不会影响它。
- 在面板中重启服务器,并监控控制台。
- 进入 GRUB 菜单。云镜像通常会设置
GRUB_TIMEOUT=0,因此 BIOS 启动时按住Shift;UEFI 启动时,在重启开始后立即反复按Esc。 - 依次选择
Advanced options for Ubuntu、以(recovery mode)结尾的条目,然后在恢复菜单中选择root。 - 先运行
mount -o remount,rw /。恢复环境会以只读方式挂载根文件系统,因此不执行此操作时,passwd会失败并显示passwd: Authentication token manipulation error,因为它无法写入/etc/shadow。 - 为所需账户运行
passwd ubuntu,然后从面板重启服务器。
如果 root 已设置密码,而丢失的正是该密码,恢复 shell 会要求输入密码,此方法无法继续。请改为启动服务商的救援镜像,然后挂载实际磁盘,并在该系统中修改密码。
lsblk
sudo mount /dev/vda1 /mnt
sudo mount --bind /dev /mnt/dev
sudo mount --bind /proc /mnt/proc
sudo mount --bind /sys /mnt/sys
sudo chroot /mnt passwd ubuntu
sudo umount -R /mnt请从 lsblk 读取分区布局,不要直接复制本页的 /dev/vda1。根分区通常是容量最大的分区。在 UEFI 镜像中,根分区旁边会有一个较小的 EFI 分区,其中完全没有 /etc 目录。
SSH 不再接受密码时的处理方法
使用仍然打开的会话操作。如果已没有任何会话,请使用控制台。
Permission denied, please try again. 表示服务器提供了密码身份验证,但拒绝了您发送的密码。常见原因是 Caps Lock 已开启,或者控制台键盘布局与设置密码时使用的布局不同。
Permission denied (publickey). 表示服务器从未提供密码身份验证。某处设置了 PasswordAuthentication no。在 Ubuntu 22.04 及更高版本中,该设置通常位于 /etc/ssh/sshd_config.d/ 下的 drop-in 文件中,并会覆盖主配置文件。读取生效的配置值:
sudo sshd -T | grep -Ei 'passwordauthentication|kbdinteractiveauthentication|permitrootlogin'同时设置 KbdInteractiveAuthentication yes 和 PasswordAuthentication no 仍会允许使用密码,因为 keyboard-interactive 方法使用相同的 PAM 堆栈。关闭其中一个而保留另一个,会导致看似仅允许密钥登录的服务器仍然接受输入的密码。
断开连接消息中的 Too many authentication failures 表示客户端在尝试密码前提供了多个密钥,服务器触发了 MaxAuthTries;其默认值为 6。强制使用单一身份验证方法:
ssh -o IdentitiesOnly=yes -o PubkeyAuthentication=no deploy@203.0.113.10在刚才仍可用的端口上出现 Connection refused,通常表示 fail2ban 监控 SSH 在多次失败后封禁了您的地址。其默认封禁规则会拒绝数据包,而不是直接丢弃,因此拒绝会快速返回,而不会超时。在控制台中,sudo fail2ban-client status sshd 会列出已封禁的地址,sudo fail2ban-client set sshd unbanip 203.0.113.10 会解除对您地址的封禁。
密码只是过渡,密钥才是最终方案
可通过 SSH 使用的密码,相当于允许互联网上的每个扫描器不断猜测。改用基于密钥的身份验证后,密码猜测就不再有意义。生成密钥对,安装公钥,然后在执行其他更改前,从第二个终端确认该密钥可以让您登录。SSH 密钥管理基础介绍密钥生成、authorized_keys和密码短语。
然后关闭密码身份验证,并使用 sudo sshd -T确认设置已生效,不要只相信您编辑过的文件。VPS 上的 SSH 加固会介绍值得修改的其余 sshd 设置,新 VPS 上线后的前十分钟则按新服务器上的执行顺序排列这些操作。
之后仍保留一个密码。仅使用密钥的服务器如果 sshd 配置损坏,只能通过服务商控制台访问,而该控制台需要用户名和密码。保留一个强密码的账户,并将密码妥善存储,可以让您在五分钟内修复问题,而不必重新安装系统。
FAQ
如果不知道旧密码,如何在 VPS 上修改 root 密码?
以可以运行 sudo 的用户登录,然后运行 sudo passwd root。该命令会设置新密码,不会询问旧密码,因为 sudo 已完成身份验证。如果服务器上没有任何账户可以运行 sudo,请打开服务商控制台,重启进入 GRUB 恢复菜单,选择 root shell 项,然后运行 mount -o remount,rw /,再运行 passwd。如果 root 已设置密码,而您丢失的正是该密码,恢复 shell 会要求输入密码。此时只能使用服务商的救援镜像,挂载磁盘并执行 chroot。
为什么 passwd 会显示“Authentication token manipulation error”?
该消息通常由两种原因导致。常见原因是在 Current password: 提示符处输入了错误答案,其下方的 passwd: password unchanged 行会确认没有写入任何内容。另一种原因是文件系统不可写。在恢复模式下,/ 会以只读方式挂载,因此会遇到此问题。运行 mount -o remount,rw /,然后重试。
修改 Linux 密码也会修改 sudo 密码吗?
会。sudo 没有自己的密码。它通过 PAM 使用与 SSH 和 su 相同的 /etc/shadow 条目对您进行身份验证,因此每个账户只有一个密码。这也是修改密码后第一次出现 sudo 提示符时可以进行实际验证的原因。在当前会话仍可用时,运行 sudo -k && sudo -v 强制显示该提示符。
修改密码会导致 SSH 密钥或当前会话失效吗?
不会。公钥身份验证不会读取 /etc/shadow,因此修改密码、执行 passwd -l 或执行 chage -d 0 后,密钥仍可正常使用。已经建立的会话会继续保持,因为 SSH 只在登录时检查凭据。活动会话中唯一会发生变化的是 sudo:其 15 分钟时间戳过期后,会要求输入新密码。
如何强制用户在下次登录时修改密码?
运行 sudo chage -d 0 deploy,或运行 sudo passwd -e deploy,两者作用相同。系统会将上次修改日期设为 epoch,PAM 会将密码视为已过期。下一次交互式登录必须先设置新密码,才能启动 shell。不要对通过 SSH 执行脚本的账户执行此操作:此时非交互式命令会因 Password change required but no TTY available. 失败,且不会运行。