ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SSH连不上Ubuntu虚拟机?从网络到认证的全流程排查指南

SSH连不上Ubuntu虚拟机?从网络到认证的全流程排查指南 先别急着去看网卡、改防火墙、重装系统。SSH连不上Ubuntu虚拟机这个问题我前前后后排查过不下几十次有帮同事救急的也有自己半夜折腾的。其实90%的情况都逃不出几个固定套路只要你愿意静下心来看一眼报错信息很多问题在两分钟内就能定位。这篇文章我就把你可能遇到的所有坑从网络层到服务层到认证层一条条拆开讲清楚。1. 先看报错文字三类典型失败信息分别指向哪个环节这是最容易被忽略、但价值最高的一步。很多人的做法是SSH连不上了赶紧打开VMware把虚拟机重启一遍结果没用再检查一下网卡设置还是没用最后甚至把Ubuntu重装了问题依旧。核心原因就是你根本没有读SSH告诉你什么。SSH是个很老实的工具它把所有失败原因都分成不同层次写在报错里。不同报错文字代表完全不同的故障区间排查方向也完全不一样。报错关键字故障层次优先排查方向常见原因Connection refused服务端应用层SSH服务没开、22端口没监听openssh-server没装、sshd没启动、防火墙REJECTConnection timed out网络层数据包根本没到对方网卡没配对、IP网段不同、防火墙DROP、VMware网络模式错误No route to host网络层路由不通网关配置错误、虚拟网络编辑器配置损坏Permission denied (publickey,password)认证层账号密码或密钥不对密码错误、sshd_config禁止密码登录、root被限制REMOTE HOST IDENTIFICATION HAS CHANGED认证层known_hosts缓存冲突系统重装、快照回滚、IP被别的机器占用连接后立即断开 / 卡在登录后没反应会话层shell初始化或服务配置问题登录shell异常、DNS反解超时、资源耗尽记住这个对应关系你就有了定位问题的地图。1.1 Connection refused服务端根本没开门字面意思就是连接被拒绝了这说明你的网络是通的请求顺利到达了对方的机器但对方机器上没有程序在22端口监听。打个比方就是你按了门铃屋里有人也知道你来了但就是不开门。这个报错出现时你要检查的是虚拟机里面SSH服务是否安装、是否运行。这是新手最常见的翻车点因为Ubuntu桌面版默认不会安装openssh-server你装完系统直接就想SSH连上去那肯定是不行的。1.2 Connection timed out你根本就没找到门Connection timed out意味着你的数据包发出去之后石沉大海没有任何回应。可能是虚拟机没开机、网络没连通、IP地址变了也有可能是中间的防火墙悄悄把你的包丢了。这里有个重要的概念区分REJECT和DROP。如果防火墙规则是REJECT客户端会立刻收到Connection refused如果是DROP客户端就只能傻等直到超时报Connection timed out。所以看到timeout第一反应应该是去查网络连通性而不是去看SSH服务。1.3 连接串起来了但卡在认证环节还有一类报错不是连不上而是连上了但进不去。比如Permission denied。这说明网络通了、服务也正常跑着但账号密码或者密钥验证没过。这种问题排查思路完全不同后面第5章专门展开。看到这里你应该明白了SSH的报错信息不是乱写的它就是一份故障分层地图。带着这张地图去排查你永远不会做无用功。2. 网络层排查VMware NAT、桥接、仅主机三种模式下的连通性定位网络层问题占了SSH连接失败的很大比例尤其是VMware虚拟机网络模式搞错了或者虚拟网络编辑器没配好能整出各种奇怪的现象。2.1 VMware三种网络模式的选型逻辑VMware给虚拟机提供了三种网络模式很多新手不理解它们之间的区别于是就在默认选项里瞎选最后网络完全不通。NAT模式默认虚拟机在VMware创建的私有网段内通常是192.168.xx.0/24通过宿主机的网络地址转换访问外网。宿主机可以看到这个私有网段虚拟机也能访问宿主机。这是最常用的模式因为不需要宿主机和虚拟机在同一网段也不会占用局域网IP资源。用NAT模式时有几个IP地址你必须知道虚拟机自己的IP一般在192.168.xx.128~254之间DHCP分配网关通常是192.168.xx.2VMware虚拟路由器宿主机侧对应网卡VMnet8通常是192.168.xx.1桥接模式虚拟机就像是局域网里的一台独立电脑直接使用和宿主机同一网段的IP。适用于需要局域网内其他真实设备直接访问虚拟机的场景。缺点是会占用真实IP且如果路由器开启了AP隔离虚拟机之间可能无法互通。仅主机模式虚拟机只能和宿主机通信不能访问外网。适合完全隔离的测试环境但如果你想在虚拟机里安装软件包这模式就行不通了。如果你只是做开发、跑服务NAT模式是最省心的。但NAT模式有个容易踩的坑VMware在分配网段时不同版本默认网段不一样有的版本是192.168.128.0/24有的是192.168.188.0/24还有的是192.168.217.0/24。你必须在VMware的虚拟网络编辑器里确认实际网段不要凭空猜测。2.2 ping不通时按这三步顺序定位不要一上来就凭感觉乱试按照下面的顺序一步步排查第一步在虚拟机里确认自己的IP地址。打开终端执行ip addr查看网卡是否有IP。如果网卡没有IP说明DHCP没生效或者网卡没启动。很多Ubuntu服务器版默认没有启用DHCP需要手动编辑netplan配置。这一步能避免你拿着错误的IP在宿主机上猛敲命令。第二步在宿主机上ping虚拟机的IP。如果通了说明宿主机到虚拟机的物理链路是通的如果不通进第三步。这里注意Windows防火墙可能会拦截ICMP请求导致ping不通但SSH却可以连接。所以ping不通不代表SSH就一定连不上反过来也一样。第三步在虚拟机里ping网关。比如ping 192.168.188.2。如果网关ping不通说明虚拟机的路由有问题或者VMware的NAT服务没有正常运行。去Windows的服务管理器里看看VMware NAT Service和VMware DHCP Service这两个服务是否启动这是很多莫名奇妙网络不通的元凶。2.3 一个容易忽略的物理前提宿主机的VMnet网卡在NAT模式下宿主机通过VMnet8这张虚拟网卡与虚拟机通信。如果这张网卡被禁用了那就算虚拟机IP再正确也没用。排查方法在Windows的命令行里执行ipconfig看看有没有VMnet8的条目。如果没有或者显示的是媒体已断开连接去控制面板 网络和 Internet 网络连接里找到VMware Network Adapter VMnet8启用它并检查它的IP地址是否和VMware虚拟网络编辑器里配置的一致。顺便说一个跟网络层无关但容易碰到的现象有时候SSH连接会卡在输入密码前的那个阶段等很久才提示输入密码或者连接成功后敲命令明显有延迟感。这个大概率是SSH服务端在做DNS反解也就是把连接方的IP解析成主机名在局域网环境下这个解析会超时。解决方法是改一下sshd_config里的UseDNS no后面第5章会讲。3. 服务端检查openssh-server 装没装、跑没跑、端口有没有在听网络通了那就该把目光转向虚拟机内部了。SSH服务这一层的问题是除了网络之外的第二大翻车点。3.1 默认不安装的openssh-server头号翻车点Ubuntu桌面版默认是不安装SSH服务端的服务器版在安装时如果没勾选也会缺。很多人用虚拟机装完Ubuntu桌面版后第一件事就是想用SSH连上去结果自然是Connection refused。检查命令dpkg -l | grep openssh-server如果没有任何输出或者只看到ii状态但版本号很旧那就直接安装sudo apt update sudo apt install openssh-server安装完成后SSH服务会自动启动。这里有个小细节在Ubuntu上服务名是ssh而不是sshd。你执行systemctl status sshd会提示找不到服务但执行systemctl status ssh就是正常的。这个命名细节坑了不少从CentOS转过来的老手。3.2 端口到底有没有在监听ss vs netstat确认SSH服务在运行后还要确认22端口真的在监听。有些情况下服务显示active但端口没开比如配置文件里改了Port但服务没重启成功或者端口被别的进程占用。sudo ss -tlnp | grep :22看到类似LISTEN 0 128 0.0.0.0:22的输出才是正常的。注意这里必须是0.0.0.0:22如果看到的是127.0.0.1:22说明sshd只开启了本地回环监听外人根本连不进来。这种情况通常是/etc/ssh/sshd_config里的ListenAddress配置错了。如果端口没在监听看一下服务的运行日志sudo journalctl -u ssh --no-pager -n 50日志会告诉你服务为什么没起来可能是配置文件语法错误、端口被占用或者其他依赖问题。3.3 配置改错导致的假连不上SSH连接失败还有一种不太常见但很迷惑人的情况配置文件的Port被改成了非22端口。你还在傻傻地敲ssh userip对方却在9527端口等你。检查/etc/ssh/sshd_config看看有没有非注释状态的Port配置。注意这个文件的注释默认很多不要被带偏。如果你确实改了端口连接时就要用ssh -p 9527 userip。另一个高频坑是PermitRootLogin。如果你试图用root账号登录而配置是PermitRootLogin prohibit-passwordUbuntu的默认值密码登录会被拒绝。你需要用一个普通用户登录然后su -切到root或者把配置改成yes后重启服务。4. 防火墙与安全策略ufw、iptables、fail2ban 都在拦什么网络通了、服务也开了但连接还是失败那就要看防火墙了。这个东西平时不吭声关键时刻能让你怀疑人生。4.1 ufw没放行22端口的问题Ubuntu自带的防火墙是ufw。很多教程会让你sudo ufw enable开启防火墙但没告诉你要提前放行SSH端口。结果防火墙一开SSH连接立刻断了然后卡在虚拟机面前手足无措。查看防火墙状态sudo ufw status如果显示Status: active看看输出里有没有22/tcp或者OpenSSH的ALLOW规则。没有就放行sudo ufw allow 22/tcp # 或者 sudo ufw allow OpenSSH这里有个细节值得说一下ufw的默认策略是拒绝所有入站连接所以如果你开了ufw却没放行22端口从客户端看可能是Connection refused如果ufw用了REJECT策略也可能是timeout如果DROP了。不同Ubuntu版本策略略有差异保险起见两个方向都检查一遍。4.2 iptables的隐藏规则ufw只是包在iptables外面的一层壳实际生效的是iptables规则。有时候ufw显示没启动但iptables里却有历史遗留的规则在拦着。直接查看当前的iptables规则sudo iptables -L -n --line-numbers重点关注INPUT链。如果看到有DROP或REJECT的规则在22端口之前的行号位置那就是它在捣乱。清理方法sudo iptables -D INPUT 行号注意iptables规则是即时生效且不持久的reboot之后规则会清空。如果你需要永久保存规则要安装iptables-persistent并把当前规则导出。4.3 fail2ban你之前可能把自己给ban了这个问题非常隐蔽。如果你在虚拟机上装过fail2ban而且此前有过几次SSH密码输入错误它会把你的IP加入黑名单。被ban之后的症状很迷惑——有时候是连接超时有时候是连接被拒绝而且大概率你在虚拟机的终端上检查SSH服务一切正常。查看是否被bansudo fail2ban-client status sshd输出里会有Currently banned列表。如果看到你的宿主机IP在里面执行sudo fail2ban-client unban 你的IP说实话fail2ban在局域网里有点用但不多。如果你只是自己开发用我建议干脆别装它省下的安全成本远不及它给你添的堵。5. 认证卡点密钥权限、known_hosts 和 sshd_config 的隐藏限制前面的坑都排完了SSH也连上了但卡在输密码或者输完密码进不去这时候问题出在认证环节。这条路上的坑更细碎需要耐心。5.1 Permission denied (publickey,password) 的逐项拆解这个报错说明SSH服务端拒绝了你的凭据。可能是密码真的错了也可能是服务端根本不接受密码登录。先排除最普通的密码错误。注意Linux终端输入密码时不显示任何字符很多人在虚拟机里输错了都不知道。建议在虚拟机本机的终端里先确认你的密码能登录省的做无用功。如果密码没问题查看/etc/ssh/sshd_config里这两个关键配置PasswordAuthentication yes PermitRootLogin prohibit-passwordPasswordAuthentication no意味着密码登录被禁用只允许密钥登录。很多安全教程会让你关掉密码登录但没提醒你用虚拟机的时候别关。PermitRootLogin prohibit-password意味着root账号不能直接用密码登录只能密钥登录。很多人在这一步卡了很久因为用root连不上就以为系统有问题其实只是策略限制。改完配置记得重启服务sudo systemctl restart ssh5.2 密钥登录时的权限地狱密钥认证是另一个高频出问题的地方而且权限问题占大头。SSH对密钥相关文件的权限要求非常严格权限过宽直接拒绝加载。标准权限应该是chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_rsa # 私钥 chmod 644 ~/.ssh/id_rsa.pub # 公钥如果你把authorized_keys设成644或者把~/.ssh设成755SSH服务会直接无视这个文件然后报Permission denied你还一脸懵。还有一个小坑把公钥写入authorized_keys时一定要写成一行完整的ssh-rsa AAAA...格式不要手贱换行。公钥中间任何换行都会导致认证失败。5.3 REMOTE HOST IDENTIFICATION HAS CHANGEDknown_hosts冲突这个报错遇到过的人一定印象深刻它整段红字还加粗告诉你远程主机标识已更改看着就很吓人。它出现的原因是SSH客户端会在~/.ssh/known_hosts文件里记录每个IP对应的主机指纹host key。如果虚拟机系统重装了、VMware快照回滚了、或者局域网里某个IP被另一台机器占用了客户端发现指纹对不上就会拒绝连接。解决办法很简单删掉那个IP的旧指纹记录ssh-keygen -R 192.168.188.128然后重新连接输入yes确认新指纹即可。注意如果你用VSCode远程开发插件VSCode有自己独立的known_hosts管理方式但报错逻辑和命令行SSH是一致的。5.4 登录后立即断开或卡住的隐藏原因有一种情况是SSH能连上密码也正确但登录后立即断开或者卡在某个界面半天没反应。除了最明显的/etc/ssh/sshd_config里UseDNS no要加上、GSSAPIAuthentication no建议加上之外还要检查用户的登录shell。如果用户shell被改成了/usr/sbin/nologin或/bin/falseSSH登录成功后会在启动shell这一步被拒绝表现为连接已关闭或直接闪退。查看用户shellchsh -l # 列出所有合法shell cat /etc/passwd | grep 用户名如果/etc/passwd里对应行末尾是/usr/sbin/nologin那就改回/bin/bashsudo usermod -s /bin/bash 用户名6. VMware特有的冷门坑与一条龙排查命令清单最后这部分讲讲VMware这个特定环境下的坑顺便给一份可以直接照做的完整排查流程。6.1 快照回滚和虚拟机克隆后的连锁反应这个坑非常隐蔽我在帮人排查时遇到过两次。如果你给虚拟机做过快照然后在某个时间点回滚了你会遇到两个问题一是MAC地址变了。回滚后的网卡MAC和客户端known_hosts里记录的指纹对应不上触发REMOTE HOST IDENTIFICATION HAS CHANGED报错。用上面说的ssh-keygen -R即可解决。二是Ubuntu的网卡名称变了。Ubuntu用netplan管理网络配置文件名一般是/etc/netplan/01-network-manager-all.yaml或类似的名字。如果你在配置里写了固定的网卡名比如ens33快照回滚后网卡变成了ens38那虚拟机启动后这个网卡配置就不会被应用导致没有IP或者IP不正确。查看当前网卡真实名称ip addr然后修改netplan配置把网卡名改对或者干脆用通配符match:匹配MAC地址。改完执行sudo netplan apply6.2 VMware的后台服务也是隐形炸弹VMware Desktop安装在Windows上的时候会注册一堆Windows服务。跟网络相关的主要是VMware NAT ServiceVMware DHCP ServiceVMware USB Arbitration Service这个跟SSH关系不大如果NAT服务没启动虚拟机的网络会变得极其诡异比如虚拟机自己显示有IP但宿主机ping不通虚拟机上不了网。很多人这时候会去折腾虚拟机的网络配置其实看一眼Windows的服务列表就能解决问题。在Windows上用WinR输入services.msc打开服务管理器找到这三个服务确认是正在运行。如果停了右键启动并设置为自动启动。6.3 从零开始的完整排查命令清单直接抄作业为了让这套经验可以直接落地我把排查流程整理成一份可以按顺序执行的清单。建议在遇到SSH连接失败时从头到尾走一遍十有八九能把问题揪出来。宿主机侧操作# 1. 确认VMnet8虚拟网卡状态 ipconfig /all # 2. 确认VMware NAT和DHCP服务运行中 services.msc # 3. 试着ping一下虚拟机IP ping 192.168.188.128虚拟机侧操作# 4. 确认网卡有IP且网关正确 ip addr ip route # 5. 检查SSH服务安装状态和运行状态 dpkg -l | grep openssh-server systemctl status ssh # 6. 检查22端口监听情况 sudo ss -tlnp | grep :22 # 7. 检查防火墙状态 sudo ufw status sudo iptables -L -n | grep :22 # 8. 查看SSH服务日志定位原因 sudo journalctl -u ssh --no-pager -n 50 tail -30 /var/log/auth.log客户端侧操作# 9. 用详细日志模式连接观察卡在哪一步 ssh -vvv user192.168.188.128 # 10. 遇到host key冲突时清理指纹 ssh-keygen -R 192.168.188.128整套流程走下来常规的SSH连接失败问题基本都能定位。我自己的体会是这个问题的难点从来不是单点原因有多复杂而是你愿不愿意按照从网络层到服务层再到认证层的顺序逐步排查。很多人栽跟头都是因为跳过了某一步直接凭感觉下结论结果绕了一大圈才发现是最初级的错误。按这份清单走你就能少走很多弯路。
返回列表