← 返回工具首页 SSH 连接失败?这篇帮你排查所有原因

SSH 连接失败?这篇帮你排查所有原因

深夜登服务器踩坑,SSH 连不上,网络没动,密码没改,可就是 Connection refused。急得像热锅上的蚂蚁,结果问题可能就藏在某个权限数字或者某个被遗忘的配置里。这篇指南把所有常见的 SSH 连接失败场景全拆开,配上命令行演示,帮你 5 分钟定位根因,不再盲猜。

你正在经历哪种报错?

先认清楚自己碰到了什么,这比盲目试错重要得多。以下是几个最常见的 SSH 报错,先对号入座:

报错 1:Connection refused
ssh: connect to host example.com port 22: Connection refused
报错 2:Connection timed out
ssh: connect to host example.com port 22: Connection timed out
报错 3:Permission denied (publickey)
Permission denied (publickey).
报错 4:Permission denied (password)
Permission denied (password).
报错 5:Connection closed by remote host
ssh_exchange_identification: Connection closed by remote host
报错 6:Host key verification failed
Host key verification failed.

以上六种,涵盖了 90% 以上的 SSH 连接失败场景。下面的排查思路就按这个顺序来,层层过滤,快的话 2 分钟定位,慢的话也不超过 15 分钟。

方向一:网络层面 — 能通吗?

先 ping 一下

# 最基础的连通性测试
ping -c 4 example.com
如果 ping 不通,说明网络层面有问题,这时候 SSH 连不上的根因不是 SSH 本身,是网络。先检查目标服务器是否宕机,或者自己这边的路由/DNS 有没有问题。

telnet 测端口通不通

# 检查 22 端口是否可达
telnet example.com 22

如果提示 Connected to example.com,说明端口层是通的,问题在别处。如果 Connection refused,说明目标机器 TCP 22 端口没有服务在监听,或者被防火墙挡了。

nc 更精确的端口扫描

# -zv 意思是仅测试连接,不发数据
nc -zv example.com 22

输出类似 Connection to example.com 22 port [tcp/ssh] succeeded! 则说明 SSH 端口是通的。

注意:telnet 和 nc 不自带的话,macOS / Linux 装一下:
sudo apt install netcatbrew install netcat

方向二:端口 — 22 还是 2222?

这个被问得最多。很多服务为了安全把 SSH 端口改成了非 22 端口,结果自己忘了,对着默认 22 狂试,还以为被封了。

查看当前连接用的端口

# 明确指定端口连接
ssh -p 2222 user@example.com

服务器上查看 SSH 端口配置

# 在服务器上执行,查看 sshd 监听的端口
sudo grep "Port " /etc/ssh/sshd_config

默认是 22,如果改成其他数字,客户端也必须用 -p 指定。

端口改了但客户端没改?

有一种情况很阴险:服务端确实改了端口,但客户端还是用默认的 22,结果碰到的是一个什么服务都没有的 22,于是 Connection refused。

# 同时扫描常见 SSH 端口,找出哪个在跑 SSH
nc -zv example.com 22
nc -zv example.com 2222
nc -zv example.com 22022
也可以直接让服务器管理员执行 ss -tlnp | grep sshd 查看 sshd 实际监听的端口。

方向三:密钥 — 权限对了没?

密钥登录是最常见的方式,也是最容易被权限坑的。SSH 对文件权限极其敏感,错了直接拒绝。

Permission denied (publickey)?先查这三点:

  1. 私钥文件权限是 600 吗?
  2. 公钥在服务器上的 ~/.ssh/authorized_keys 里有吗?
  3. 用户目录 ~.ssh 目录权限对吗?
# 检查私钥权限
ls -la ~/.ssh/id_rsa
# 权限必须是 600,如果不是,修复它:
chmod 600 ~/.ssh/id_rsa
警告:严禁把私钥权限设为 777,这等于把钥匙公开,SSH 会主动拒绝使用这种私钥。
# 检查 .ssh 目录权限
ls -la ~/.ssh/
# 输出应该类似:
# drwx------  2 user  4096 ... .ssh/
# -rw-------  1 user  ... authorized_keys
# 如果 .ssh 目录权限不对,修复:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_rsa

用 -v 参数看详细认证过程

# -v 参数开启 verbose 模式,可以看到每一步在干嘛
ssh -v user@example.com

输出里找 Authentications that can continue:Permission denied 相关行,能帮你判断认证卡在哪一步。

# 更详细的 -vvv,适合深度排查
ssh -vvv user@example.com

指定密钥文件登录

# 明确指定用哪个私钥文件
ssh -i ~/.ssh/my_key user@example.com

如果密钥文件名不是默认的 id_rsa,就必须用 -i 指定,否则 SSH 会用默认密钥然后得到 Permission denied。

方向四:防火墙 — 被墙了?

网络层通了,端口也对了,但还是连不上?大概率是防火墙在作怪。

本地防火墙检查

# Linux 查看防火墙规则(ufw)
sudo ufw status

# 或 iptables
sudo iptables -L -n | grep 22

服务器防火墙(云服务器最常踩坑)

