他的回复:
先定性质:Permission denied 不是网络问题,别在安全组上耗时间OpenSSH 的报错是分层的,这一层决定了排查顺序:Connection timed out / No route to host:网络层不通,才轮到安全组、ACL、路由、实例没启动。Connection refused:22 端口没监听,sshd 没起来、改过端口,或实例刚创建还没起服务。Permission denied (publickey) / Permission denied (publickey,password):TCP 已建立、sshd 已应答、密钥交换已完成,纯粹是「这个用户 + 这份凭证」没被接受。你描述的是第三种。也就是说 22 端口是通的、sshd 是活的,你列的第 6 条(安全组有没有放行 22)大概率不是元凶——真正被安全组挡住时,现象是卡住十几秒后超时,而不是秒回 Permission denied。密钥和密码同时被拒,问题一定收敛在认证层的三件事上:登录用的用户名、实例里的凭证、sshd 的认证开关。第 0 步:让客户端把服务端的底牌亮出来这一步比反复试 chmod 有效率得多:ssh -vvv -i ~/your-key.pem @盯三行输出:1. debug1: Authentications that can continue: publickey,password—— 服务端愿意接受哪些认证方式。如果这里只有 publickey,说明密码登录在服务端就被关掉了(或该用户不允许密码登录),你换密码自然是死路,不是密码记错。2. debug1: Offering public key: /path/your-key.pem—— 没有这一行,说明本地密钥根本没被加载:路径写错、文件权限过宽被客户端拒收(会先打 WARNING: UNPROTECTED PRIVATE KEY FILE)、或文件其实是 .ppk 而不是 OpenSSH 格式。有 Offering 但紧跟着又是 Authentications that can continue,说明公钥发出去了、服务端不认,即 authorized_keys 里没有它。3. debug1: Authenticating to as ''—— 确认用户名。华为云不同公共镜像默认用户不同(CentOS/Debian 一般是 root,Ubuntu 是 ubuntu),拿错用户名时,密码再对也是 Permission denied。第 1 步:用控制台 VNC 旁路进机器看日志SSH 进不去时,控制台的「远程登录」(VNC)不经过 sshd,是最好的旁路。进去后按顺序看:# 1) sshd 到底在不在、监听哪个端口ss -tlnp | grep -E ':22|sshd'# 2) 认证失败的原始原因(这一行会直接告诉你为什么拒)sudo tail -n 50 /var/log/secure # CentOS / RHEL / openEulersudo tail -n 50 /var/log/auth.log # Ubuntu / Debiansudo journalctl -u sshd -n 50 --no-pager日志里的措辞能直接分流:Authentication refused: bad ownership or modes for file /home/xxx/.ssh/authorized_keys → 权限/属主问题,见第 2 步。Failed password for root from ... → 密码确实被送到了服务端且校验失败:密码不对,或该用户没有密码。User xxx not allowed because not listed in AllowUsers / ROOT LOGIN REFUSED → sshd 配置或用户策略拦截。Invalid user xxx → 用户名不存在,问题在第 0 步的第 3 条。第 2 步:文件权限(chmod 600 只是其中一半)sshd 默认开启 StrictModes,只要链路中任一环权限过宽就拒收,且报错只说 Permission denied,不告诉你原因。VNC 里一次性修正:chmod 700 ~/.sshchmod 600 ~/.ssh/authorized_keyschmod go-w ~ # 家目录不能对 group/other 可写,这条最常被漏chown -R $(id -u):$(id -g) ~/.sshrestorecon -Rv ~/.ssh # 仅 CentOS/RHEL/openEuler 且 SELinux 为 enforcing 时需要getenforce # 返回 Enforcing 才需要上一行authorized_keys 里还要确认公钥是一整行(ssh-rsa AAAA... comment 不能断行、不能带多余空格)。从网页复制时被自动换行截断,是新手最常见的坑之一。第 3 步:authorized_keys 里到底有没有你的公钥用本地私钥反推公钥指纹,再和机器里的比对,比肉眼扫字符串可靠:ssh-keygen -lf ~/your-key.pem # 本地私钥的指纹(SHA256:...)ssh-keygen -lf ~/.ssh/authorized_keys # VNC 里执行,看列表里有没有同一个如果里面是一条完全不同的公钥,说明实例绑定的密钥对不是你手上这把——这正好对应你列的第 4 条。注意云上换绑密钥对有一个容易忽略的前提:更换/绑定密钥对后必须重启(或按控制台提示执行重置操作)才会写进实例,只点绑定不重启,实例里的 authorized_keys 还是旧的。这是「我明明绑了却还是 Permission denied」的第一大原因。第 4 步:sshd 配置的真实取值不要只看 /etc/ssh/sshd_config 主文件——新版发行版会把配置拆到 sshd_config.d/*.conf,优先级更高,后面的会覆盖前面的:sudo sshd -T | grep -Ei 'passwordauth|pubkeyauth|permitrootlogin|allowusers|port'以 sshd -T 的输出为准(它是合并后的生效值),逐项对照:密钥登录必须 pubkeyauthentication yes;密码登录必须 passwordauthentication yes,且 permitrootlogin 不能是 no(Ubuntu 系默认 prohibit-password,即只允许密钥、不许密码);改完记得 sudo systemctl reload sshd,并且保持当前 VNC 会话不要断,另开一个窗口验证,避免把自己锁在外面。关于「密码登录也被拒绝」的单独说明如果创建实例时选的是密钥对登录,实例内 root 通常没有设置密码,此时密码登录必然失败——不是密码错,而是压根没有可用密码。正确做法是在控制台对该实例执行「重置密码」并按要求重启使其生效,同时确认上一步的 PasswordAuthentication、PermitRootLogin 已放开。边界与几个易踩的坑不要用 chmod 777 或 chmod -R 755 ~/.ssh 绕过:看起来「能登了」,实际是关掉了 StrictModes 的保护,之后任何人只要拿到目录写权限就能塞公钥进来。新版客户端 + 老镜像:OpenSSH 8.8 起客户端默认禁用 ssh-rsa(SHA-1)签名,老服务端只提供 ssh-rsa 时,握手成功但认证阶段直接 Permission denied (publickey),-vvv 里会看到 no mutual signature algorithm。临时验证:ssh -o PubkeyAcceptedAlgorithms=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa ...,能登进去就说明是这个原因,根治要升级服务端或换 ed25519 密钥。.ppk ≠ .pem:Windows 上用 PuTTYgen 生成的是 PuTTY 格式,OpenSSH 客户端读不了,先用 PuTTYgen 的 Conversions → Export OpenSSH key 转一次。反复失败可能触发账号临时锁定:部分镜像启用了 pam_faillock,连续多次认证失败会锁一段时间,此时密码正确也登不进(日志里是 account locked 一类记录,以你机器实际日志为准)。排查时优先用密钥,别用密码硬试。若确认 sshd 配置、权限、密钥都对,仍然只报 Permission denied,最后再看一眼 /etc/hosts.deny、/etc/ssh/sshd_config 里的 DenyUsers,以及是否有安全加固基线把 SSH 收得更严——这类镜像往往改了默认端口并禁用了 root 登录。按上面顺序走,-vvv 那一步基本就能把范围从「六个可能」压到「一个确定原因」,剩下的都是对症处理。