适合读者:开始独立管理云服务器的初级运维人员。示例以 Linux/OpenSSH 为背景,
192.0.2.20是文档地址,ops是示例用户,操作前替换为实际目标。

1. 先把“连不上”变成具体错误
SSH 连接要经过目标解析、端口连接、服务器身份校验、用户认证和会话建立。不同阶段失败,需要查看不同位置。
先记录实际命令、错误原文、时间、来源网络,以及最近是否发生重装、改端口、换 IP 或密钥。不要把所有问题都归为“密码不对”。
| 常见提示 | 大致定位 |
|---|---|
Could not resolve hostname |
主机名解析 |
Connection timed out |
连接或握手超时,需要看详细输出停在哪 |
Connection refused |
端口连接被拒绝 |
REMOTE HOST IDENTIFICATION HAS CHANGED |
保存的主机身份与当前身份不一致 |
Permission denied (publickey) |
用户认证未通过 |
| 已认证后立即断开 | 登录 Shell、命令限制、PAM 或会话相关条件 |
这些是定位入口,不是直接结论。例如端口拒绝可能来自无人监听,也可能是策略主动拒绝。
2. 客户端先查实际配置,再开启详细日志
同一个 ssh app 命令,可能被 ~/.ssh/config 改写成其他用户、端口或跳板路径。先展开客户端配置:
ssh -G -p 22 ops@192.0.2.20 | \
grep -E '^(hostname|user|port|proxyjump|identityfile|identitiesonly) '
然后对同一个目标进行一次详细连接:
ssh -vvv -o ConnectTimeout=5 -p 22 ops@192.0.2.20
观察是否已经出现连接建立、主机密钥确认、提供公钥、认证成功等信息。-G 和 -v 的作用见 OpenSSH ssh 手册。ConnectTimeout 用于建立连接及初始协议握手阶段,不会为整个交互登录会话设置总时限。
调试输出可能带有内部地址、用户名和密钥路径,转发给他人时按需要脱敏,不要发送私钥内容。
3. 超时:核对请求到底走到哪一层
先核对云控制台上的实例状态、当前公网 IP、网卡和安全组。若公网入口经由负载均衡、NAT 或堡垒机,还要核对对应映射。
安全组规则要匹配真实来源地址、协议和端口。公司的 VPN、出口 NAT 或跳板机可能改变服务器看到的源地址。单纯放行自己笔记本的内网 IP,通常没有意义。
如果已有一个正常会话或云控制台提供带外登录,可以在服务器上查看:
ip -br address
ip route
sudo ss -lntp
确认 SSH 实际监听的端口和地址。只监听特定内网地址的服务,不会自动接受公网网卡上对应端口的请求。
网络 ACL、主机防火墙和返回路由也可能影响连接。优先确认哪条路径与哪条规则不匹配,再作针对性调整;无需把所有来源和端口一并开放。
4. 拒绝连接:确认监听和服务状态
在带外控制台或已有会话中查看本机使用的服务。Debian、Ubuntu 常见为 ssh.service,其他发行版常见为 sshd.service,按实际名称选用:
systemctl status ssh.service --no-pager -l
sudo journalctl -u ssh.service -b -n 100 --no-pager
systemctl status sshd.service --no-pager -l
sudo journalctl -u sshd.service -b -n 100 --no-pager
服务管理方式可能包含 socket 激活,不能仅凭一个 service 暂时 inactive 就认定没有入口;要与实际监听和单元配置对应起来。
若配置刚改过,先检查语法与主机密钥条件:
sudo /usr/sbin/sshd -t
示例路径应与本机实际安装位置核对。命令没有报错,只能说明这项检查通过,不能证明公网路径、用户认证和会话功能都正常。检查模式见 sshd 手册。
5. publickey 认证失败:按用户和密钥两端查
先明确要登录哪个账户。不同云镜像的初始用户名不同,正确私钥配上错误用户,同样可能得到 Permission denied (publickey)。
在客户端明确指定密钥,并限制身份选择:
ssh -vvv -o IdentitiesOnly=yes \
-i "$HOME/.ssh/id_ed25519_ops" \
-p 22 ops@192.0.2.20
确认这份密钥对应的公钥已经配置到目标账户实际使用的公钥来源。常见文件是 ~ops/.ssh/authorized_keys,但服务器也可能使用不同的 AuthorizedKeysFile、集中式公钥命令或 SSH 证书。
如果采用普通文件方式,在服务器查看示例账户的目录:
getent passwd ops
sudo ls -ld /home/ops /home/ops/.ssh
sudo ls -l /home/ops/.ssh/authorized_keys
先根据 getent 确认真实家目录,再替换示例路径。常见设置是用户自己的 .ssh 为 700,authorized_keys 为 600,并由正确用户持有;家目录及相关路径也不能被不可信用户随意改写。权限、ACL 和安全策略都应结合日志判断。
不要对整个家目录递归改权限来碰运气。真正问题可能是文件属于错误账户、公钥不匹配、账户被限制,或配置根本没有读取这个路径。
6. 为什么 grep 出来的配置和实际行为不同
服务端可能使用 Include 文件和 Match 条件。只搜索主文件中的 PasswordAuthentication,不一定能得到某个连接最终使用的设置。
可以用连接上下文查询有效配置:
sudo /usr/sbin/sshd -T \
-C user=ops,host=client.example.test,addr=198.51.100.25 | \
grep -E '^(pubkeyauthentication|passwordauthentication|authorizedkeysfile|authenticationmethods|permitrootlogin) '
替换账户、客户端主机名和服务器看到的来源地址。如果配置包含本地地址、端口或其他 Match 条件,还要提供相应上下文。-T 读取的是配置文件,而不是向正在运行的进程查询状态;若服务实际用了自定义 -f 配置,应指定同一文件。
比如要求 AuthenticationMethods publickey,password 时,正确公钥只完成第一步,后续仍可能需要另一种认证。相关选项见 sshd_config 手册。
7. 主机密钥变化,不是用户私钥坏了
主机密钥用来确认“连接的是哪台服务器”,用户密钥用来确认“你是谁”。重装机器可能更换主机密钥,错误 DNS、错误 IP 或异常中间连接也可能让身份不一致。
应先通过云控制台、管理员或其他可信渠道确认实例身份和主机指纹。如果可以使用可信带外控制台,可以查看服务器自己的指纹:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
实际算法和文件要与客户端提示的主机密钥对应。确认是预期变更后,再按具体主机和端口更新客户端记录。ssh-keyscan 可以收集服务器发来的公钥,但单凭一次网络采集不能证明它值得信任。
8. 修复后,用一个新连接验证
修改 SSH 服务配置时保留当前可用会话,先执行 sshd -t,再按本机单元支持的方式重载。可以先查看:
systemctl show sshd.service -p CanReload
服务名仍需按实际替换。重载成功后,从原先失败的客户端发起一个新连接,核对目标、用户和认证方式;再验证登录命令:
whoami
hostname
同时查看对应时间的服务端日志。旧会话仍然可用,不能证明新登录一定成功。把原始错误、修复内容和新连接结果记录下来,才能完成这次排查。