尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

报错排查 05|SSH 连不上怎么办?从网络层到认证层的 12 步分层排查法

报错排查 05|SSH 连不上怎么办?从网络层到认证层的 12 步分层排查法 我第一台云服务器的第一课就是 SSH 连不上。当时我的反应跟大多数人一样重启。重启完还是连不上然后开始在网上乱搜改sshd_config、重装 ssh、甚至重装了系统——折腾三个小时最后发现是防火墙把 22 端口关了。重启这个动作最坑的地方在于它会把现场擦掉。你之后再想查「刚才到底为什么连不上」日志已经翻篇了。这篇我按「分层」来讲。SSH 连不上只有四种可能按这四层一层层往下走最多十分钟能定位。〇、先花两分钟SSH 连接的四层结构把 SSH 想成打电话层打电话的对应出问题的表现1. 网络层号码拨得通吗Connection timed out2. 端口层对方有这条线吗Connection refused3. 服务层有人接吗连上就断、卡在登录前4. 认证层能确认身份吗Permission denied、Host key verification failed注意报错信息的区别——它其实在告诉你卡在第几层Connection timed out包发出去了没人应答→ 第 1 或第 2 层防火墙拦了、机器没开、IP 错了Connection refused有人应答但明确拒绝→ 机器活着端口上没有服务在听服务没起、端口改了能连上但登不进去 → 第 4 层认证。这一层区分能省掉一半时间refused是「服务的问题」timed out是「网络或被拦的问题」。一、第 13 步网络层先证明机器活着第 1 步ping 一下$ ping -c 3 192.168.1.50 3 packets transmitted, 3 received, 0% packet loss怎么读有回包说明机器活着、网络通。没回包别急着下结论——很多云服务器和防火墙默认丢弃 ICMPping 不通但 SSH 是好的。所以 ping 只当辅助证据。第 2 步确认 IP 和端口没记错这一步听着傻但真的有人包括我连了半天发现连的是另一个环境的机器。确认# 本机 IP在服务器上执行 $ ip -br addr ens33 UP 192.168.1.50/24第 3 步换一条路径试从另一台机器试或者用手机热点试。如果能从别的地方连上问题就在你这条网络路径上本地网络、公司出口、VPN 分流不在服务器。$ nc -vz 192.168.1.50 22 Connection to 192.168.1.50 22 port [tcp/ssh] succeeded!怎么读succeeded说明端口是开着的可以直接跳到第 9 步去查认证。Connection refused说明机器活着但没服务在听——直接看第 4 步。nc是 netcatUbuntu 上可能需要sudo apt install netcat-openbsd。不方便装的话第 5 步的ss命令也能起到类似作用。二、第 46 步端口层服务在不在第 4 步服务起了吗注意 Ubuntu 上它叫ssh不叫sshd$ systemctl status ssh ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled) Active: active (running) since Sat 2026-09-26 09:12:03 CST; 1 day 3h ago怎么读Active: active (running)才算正常。⚠️ 这一步有个大坑Ubuntu / Debian 系的服务名叫sshRHEL / CentOS 系叫sshd。在 Ubuntu 上敲systemctl status sshd会告诉你「找不到这个单元」很容易被误判成「服务没装」。更绕的是桌面版上你搜ssh也搜不到它——因为服务端压根没装能搜出来的全是别的东西$ systemctl list-unit-files | grep -iE ssh|sshd sssd-ssh.service indirect enabled sssd-ssh.socket enabled enabled ssh-access.target static -怎么读sssd-ssh是「SSSD企业账号认证服务的一个组件」ssh-access.target是个目标单元——三个都不是 SSH 服务端。搜不到ssh.service就是没装。服务没起就拉起来sudo systemctl start ssh sudo systemctl enable sshenable是设开机自启——服务「起过」和「会自动起」是两件事这个坑在Linux避坑 02里详细讲过。第 5 步服务端到底装了没有这是最容易被忽略的一种情况而且在 Ubuntu 桌面版上是默认状态。Ubuntu 桌面版默认不安装 OpenSSH 服务端只有客户端。也就是说你能从这台机器ssh去连别人客户端装了但别人连不进来——因为压根没有服务端。$ dpkg -l | grep -E openssh|ssh ii libssh2-1t64:amd64 1.11.1-1ubuntu0.26.04.4 amd64 SSH2 client-side library ii openssh-client 1:10.2p1-2ubuntu3.6 amd64 secure shell (SSH) client ​ $ ss -tlnp | grep :22 无输出怎么读这是我在自己那台 26.04.1 上跑的真实结果dpkg -l里只有openssh-client客户端没有openssh-server服务端→ 你能连出去别人连不进来ss -tlnp里没有任何:22→ 没有程序在监听 22 端口。两条合起来就是「服务端不存在」的铁证。顺便留意第一行那个libssh2-1t64——它是客户端用的库名字里有 ssh但不是服务端别被带跑。要装sudo apt install openssh-server第 6 步服务在听但只听本机有些配置尤其容器镜像、加固过的系统会把监听地址限制成127.0.0.1——只接受本机连接外面永远连不上。$ ss -tlnp | grep :22 LISTEN 0 128 127.0.0.1:22 0.0.0.0:* users:((sshd,pid812,fd3))怎么读关键看:22前面那一段地址。显示含义0.0.0.0:22所有网卡都听——外部可以连正确状态[::]:22同上走 IPv6127.0.0.1:22只听本机——外部连不上问题就在这对应的配置在/etc/ssh/sshd_config里的ListenAddress。对照一下就知道「地址」这一列有多关键——这是我机器上全部在监听的端口一个 22 都没有$ ss -tlnp LISTEN 0 4096 127.0.0.1:631 0.0.0.0:* ← 打印服务只听本机 LISTEN 0 50 0.0.0.0:445 0.0.0.0:* ← Samba所有网卡都听 LISTEN 0 50 0.0.0.0:139 0.0.0.0:* ← Samba同上 LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* ← systemd-resolved只听本机怎么读0.0.0.0:445 外面连得进来127.0.0.1:631 只有本机能连。同样是「在监听」地址不同含义完全相反——这就是第 6 步要教你的判断。三、第 78 步防火墙最常见的元凶第 7 步本机防火墙$ sudo ufw status 状态不活动怎么读不活动 ufw 没在拦此时去看看 nftables / iptables 有没有别的规则活动就要看规则里有没有放行 22⚠️ 这里有个特别容易误判的地方我在自己机器上就撞到了$ systemctl is-active ufw active $ systemctl show -p ActiveState -p SubState -p Type -p RemainAfterExit ufw.service ActiveStateactive SubStateexited Typeoneshot RemainAfterExityes看到active就以为防火墙开着不是。把后一条命令的四行连起来读就懂了Typeoneshot跑一遍就退RemainAfterExityes跑完别退停在 active 上SubStateexited进程其实已经结束了——这个active只表示「启动脚本执行过」跟「防火墙有没有启用」是两件事。那真正的开关在哪在这个文件里$ cat /etc/ufw/ufw.conf ENABLEDno LOGLEVELlowENABLEDno—— 这才是权威答案和sudo ufw status报的「不活动」完全一致。判断防火墙永远以sudo ufw status的输出为准别看systemctl is-active。顺便说下verbose版长什么样——没启用时它只回一句我机器上就是这样$ sudo ufw status verbose 状态不活动启用之后才会列出规则表格式如下这台机器上没启用所以下面是格式参考状态活动 日志记录on (low) 默认deny (incoming), allow (outgoing), disabled (routed) 新配置文件skip To Action From -- ------ ---- 22/tcp ALLOW AnywhereRHEL 系用firewall-cmd --list-all看ports或services里有没有ssh。⚠️第一句提醒如果你正通过 SSH 连着服务器在敲sudo ufw enable之前先确认 22 端口已经放行sudo ufw allow 22/tcp # 先放行 sudo ufw enable # 再启用顺序反了你会当场把自己锁在门外——这个教训值得单独记一条。第 8 步云安全组 / 机房设备如果你用的是云服务器安全组是最常见的拦路虎而且在服务器里怎么查都查不出来——因为规则在云平台的控制台上。排查方式打开云控制台看这台实例绑定的安全组入方向规则里有没有放行 22很多默认策略只放 80/443或者只允许特定来源 IP。不要把「服务器内部一切正常」等同于「网络是通的」——云安全组、机房 ACL、公司出口设备都在你看不见的地方。四、第 912 步认证层能连上但登不进去到这里连接已经建立问题在身份认证。第 9 步看服务端的拒绝日志$ sudo journalctl -u ssh -n 30 Sep 27 11:02:31 host sshd[2311]: Failed password for alice from 192.168.1.9 port 51234 ssh2 Sep 27 11:02:33 host sshd[2311]: Connection closed by authenticating user alice 192.168.1.9 port 51234 [preauth]怎么读Failed password 密码不对Connection closed by authenticating user ... [preauth] 认证阶段被断开多半是密钥或配置问题如果什么都没有说明请求根本没到达服务回到第 7、8 步。日志位置Ubuntu 在 journald上面这条命令也能在/var/log/auth.log里找到RHEL 系在/var/log/secure。第 10 步密钥登录失败九成是权限问题SSH 对密钥文件的权限极其挑剔——只要它觉得别人有可能读到你的私钥就直接拒绝使用。服务端的检查清单下面是我机器上的真实状态$ ls -ld ~/.ssh ~/.ssh/authorized_keys drwx------ 2 rainbow rainbow 4096 Sep 16 15:24 /home/rainbow/.ssh -rw------- 1 rainbow rainbow 0 Sep 16 15:24 /home/rainbow/.ssh/authorized_keys怎么读drwx------700和-rw-------600是对的权限没问题。但注意那个0——文件大小是 0里面一个公钥都没写。这种「文件在、内容空」的状态最容易被忽略登录当然失败而日志里只会干巴巴地说一句「认证失败」。怎么读.ssh目录必须是700drwx------authorized_keys必须是600-rw-------而且属主必须是你自己。多一个组读权限SSH 都可能不认。一条命令修好chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chown -R $USER:$USER ~/.ssh还有一条隐蔽的家目录本身不能是 777。/home/alice权限过于宽松时SSH 同样会拒绝——因为它认为别人可以替换你的.ssh。第 11 步服务端配置在故意拦你/etc/ssh/sshd_config里几个常见开关配置项效果PermitRootLogin noroot 不允许直接登录默认值很多人不知道PasswordAuthentication no禁用密码只认密钥AllowUsers alice白名单只有列出的用户能登DenyUsers黑名单MaxAuthTries 3认证失败 3 次就断开Port 2222改了端口客户端要用-p 2222改完配置一定要做两件事sudo sshd -t # 先检查语法错了它会告诉你哪一行 sudo systemctl reload ssh # 再让服务重读配置sshd -t这步千万别省。配置写错了直接 reload 服务结果服务起不来——而你正通过 SSH 连着下一次连接就再也进不去了。第 12 步主机密钥变了Host key verification failedWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!这不是故障是安全机制在工作你以前连过这台机器它当时的「指纹」记录在~/.ssh/known_hosts里现在指纹变了客户端就报警——因为它无法区分「服务器重装了」和「有人在中间冒充服务器」。服务器重装过、或者你换了台机器复用同一个 IP都会触发这个警告。确认是自己的机器变了清掉旧记录即可ssh-keygen -R 192.168.1.50反过来说如果你没重装过系统却看到这个警告别急着清——先确认机器是不是被人动过。顺便提一个 2026 年的新情况新版 OpenSSH 已经不再支持 DSA 密钥我机器上是OpenSSH_10.2p1所以那些老教程里ssh-keygen -t dsa的做法现在会直接被拒。现在该用的是ed25519ssh-keygen -t ed25519 -C 备注信息五、客户端自查三条命令看清我这里发生了什么如果服务器那边一切正常用客户端的详细模式看$ ssh -v alice192.168.1.50 debug1: Connecting to 192.168.1.50 [192.168.1.50] port 22. debug1: Connection established. debug1: Authentications that can continue: publickey,password怎么读-v会把每一步都打出来。卡在Connecting to ...不动 → 网络层第 1~3 步Connection established之后卡住 → 服务层Authentications that can continue:这行很有用——它列出服务端允许的认证方式。如果里面有publickey但你只有密码就知道该配密钥了。嫌不够详细可以叠-vvv。速查表文末收藏版先分清报错 → timed out网络/防火墙 refused端口没服务 机器活着吗 → ping -c 3 IP 端口通吗 → nc -vz IP 22 服务状态Ubuntu → systemctl status ssh ← 服务名是 ssh不是 sshd 服务状态RHEL 系 → systemctl status sshd 服务端装了吗 → dpkg -l | grep -E openssh|ssh 桌面版默认只有 -client 别用这个判断防火墙 → systemctl is-active ufw ← active 不代表防火墙开着它是 oneshot 防火墙真正的开关 → /etc/ufw/ufw.conf 里的 ENABLED 谁在听 22 → ss -tlnp | grep :22 看是 0.0.0.0 还是 127.0.0.1 本机防火墙 → sudo ufw status verbose RHELfirewall-cmd --list-all 启用防火墙前先放行 → sudo ufw allow 22/tcp sudo ufw enable 云服务器 → 控制台看安全组入方向规则 服务端拒绝日志 → sudo journalctl -u ssh -n 30 密钥权限 → chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys 配置语法检查 → sudo sshd -t 重读配置不断连接 → sudo systemctl reload ssh 主机密钥变了 → ssh-keygen -R IP 客户端详细排查 → ssh -v 用户名IP 生成新密钥用这个 → ssh-keygen -t ed25519 -C 备注
返回列表