刚接手一批服务器或者自己本地虚拟机折腾的时候很多人第一件事就是改SSH登录密码。这活儿听起来简单不就是passwd敲一下嘛但实际做起来坑真不少。不同发行版的细微差别、root 和普通用户改密的场景差异、改完密码后连不上的排查思路、还有那些和密码策略相关的配置文件每一个环节都可能让你卡住。这篇就专门聊聊 Linux 下修改 SSH 登录密码这件事从最基础的命令到批量操作、失败排查再到密码策略设置把里面该注意的点一次说清楚。不管你是刚入门的小白还是偶尔帮同事救场的兼职运维这篇都应该能帮你少走点弯路。1. 改密码之前先搞清楚这3件事跳过这一步直接敲passwd的人往往会在后面付出代价。不是吓唬你我见过太多人改完密码把自己锁在服务器外面最后只能通过云控制台或者机房 IPMI 去重置。所以动手之前花两分钟想清楚下面几件事。1.1 你到底要改谁的密码root 还是普通用户这是最基础但也最容易被忽略的问题。Linux 下修改密码的核心命令是passwd但“谁在执行”和“改谁的密码”决定了命令的参数和权限要求。如果你是 root 用户或者有sudo权限你可以修改系统中任意用户的密码。比如要改 root 自己的密码sudo passwd root如果你是一个普通用户想改自己的登录密码直接执行passwd不需要加用户名系统会让你先输入当前的旧密码验证身份然后再设置新密码。passwd这里有一个很关键的权限逻辑只有 root 能修改别人的密码。普通用户想改别人的密码系统会直接拒绝提示Permission denied或者让你去找管理员。这个设计是为了防止用户之间互相篡改密码属于 Linux 多用户体系的基本安全边界。另外注意一点用sudo passwd root修改 root 密码时系统不会要求你输入 root 的旧密码因为你已经是 sudo 用户了这是 sudo 机制授权范围内的操作。但如果你想用su - root切换身份后再执行passwd那就必须要知道 root 当前的密码才能切过去。这两种路径在实际操作中要分清楚别在同事的机器上迷糊了。1.2 当前登录状态确认别改到一半断连改密码本身是个瞬间操作但真正让人头疼的是改完之后连接断开然后新密码又因为各种原因登录不上。所以在动手之前我一般会做两个小确认。第一个确认当前 SSH 会话是否稳定。如果你是通过 Wi-Fi 远程连接服务器网络本身就不稳定我建议你先 ping 一下服务器确认延迟和丢包率在正常范围内再执行改密操作。改密过程中断连并不会导致系统崩溃但会让人心态崩溃。第二个确认你是否还有别的登录通道。这个特别重要。如果你的服务器是云服务器确认一下云控制台的 VNC 或管理终端是否可用如果是虚拟机确认宿主机上的虚拟控制台是否能访问。一旦 SSH 密码改完登不进去这就是你的救命通道。这个习惯我强烈建议每一个人都养成尤其是生产环境的服务器。我曾经因为改密后 SSH 服务配置没生效大半夜靠云厂商的网页终端才把 sshd_config 改回来没有备用通道的话那晚就只能坐在机房门口哭了。1.3 不同发行版的改密命令差异Linux 发行版虽然内核同源但用户态工具链和命令细节上存在不少差异。好在修改密码这个场景命令基本统一都是passwd由shadow-utils或passwd包提供各大主流发行版Debian/Ubuntu、CentOS/RHEL/Rocky、openSUSE、Arch都通用。真正有差异的是以下几个方面密码到期策略有些发行版默认开启了密码到期机制比如 Ubuntu 桌面版在首次登录后会强制你修改密码而 CentOS 7 默认PASS_MAX_DAYS: 99999也就是永不过期。PAM 配置路径Debian 系通常在/etc/pam.d/common-passwordRed Hat 系在/etc/pam.d/system-auth和/etc/pam.d/password-auth改密码复杂度策略时要找对文件。用户绑定和 SELinuxRed Hat 系默认启用 SELinux虽然改密码不受影响但改了用户 home 目录权限之类的操作可能被 SELinux 拦截。我的建议是改密前先确认发行版版本和 init 系统命令上cat /etc/os-release就能看到。这能帮你判断后续排查问题的方向不至于用 Ubuntu 的思路去处理 CentOS 的问题。2. 修改SSH登录密码的核心操作确认好基础信息后就可以实际操作了。这部分我会把passwd命令的细节、多用户场景、批量修改和管道操作的隐患都展开讲一下基本都是日常高频使用的内容。2.1 passwd命令的两种用法与交互过程passwd命令的表层用法很简单但它的交互过程和安全机制值得新人了解一下。场景一root 改自己的密码sudo passwd执行后系统提示New password:和Retype new password:输入两遍一致后显示passwd: password updated successfully。这里有个细节输入密码时屏幕不会有任何回显连星号都不会显示。这是正常的不是键盘坏了也不是系统卡了只是安全设计防止别人看到你输入了多长的密码。很多人第一次用时会反复确认这是不是没输入进去。场景二root 改指定用户的密码sudo passwd zhangsan系统会直接提示输入新密码不会要求输入 zhangsan 的旧密码。这在重置忘记密码的账号时非常有用。场景三普通用户改自己的密码passwd系统首先提示Current password:要求输入当前密码验证。验证通过后设置新密码。这里有个心理博弈新密码不能和旧密码太相似否则 PAM 策略会拒绝。有一点要特别提醒新密码设置时如果连续两次输入不一致命令会报passwd: Authentication token manipulation error需要重新执行。如果输入的密码太简单系统会警告BAD PASSWORD: The password is shorter than 8 characters但它仍然会让你继续输入第二遍并更新成功除非 PAM 的minlen策略设置为拒绝。关于 PAM 策略如何硬性拦截后面第 4 节会详细讲。关于时间戳passwd修改成功后/etc/shadow文件中对应用户那一行的第三个字段最后一次修改密码的日期以天为单位从 1970-01-01 算起会被更新。用chage -l username能看到详细信息chage -l zhangsan2.2 批量修改多台服务器的密码管理多台服务器时一台台 SSH 上去执行passwd无疑很低效。我处理超过 5 台机器时一般会改用批量方式。方案一循环 sshpass如果你有一个统一的临时密码可以用sshpass配合循环批量修改。sshpass并非所有发行版默认安装需要手动装。这里给一个示例脚本注意别在生产环境直接复制的先理解逻辑#!/bin/bash # 批量修改服务器密码脚本示例 HOSTS192.168.1.10 192.168.1.11 192.168.1.12 USERroot OLDOldPass123 NEWNewPass456 for host in $HOSTS; do sshpass -p $OLD ssh -o StrictHostKeyCheckingno $USER$host \ echo $USER:$NEW | chpasswd echo $host 修改成功 done这个脚本本质上用chpasswd在目标机器上完成密码变更比在 SSH 会话里跑交互式passwd更适合脚本化。chpasswd从标准输入读取用户名:密码格式的内容非常方便。方案二Ansible 或批量运维平台如果机器规模上到几十上百台手动脚本的可靠性就有点跟不上了我会推荐上 Ansible。下面这个 ad-hoc 命令可以批量更新所有机器的 root 密码ansible all -m user -a nameroot update_passwordalways password{{ NewPass123 | password_hash(sha512) }} -k注意password_hash过滤器会自动生成符合/etc/shadow格式的哈希串这是官方推荐的姿势。update_passwordalways表示不管当前密码是什么都强制更新如果你的场景是“仅在密码过期时才改”可以改成on_create。我的经验是能用 Ansible 就别自己写脚本循环。不是不相信脚本而是 Ansible 有完善的错误处理、日志和重试机制出错后定位问题快得多。2.3 关键细节管道echo传密码的隐患与安全替代方案很多追求效率的朋友尤其是看过一些老教程的喜欢用下面这种方式修改密码echo NewPass123 | passwd --stdin root这里有一个极易踩坑的细节--stdin参数是Red Hat 系的passwd才支持的Debian/Ubuntu 上的passwd并没有这个参数。你在 Ubuntu 服务器上执行这条命令会得到Usage: passwd [options] [LOGIN]然后啥也不改。这是发行版差异最典型的血泪坑。就算在 CentOS 上能用这种方式也有两个隐患。第一个隐患是密码会出现在 shell 的历史记录里第二个隐患是进程列表里会短暂显示密码明文因为它是作为命令行参数或标准输入传递的。多用户共用服务器时其他人通过ps aux在那一瞬间就能看到你的新密码。如果你实在想用一行命令完成非交互式修改我建议尽量配合chpasswd或chpasswd -e。在 Debian/Ubuntu 和 CentOS 上都有直接输入密码不经过命令行参数安全性相对好一些echo root:NewPass123 | chpasswd其中-e参数表示输入的是已加密的密码串适用于你已经有哈希值的场景。比如你可以先在一台机器上用openssl passwd -6生成一个密码哈希然后把这个哈希批量下发到其他机器。echo root:$(openssl passwd -6 NewPass123) | chpasswd -e3. 改完密码之后连接出问题怎么办改完密码后最尴尬的时刻是当你用新密码登录时发现登不进去。本节将这部分的排查思路和常见坑总结一下这些都是实战中反复出现的问题。3.1 密码修改成功但连接失败先看sshd_config有一种情况特别常见passwd显示修改成功但 SSH 用新密码登录时报Permission denied, please try again。很多人第一反应是“密码是不是没改成功”然后反复重试甚至怀疑键盘坏了。大多数情况下密码确实改成功了问题出在 SSH 服务端的配置上。检查/etc/ssh/sshd_config中这几个关键参数PasswordAuthentication yes是否允许密码登录。如果它是no那你用密码登录当然会被拒绝。PubkeyAuthentication yes是否允许公钥登录。如果服务器开启了公钥登录但没启用密码登录而你之前一直是密钥登录改密码当然无效。PermitRootLogin有三个常见值yes允许 root 密码登录、prohibit-password不允许 root 密码登录但允许密钥、no完全禁止 root 登录。如果你改的是 root 密码而这个参数是prohibit-password那么用密码登录 root 必然被拒需要用普通用户登录后su -切换。排查时先看配置grep -E ^(PasswordAuthentication|PubkeyAuthentication|PermitRootLogin) /etc/ssh/sshd_config如果发现了不合适的配置修改后需要重启 sshd 才能生效sudo systemctl restart sshd # 或者 sudo service sshd restart还有一点容易忽略sshd 配置支持 Match 块和不同端口的多实例。如果你的 sshd_config 里有类似下面这样的块注意别被坑到Match User zhangsan PasswordAuthentication no这种情况表示针对zhangsan这个用户密码登录是被禁止的。即便你在系统层面改了密码SSH 层面还是不让密码登录。这种细粒度配置排查起来比较费眼建议直接sshd -T查看最终生效的配置sudo sshd -T | grep -E passwordauthentication|permitrootlogin3.2 改密后无需重启SSH服务这个问题经常有人问改了密码之后需要重启 sshd 吗答案是不需要。SSH 登录时服务端只负责验证你提交的密码和/etc/shadow中的哈希是否匹配密码存在系统用户数据库里和 SSH 服务的运行状态无关。你改完密码的瞬间下一次 SSH 登录就会使用新密码。你可以自己测一下改完密码保持当前会话不断开然后另开一个终端尝试新密码登录会发现已经生效。真正需要重启 sshd 的场景是你修改了/etc/ssh/sshd_config配置文件。比如改端口、改登录方式限制这些配置是 sshd 进程启动时加载的不重启不会生效。但这里有个细节重启 sshd 不会踢掉当前已建立的 SSH 连接已有的会话会继续存活只有新的连接会使用新配置。所以你可以放心重启 sshd不用担心自己被断开。如果是systemctl restart sshd过程中出现配置错误导致服务起不来那就麻烦了——我的建议是先用sshd -t检查配置语法sudo sshd -t如果有语法错误sshd -t会直接报错这时候千万别重启服务先修配置。3.3 SSH密钥登录时改密码的坑很多人在使用 SSH 密钥登录时对“密码”的理解会出现偏差。这里要区分两个完全不同的密码第一个密码SSH 登录密码也就是用户系统密码。你改了它不影响已经配置好的密钥登录因为密钥登录走的是公钥认证不验证密码。只要服务器上有你的公钥而你本地持有对应的私钥你照样能登录。第二个密码SSH 私钥的 passphrase口令。如果你生成密钥对时设置了 passphrase那么每次使用私钥时会要求输入这个口令。这个口令和系统密码毫无关系改了系统密码也不会影响私钥的使用。很多人遇到的问题是服务器端禁用了密码登录只允许密钥登录用户自己忘了私钥 passphrase或者换了电脑没带私钥这下就彻底登不进去了。这种情况只能通过备用通道VNC、控制台去修改 sshd_config把密码登录先开回来或者把新公钥加到~/.ssh/authorized_keys里。还有一个容易忽略的坑当你改了系统密码后如果使用ssh-copy-id登录某些服务器会短暂触发 SSH 登录失败原因是本地的 SSH agent 缓存了旧凭据。清一下 agentssh-add -D然后重新尝试登录。这个问题在 mac 和 Windows 的 SSH agent 上都遇到过属于改密后的“假故障”。4. 密码策略、有效期与账号管理经验改密码只是手段保障安全才是目的。这节讲一下和密码相关的账号管理经验包含有效期设置、复杂度策略、新用户密码预置以及高频错误速查。这些内容在现场运维和面试中都是高频考点。4.1 用chage管理密码有效期Linux 的密码有效期信息存在/etc/shadow文件中直接改这个文件很不明智正确姿势是用chage命令。查看某个用户当前的密码有效期chage -l zhangsan输出内容包含上次修改时间、密码过期时间、两次修改最小间隔、过期后账号宽限天数等。常见的需求是设定 90 天强制改密sudo chage -M 90 zhangsan这个命令的意思是设置zhangsan的密码最长使用天数为 90 天。到了第 90 天系统会要求用户登录时修改密码。如果你希望某个用户密码永不过期可以设为-M -1或者配置/etc/login.defs里的PASS_MAX_DAYS。但注意如果/etc/login.defs里设置了默认的PASS_MAX_DAYS新用户创建时会沿用这个默认值所以对公司内部的安全策略来说chage是在单独用户粒度做覆盖。chage -E则可以设置账号的到期日期比如让一个临时员工的账号在某一天之后自动失效sudo chage -E 2025-12-31 tempuser这个命令在管理临时账号时很实用比手动删用户安全得多。4.2 PAM密码复杂度策略passwd命令在验证新密码时会走 PAMPluggable Authentication Modules模块默认的密码复杂度策略由pam_pwquality.so或pam_cracklib.so控制。在 Debian/Ubuntu 上配置文件在/etc/pam.d/common-password在 CentOS/RHEL 上配置文件在/etc/pam.d/system-auth和/etc/pam.d/password-auth。常见的配置项大致如下password requisite pam_pwquality.so retry3 minlen12 difok3 ucredit-1 lcredit-1 dcredit-1 ocredit-1各参数含义retry3用户最多尝试 3 次输入新密码。minlen12密码最小长度 12 位。difok3新密码至少要有 3 个字符和旧密码不同。ucredit-1至少包含 1 个大写字母。lcredit-1至少包含 1 个小写字母。dcredit-1至少包含 1 个数字。ocredit-1至少包含 1 个特殊符号。实际配置时ucredit这类参数为负数表示“至少需要几个”为正数表示“最多允许几个”这个很多人会混淆。比如ucredit-1是必须至少 1 个大写字母如果是ucredit1反而表示最多允许 1 个大写字母含义完全相反。如果你设置了这些策略但发现passwd仍然接受弱密码很可能是因为 PAM 配置没有被正确加载或者你有多个配置文件相互覆盖。排查时可以用pamtester或直接观察passwd的报错信息。生产环境上做修改前建议先备份 PAM 配置文件改错会导致所有用户无法修改密码连 SSH 密钥登录可能都受影响别问我怎么知道的。4.3 新建用户时提前设置密码很多新手用useradd创建用户后会发现新用户处于“锁定”状态无法直接登录。这是因为useradd默认创建的用户没有设置密码/etc/shadow中该用户记录的密码字段是!或!!表示账号锁定。正确的姿势是创建用户后马上设置密码sudo useradd -m zhangsan sudo passwd zhangsan或者用一条命令完成echo zhangsan:初始密码 | sudo chpasswd这里有一个安全建议创建用户后尽早设置一个临时密码并要求对方首次登录后修改。要让用户首次登录必须换密码可以用sudo chage -d 0 zhangsan-d 0表示将密码修改日期设为 0也就是 1970-01-01系统会认为该用户的密码在很久以前就到期了下一次登录时强制要求修改密码。这个机制在批量开通账号时非常实用。如果你发现创建用户后 SSH 登录时报Permission denied先检查一下/etc/shadow中该用户的密码字段是不是!。是的话说明只是没设密码并不是 SSH 配置问题。4.4 常见错误提示速查表下面这个表格是我在实际操作中整理的高频错误和排查方向因为系统版本和 PAM 配置不同细节可能有差异但排查思路通用。错误提示可能的含义排查建议passwd: Authentication token manipulation error两次输入的新密码不一致或 PAM 模块异常重新执行passwd仔细输入检查 PAM 配置passwd: Authentication failure普通用户验证旧密码失败确认当前密码输入正确Caps Lock 是否开启Permission denied, please try againSSH 登录被拒绝检查 sshd_config 的 PasswordAuthentication 和 PermitRootLoginPermission denied (publickey)服务器只允许密钥登录使用密钥登录或通过控制台临时开启密码登录Your password has expired密码已过期必须重置按提示修改密码或用chage -d 0强制重置You must wait longer to change your password两次修改密码间隔太短检查/etc/shadow中该用户的最小修改间隔或执行chage -m 0BAD PASSWORD: The password is too similar to the old one新密码和旧密码太像换一个完全不同的新密码这个警告不一定阻止修改user zhangsan does not exist目标用户不存在用id zhangsan确认用户是否存在还有一个检查思路很重要如果你修正了密码登录配置记得先ssh -v查看详细登录日志它会明确告诉你认证被拒在哪一步。这比盲目改配置高效得多。5. 几个容易被忽略的小经验写到这我顺势分享几个实操中小经验看着不起眼但能省不少事。第一个经验改密码前先开一个新终端测试旧密码是否可以正常登录。不要觉得多此一举这能排除当前 SSH 会话使用的密钥登录还是密码登录的混淆情况。万一你一直在用密钥登录对密码登录是否开启都没概念改完密码当然会一头雾水。第二个经验改密码后要顺手检查一下历史命令。如果你刚才用管道方式传过密码~/.bash_history里可能有敏感记录。清一下history -c history -w如果你使用的是echo | passwd --stdin密码还会出现在进程列表里所以还是尽量用chpasswd的标准输入方式。第三个经验写脚本时尽量用chpasswd而不是passwd --stdin。除了发行版差异chpasswd还支持批量处理多行输入而且天然适合管道操作。脚本的可移植性和可维护性都会更好。第四个经验日常服务器管理中加入类似“改密后检查 sshd 配置”的 checklist。我见过不止一个案例PasswordAuthentication 被之前的同事改成了 no然后密码登录永远失败所有人都以为是密码问题白白排查了一整天。最后一个个人习惯每次批量改完密码后我都会随机抽一台机器重新登录一次。密码这种凭据一旦批量下发配置错误很容易被掩盖只有亲自走一遍完整流程才能确认从认证到授权的各个环节都没问题。
