SSH 无法连接必须先按故障阶段分类:域名解析、路由、TCP 端口、SSH 握手、认证、登录后会话。把所有问题都归因于“密钥权限”或“代理”会浪费大量时间。本文给出客户端与服务端两侧都可执行的系统排查流程。
一、先读懂错误信息
Connection timed out:通常是路由、安全组、防火墙、NAT、代理或端口未响应。
Connection refused:目标可达,但该端口没有监听或被主动拒绝。
Connection reset / closed:中间设备或服务端在握手期间关闭连接。
Permission denied:已经连到 SSH 服务,问题位于用户、密钥、认证策略或目录权限。
Host key verification failed:主机指纹变化,应先核实实例身份,不能直接忽略。
二、确认目标没有连错
date -Is
nslookup example.com
# Linux/macOS
dig +short example.com
# Windows PowerShell
Resolve-DnsName example.com核对 IP、端口、用户名、环境、堡垒机和云实例状态。若域名解析到 198.18.0.0/15 等测试保留地址,常见原因是代理软件的 Fake-IP DNS;应检查代理模式、DNS 和绕过规则,而不是把该地址当真实服务器地址。
三、从客户端测试 TCP 可达性
# Windows PowerShell
Test-NetConnection <HOST> -Port 22
# Linux/macOS
nc -vz -w 5 <HOST> 22
traceroute <HOST> # Windows 使用 tracertPing 失败不等于 SSH 不通,因为 ICMP 可能被禁;关键是 TCP 目标端口。比较同网络、手机热点和另一台主机的结果,可以区分本机代理、办公网出口和服务端问题。
四、用详细日志定位停在哪一步
ssh -vvv -o ConnectTimeout=10 -p 22 ubuntu@<HOST>日志停在 Connecting 表示 TCP 尚未建立;出现 Remote protocol version 说明 SSH 握手已经开始;Offering public key 后仍失败说明进入认证阶段。排障日志可能包含用户名、路径和主机信息,对外分享前要脱敏。
五、检查代理、VPN 和 MobaXterm
系统浏览器能访问网页,并不代表 SSH 会自动使用同一个代理。检查 MobaXterm 会话的 Network settings、SSH gateway、Proxy、端口转发和全局代理;暂时禁用代理后用 IP 直连做对照。若必须经过堡垒机,使用明确的 ProxyJump 配置。
ssh -J jumpuser@bastion.example.com ubuntu@private-host
ssh -G ubuntu@<HOST> | grep -Ei 'hostname|port|user|proxy'若代理使用 Fake-IP DNS,要为服务器域名设置直连/真实解析规则。不要把私钥上传给代理服务或粘贴到聊天工具。
六、云侧逐层检查
实例处于运行状态,公网 IP/EIP 没有变化。
安全组入站仅允许可信来源 IP 到实际 SSH 端口。
网络 ACL 入站和出站都允许请求及临时返回端口。
公网子网有到 Internet Gateway 的路由;私网主机应通过 VPN、专线或堡垒机进入。
源地址是否因公司出口、VPN 或家庭宽带变化。
不要为了排障长期把 22 端口开放到 0.0.0.0/0。临时规则也应限制源 IP、记录负责人并设置删除时间。
七、通过云控制台进入服务器后检查监听
如果 SSH 完全不可达,优先使用云厂商串口控制台、会话管理或救援模式进入,而不是反复尝试密码。
sudo ss -lntp | grep -E ':22'
sudo systemctl status ssh --no-pager # Ubuntu/Debian
sudo systemctl status sshd --no-pager # RHEL/CentOS
sudo journalctl -u ssh -u sshd --since "30 min ago" --no-pager
sudo sshd -tsshd -t 无输出通常表示语法检查通过。修改配置后先验证,再 reload;保留现有已登录会话用于回滚,切勿先退出唯一管理通道。
八、防火墙、封禁和监听地址
sudo ufw status verbose
sudo firewall-cmd --list-all 2>/dev/null
sudo nft list ruleset
sudo iptables -S
sudo fail2ban-client status sshd 2>/dev/null确认 sshd 是监听 0.0.0.0/:: 或目标网卡,而不是只监听 localhost。检查 fail2ban、安全代理和 TCP Wrappers 类策略是否封禁了当前出口 IP。解除封禁前确认来源可信,并追查为何触发。
九、密钥认证与权限
客户端私钥只应由当前用户读取;服务端 authorized_keys 及其父目录必须由目标用户拥有,且不能对组或其他用户可写。
# 客户端 Linux/macOS
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
ssh-keygen -y -f ~/.ssh/id_ed25519 | head
# 服务端
sudo -u <USER> stat -c '%U:%G %a %n' ~<USER> ~<USER>/.ssh ~<USER>/.ssh/authorized_keys
sudo chown -R <USER>:<USER> ~<USER>/.ssh
sudo chmod 700 ~<USER>/.ssh
sudo chmod 600 ~<USER>/.ssh/authorized_keysWindows 上要通过文件属性或 icacls 移除多余继承权限,并确认 MobaXterm 选择了正确私钥格式。不要反复转换密钥覆盖原文件;先备份并通过公钥指纹核对。
十、服务端认证策略
sudo sshd -T | grep -Ei 'port|listenaddress|pubkeyauthentication|passwordauthentication|permitrootlogin|allowusers|denyusers|authorizedkeysfile|maxstartups'
sudo journalctl -u ssh -u sshd --since "10 min ago" | tail -100
getent passwd <USER>
sudo passwd -S <USER>sshd -T 展示最终生效值,可发现 Include 和 Match 块覆盖。核对用户名、shell、账户锁定、AllowUsers/DenyUsers、PubkeyAuthentication 和 AuthorizedKeysFile。Ubuntu 云镜像常用 ubuntu,其他镜像可能是 ec2-user、debian 或 rocky。
十一、SELinux、磁盘和系统资源
df -hT
df -i
free -h
systemctl --failed
getenforce 2>/dev/null
ls -Zd ~<USER>/.ssh ~<USER>/.ssh/authorized_keys 2>/dev/null
sudo restorecon -Rv ~<USER>/.ssh 2>/dev/null磁盘或 inode 满会导致日志、临时文件和会话创建失败;内存耗尽或进程数达到上限也会让连接被关闭。SELinux 标签异常时使用 restorecon 恢复策略标签,不要直接永久关闭 SELinux。
十二、连接建立后立即断开
ssh -vvv -tt ubuntu@<HOST> /bin/bash --noprofile --norc
sudo tail -n 100 /var/log/auth.log 2>/dev/null
sudo tail -n 100 /var/log/secure 2>/dev/null重点检查 shell 是否存在、home 是否可访问、.bashrc/.profile 是否包含 exit 或失败命令、PAM、磁盘空间、MaxSessions 和命令限制。用最小 shell 测试可以区分认证成功后的环境问题。
十三、安全修改与回滚流程
保持一个已登录会话不关闭,并准备云控制台备用通道。
备份配置,单次只改一个变量。
执行 sshd -t,确认无错误后 reload 而不是 restart。
新开终端验证登录、sudo、文件传输和堡垒链路。
失败立即恢复备份并 reload;验证成功后再关闭旧会话。
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S)
sudo sshd -t && sudo systemctl reload sshd # Ubuntu 服务名可能为 ssh十四、故障检查清单
□ 已根据错误信息确定网络、握手、认证或会话阶段
□ 域名、真实 IP、端口、用户名和出口 IP 已核对
□ 代理/VPN/Fake-IP 与直连结果已对比
□ 云安全组、ACL、路由和主机防火墙已逐层检查
□ sshd 监听、配置语法、日志和最终认证策略已确认
□ 密钥所有权、权限、指纹和 SELinux 标签已确认
□ 修改前保留可用会话,验证后再结束旧通道
总结
SSH 排障最有效的方法是按连接阶段缩小范围:先确认目标与 TCP,再看握手、认证和会话。代理、密钥权限只是其中两个分支;用客户端 -vvv、服务端日志和云网络证据相互印证,才能安全恢复而不扩大暴露面。