Ubuntu VPS 如何修改 root 和用户密码
使用 passwd、chpasswd 和 chage 修改 Ubuntu VPS 密码,验证新密码是否生效,并处理 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。其时间戳过期后,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 permitrootloginsshd -T 会在解析每个 Include 行后输出生效配置,因此当 /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 软件包不认识该方法名称。这些哈希值在跨版本升级后仍然有效,因此将 24.04 服务器升级到 26.04不会强制您重置任何人的密码。
如何检查密码确实已更改?
先查看元数据,再通过登录进行验证。
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 将上次更改日期设置为 Unix 纪元时间,因此 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 /。恢复环境会以只读方式挂载 root 文件系统,因此不执行此命令时,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。root 分区通常是最大的分区。在 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 堆栈。关闭其中一个、保留另一个启用,会导致看似仅允许密钥认证的服务器仍然接受输入的密码。
被拒绝的密钥登录也会输出同一行。因此,如果您提供的是密钥而不是密码,服务器的密码设置只是 Permission denied (publickey) 背后的五个问题之一;ssh -v 的输出会告诉您具体是哪一个问题。
断开连接消息中的 Too many authentication failures 表示客户端在尝试密码前提供了多个密钥,服务器触发了 MaxAuthTries;其默认值为 6。强制只使用一种方法:
ssh -o IdentitiesOnly=yes -o PubkeyAuthentication=no deploy@203.0.113.10在刚才还可用的端口上出现 Connection refused,通常表示 监控 SSH 的 fail2ban 在多次认证失败后封禁了您的地址。其默认封禁规则会拒绝数据包,而不是直接丢弃,因此拒绝响应会很快返回,而不会超时。在控制台中,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 上线后的前 10 分钟则按全新服务器上的执行顺序排列这些操作。
之后保留一个密码。仅支持密钥登录的服务器如果 sshd 配置损坏,就只能通过服务商控制台访问,而控制台要求用户名和密码。您已保存的强密码账户,可以决定问题是 5 分钟内修复,还是必须重新安装系统。
FAQ
如何在不知道旧密码的情况下更改 VPS 上的 root 密码?
以可运行 sudo 的用户登录,然后运行 sudo passwd root。该命令会直接设置新密码,不会询问旧密码,因为 sudo 已完成身份验证。如果服务器上没有任何账户可以运行 sudo,请打开服务商控制台,重启进入 GRUB recovery 菜单,选择 root shell 项,然后运行 mount -o remount,rw /,再运行 passwd。如果 root 已设置密码,而你丢失的正是该密码,recovery shell 会要求输入它。此时只能使用服务商的 rescue image,挂载磁盘并执行 chroot。
为什么 passwd 会显示“Authentication token manipulation error”?
此消息有两个常见原因。第一种是对 Current password: 提示的回答错误,下面的 passwd: password unchanged 行会确认没有写入任何内容。第二种是文件系统不可写。在 recovery mode 中通常会遇到这种情况,因为 / 在该模式下以只读方式挂载。运行 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 minute 时间戳过期后,会要求输入新密码一次。
如何强制用户在下次登录时更改密码?
运行 sudo chage -d 0 deploy,或运行 sudo passwd -e deploy,两者作用相同。存储的最后更改日期会被设为 epoch,PAM 会将密码视为已过期。下一次交互式登录时,用户必须先设置新密码,之后才能启动 shell。不要对通过 SSH 执行脚本的账户执行此操作:此时非交互式命令会因 Password change required but no TTY available. 而失败,且不会运行。