如果用的是阿里云、腾讯云、AWS 等云服务,安全组规则是最容易被忽略的地方。本地防火墙关了都没用,云厂商控制台的安全组没开 TCP 22 入站,一样 Connection refused。

# 在服务器上直接查 iptables INPUT 链
sudo iptables -L INPUT -n | grep -E "22|ssh"
云服务器排查顺序:
1. 云厂商控制台 → 安全组 → 确认入站规则有 TCP 22(或你自定义的端口)
2. 服务器内部防火墙:sudo ufw allow 22/tcp
3. 再测试连接

firewalld 用户

# 检查 firewalld 是否在运行
sudo firewall-cmd --state
# 开放 SSH 端口
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

方向五:known_hosts — 被中间人拦截了?

Host key verification failed

这是 SSH 在告诉你:服务器的身份变了。可能是服务器重装了系统、换了 IP,或者……真的有人在搞中间人攻击。

先确认是真的服务器还是假服务器

# 查看服务器的 fingerprint
ssh-keyscan example.com | head -1

联系服务器管理员,确认当前正确的 fingerprint。如果 fingerprint 对上了,说明之前记录的信息过期了,清掉旧的就行。

清除旧的 known_hosts 记录

# 清除单台服务器的记录
ssh-keygen -R example.com

# 清除指定 IP 的记录
ssh-keygen -R 192.168.1.100

# 清除特定主机的特定 IP:port 组合
ssh-keygen -R [example.com]:2222

清除后再连接,SSH 会让你确认并写入新的 fingerprint:

# 首次连接会看到类似提示,输入 yes 即可
Are you sure you want to continue connecting (yes/no/[fingerprint])?
安全提醒:如果服务器没换过,但你突然收到 "Host key changed" 警告,不要直接 yes。先联系服务器管理员确认。这可能是真实的中间人攻击。

已知 hosts 的指纹文件在哪?

# 用户级 known_hosts
cat ~/.ssh/known_hosts

# 系统级 known_hosts
cat /etc/ssh/ssh_known_hosts

进阶:SSH Config 这么配才靠谱

每次输长长一串命令很烦?Host 别名、默认用户、端口、密钥文件,都可以写进 ~/.ssh/config,一劳永逸。

# 编辑 SSH 配置文件
nano ~/.ssh/config

配置示例:

# 生产服务器
Host prod
    HostName     123.45.67.89
    User         deploy
    Port         2222
    IdentityFile ~/.ssh/id_rsa_prod
    ServerAliveInterval 60
    ServerAliveCountMax 3

# 开发服务器
Host dev
    HostName     dev.example.com
    User         developer
    Port         22
    IdentityFile ~/.ssh/id_rsa

# GitHub(注意这里用 git@github.com 作为 HostName)
Host github.com
    HostName     github.com
    User         git
    IdentityFile ~/.ssh/github_ed25519
配置好之后,连接只需要输入 ssh prodssh dev,所有参数自动生效,不用记 IP、端口、密钥路径。

配置文件权限也要注意

# config 文件权限必须是 600
chmod 600 ~/.ssh/config

用 ProxyJump 穿透跳板机

# 假设要访问内网机器,但要先登跳板机
Host internal
    HostName     192.168.1.100
    User         developer
    ProxyJump    bastion@example.com

ssh internal 时,SSH 会自动先登跳板机,再跳到内网机器,全程透明。

总结:SSH 连接失败排查 checklist

快速复盘,6 步锁定问题:

  1. ping 通不通? → 不通先查网络层
  2. 端口对不对? → 默认 22,改过用 -p 指定
  3. 密钥权限 600?chmod 600 ~/.ssh/id_rsa
  4. authorized_keys 有你的公钥? → 服务器上 ~/.ssh/ 目录检查
  5. 防火墙和安全组开了吗? → 云服务器安全组最容易被忽略
  6. known_hosts 过期了?ssh-keygen -R example.com 清除旧记录

这六步走完,99% 的 SSH 连接问题都能定位。如果还是不行,把 ssh -vvv 的完整输出发给身边有经验的朋友,或者搜索引擎搜报错关键字,通常很快能找到答案。

不想折腾命令行?试试在线 SSH 工具

CloverTools 提供可视化 SSH 连接工具,支持密钥上传、端口配置、known_hosts 管理,打开浏览器就能连服务器。

立即使用 SSH 连接工具

本文由 CloverTools 整理编写

💡 遇到同类问题?用工具快速解决

试试这些配套工具,无需注册,打开即用

浏览所有工具

常见问题

Q: 如何使用 ssh连接失败排查指南 相关工具?
A: 这类工具一般有明确的输入框和输出框,按提示输入内容,点击对应按钮即可得到结果。建议先用简单示例测试功能是否正常,再处理实际数据。
Q: ssh连接失败排查指南 适合在什么场景使用?
A: 根据具体工具类型决定。格式转换工具适合处理第三方数据,编码工具适合加密传输,压缩工具适合文件上传前处理。多积累工具使用经验,遇到问题时能快速判断用哪个工具解决。
Q: 有没有更好的替代工具?
A: 不同工具有不同侧重,重点是理解原理。可以同时安装多个类似工具,实际使用中对比效果,选择最顺手的一个。随着使用经验增加,你也能判断工具的好坏。