SSH 服务器拒绝了密码,原因通常不是密码输错,而是服务端没有走密码认证这条路:要么 sshd 关闭了密码认证,要么账户被锁定或被 PAM 拦截,要么连接根本没到达 sshd。 按照“先看报错、再看配置、最后看日志”的顺序排查,大多数情况在十分钟内就能定位到根因。
密码认证这一步,服务端其实要过四道关
很多人以为输入密码,服务端比对一下,对就放行、错就拒绝,实际流程比这复杂得多,密码认证是一连串判断里的最后一环,任何一环不通过,客户端收到的都是同一句“Permission denied (password)”。
完整链路大致是这样:
- TCP 连接建立:22 端口(或自定义端口)是否可达,安全组、防火墙有没有放行。
- 协议协商与会话:sshd 接受连接,进入用户认证阶段。
- 认证方式选择:sshd 检查
PasswordAuthentication是否开启,没开就直接跳过密码方式。 - 账户与 PAM 校验:密码本身是否正确,账户是否锁定、是否过期、shell 是否有效、是否被登录频率限制拦截。
关键在于第 3 步和第 4 步,客户端返回的提示几乎一模一样,这就是为什么有人反复输入正确密码,得到的永远是“拒绝”,从运维角度看,这条报错只说明“认证没有成功”,并不说明“密码错了”。
为什么ssh服务器拒绝了密码:五个最常见原因
PasswordAuthentication 被关闭,密码这条路直接走不通
这是出现频率最高的一种,主流发行版和不少云厂商官方镜像,出于安全考虑默认只允许密钥登录,把 /etc/ssh/sshd_config 里的 PasswordAuthentication 设成了 no,此时你在客户端敲密码,服务端连比对都不会比对,直接回绝。
验证方式很直接,在能登录的终端里执行:
sshd -T | grep -i passwordauth
输出 passwordauthentication no 就说明问题在这里,要确认的是实际生效值,而不是配置文件里写的值,因为后面还会说到配置覆盖的问题。
账户被锁、密码过期或 shell 无效,密码对了也进不来
密码正确但账户本身不合格,同样会被拒,常见的情况有:
- 多次输错密码触发锁定策略,账户处于锁定状态。
- 密码被设置为已过期,强制要求改密,而 SSH 非交互会话无法完成改密流程。
- 账户的登录 shell 被设成
/sbin/nologin或/bin/false。 - 账户从未设置过有效密码,密码字段是 或 。
在服务端用下面两条命令核对:
passwd -S 用户名 # 查看密码状态,L 表示锁定,NP 表示无密码 chage -l 用户名 # 查看密码有效期、过期时间、最后修改时间
passwd -S 输出的第二列是关键,P 才是正常可用状态,有些服务器创建账户时用 useradd 但没有 passwd,账户看着存在,实际没有可用密码,这种情况在批量创建账户的脚本环境里并不少见。
PAM 与登录限制:失败几次之后,正确的密码也会被拒
PAM 是 SSH 密码认证背后真正的执行者。pam_tally2、pam_faillock 这类模块会记录失败次数,超过阈值就临时或永久拒绝该账户或该来源 IP,再叠加上 fail2ban 这类工具,失败几次后直接封 IP,客户端表现出的依然是“拒绝密码”,甚至连接超时。
业内专家指出,近年来越多服务器把这些限制做成默认开启,运维人员接手一台旧机器时,往往不知道曾有人为加固而调整过策略,排查方向是查看 /etc/pam.d/sshd 里是否引入了失败计数模块,以及:
faillock --user 用户名 # 查看失败记录 fail2ban-client status sshd # 查看封禁列表
如果账号确实出现在封禁列表中,解锁后再试一次,往往立刻恢复正常。
配置被 drop-in 片段覆盖,改了主文件却没生效
新版 OpenSSH 支持 /etc/ssh/sshd_config.d/ 目录下的片段配置,并且这些片段常常在 sshd_config 顶部通过 Include 被优先加载,结果就是:你在主文件里把 PasswordAuthentication 改成 yes,但片段文件里写着 no,生效的仍然是后者。
行业内有一个共识:判断 SSH 配置以 sshd -T 的输出为准,不以文件内容为准。 排查时顺手看一眼片段目录:
grep -r "PasswordAuthentication" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/
同时注意修改后必须重载服务才生效:
systemctl reload sshd # 或 systemctl reload ssh
reload 比 restart 温和,不会中断已有连接,适合远程操作时使用。
连接还没到 sshd:安全组、防火墙与端口改动的干扰
还有一种容易误判的情况:连接压根没到 sshd,客户端却把超时或连接被拒也笼统理解为“密码被拒”,典型场景是云服务器的安全组只放行了密钥登录用的端口,或者 sshd 端口从 22 改成了其他值,而防火墙没同步放行,此时换个端口、换个网络(比如从办公网切到手机热点)测试,现象会明显不同。
在客户端用 ssh -v 能看到握手停在哪一步,如果卡在 Connecting to ... 就说明是网络层,与密码无关。
ssh密码正确但提示拒绝密码?按这五步自查
第一步:用详细模式看清认证阶段
ssh -v 用户名@服务器IP
重点看输出里 Authentications that can continue: 这一行,如果里面只有 publickey,没有 password,问题就在服务端配置;如果列出了 password 但输入后仍被拒,问题在账户或 PAM。
第二步:确认 sshd 实际生效的配置
sshd -T | grep -iE "passwordauth|permitrootlogin|maxauthtries|port"
一并确认是否禁止了 root 直接登录,有的服务器 PermitRootLogin no,用 root 账号试密码永远失败,这并不是密码问题。
第三步:翻日志找确切原因
不同发行版日志位置不同:
- Debian/Ubuntu:
/var/log/auth.log - CentOS/RHEL:
/var/log/secure - 使用 systemd-journald:
journalctl -u sshd -n 50 --no-pager
日志里会出现诸如 Failed password for invalid user、User xxx not allowed because account is locked、Authentication refused 之类的具体描述,比客户端提示精确得多。
第四步:核对账户与密码状态
回到服务端,用 passwd -S、chage -l 确认账户可用,必要时重置密码:
passwd 用户名
生产环境改密码前,务必先确认还有其他可用登录方式(密钥、控制台 VNC),避免把自己锁在门外。
第五步:排除网络层干扰
从客户端执行 telnet 服务器IP 22 或 nc -zv 服务器IP 22,确认端口连通,在公司机房内网能连、从公网连报拒绝密码,基本可以判定为安全组或边界防火墙策略差异,而不是 SSH 配置问题。
云服务器ssh密码被拒绝怎么办:控制台与镜像的两个坑
云环境有它自己的特殊性,很多“密码被拒”其实是平台侧的默认策略造成的。
官方镜像默认禁用密码登录
多数云厂商提供的公共镜像,出于降低批量爆破风险的考虑,默认关闭密码认证,只保留密钥,新购实例首次登录被拒,八成是这个原因,解决路径是先在控制台用 VNC 或“救援模式”登进去,修改 sshd 配置后重载,再尝试密码登录。
安全组与系统防火墙是两道独立的闸门
安全组放行了 22 端口,不等于系统内 firewalld、ufw 或 iptables 放行了,两道都要过,排查顺序建议先系统防火墙、再安全组:
ufw status # Ubuntu/Debian firewall-cmd --list-all # CentOS/RHEL
如果为了排障临时关闭防火墙,务必在排障完成后立刻恢复,不要把关闭状态留到第二天。
ssh服务器拒绝密码和公钥登录失败的区别
两者在客户端提示上相似,排查路径却完全不同,用一张表对照会更清楚:
| 对比项 | 密码认证被拒 | 公钥认证被拒 |
|---|---|---|
| 客户端典型提示 | Permission denied (password) | Permission denied (publickey) |
| 服务端首要检查项 | PasswordAuthentication 是否开启 | 服务端 authorized_keys 文件权限与路径 |
| 账户层面关注点 | 账户锁定、密码过期、PAM 限制 | 家目录属主与权限、SELinux 上下文 |
| 常见误判 | 反复确认密码是否输错 | 反复重新生成密钥 |
| 快速验证手段 | sshd -T 查认证方式 |
ssh -vvv 看服务端是否收到公钥 |
有个细节常被忽略:authorized_keys 及其上级目录的权限必须严格,家目录 755、.ssh 目录 700、authorized_keys 600 是通行做法,权限过宽时,sshd 会静默拒绝接受公钥,同样表现为“认证失败”。
修好之后的几个防复发动作
- 修改 sshd 配置前先备份,用
sshd -t校验语法,通过后再 reload。 - 改远程配置时保留一个已登录的会话不退出,用新窗口验证能否登录,验证通过再关闭旧会话。
- 密码和密钥两种方式至少保留一种可用,不要同时关闭。
- 在
/etc/ssh/sshd_config里显式写入关键项,避免被片段配置意外覆盖。 - 对频繁爆破的来源做限速或封禁,减少账户被锁定的概率。
据工信部相关安全通告,弱口令和暴力破解长期位居主机失陷原因前列,这也解释了为什么越来越多的默认配置在收紧密码认证。
Q&A:ssh服务器拒绝了密码的常见疑问
Q1:密码肯定没输错,为什么ssh服务器还是拒绝了密码?
因为这条报错只代表认证未通过,不代表密码比对失败,优先用 sshd -T | grep -i passwordauth 确认密码认证是否开启,再看 /var/log/auth.log 或 /var/log/secure 里的具体描述,两步就能区分是配置问题还是账户问题。
Q2:改了 sshd_config 之后还是不行,是没重启服务吗?
有可能是没重载,也可能是配置被 /etc/ssh/sshd_config.d/ 下的片段覆盖,以 sshd -T 的输出现值为准,重载用 systemctl reload sshd,不必用 restart 中断现有连接。
Q3:密码认证和密钥认证,哪个更应该保留?
从安全角度看,密钥认证抗爆破能力更强,适合长期开放的服务;密码认证便于临时接入和移交,但需要配合失败锁定和来源限制,实际部署中两者并存、各自约束,比单纯关掉其中一个更稳妥。
回到最初的问题:SSH 拒绝密码,本质上是服务端在告诉你“这条认证路径不可用或不通过”,把配置生效值、账户状态、日志记录三样东西对齐,绝大多数拒绝密码的情况都能在几分钟内找到确切原因。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/924057.html


评论列表(2条)
这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于用户名的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!
@云云3625:这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于用户名的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!