1. 连接前的方案拆解:为什么用XShell连虚拟机
1.1 解决什么问题:终端远程管理的核心场景
先说说这个事儿是干嘛的。XShell是一款Windows平台上的SSH客户端,它的核心工作就是帮你在本机开一个终端窗口,远程登录到Linux服务器或者虚拟机里的Linux系统,然后直接在窗口里敲命令。对大部分开发者和运维来说,这个动作几乎是每天都要做的。你自己装了一台VMware虚拟机,里面跑着Ubuntu或者CentOS,平时想装个软件、改个配置、重启个服务,如果每次都跑到虚拟机界面里操作,那个体验真的是又慢又别扭——窗口切来切去,复制宿主机的内容进虚拟机还要装VMware Tools,粘贴还经常失灵。用XShell连过去之后,一切都变成了纯命令行操作,复制、粘贴、脚本执行都干脆利落,这才是干活的正常姿势。
这篇文章适合谁?刚装了VMware虚拟机、想在Windows下舒服地操作Linux的新手,以及已经在用虚拟机但一直被“怎么连都连不上”困扰的同学,还有想顺带把远程开发环境打通的老手。我会把从虚拟机侧的环境准备、网络配置,到XShell侧的会话建立、乱码处理,再到失败场景的排查思路,完整地过一遍,每个步骤都给出可复现的命令和参数,不绕弯子。
1.2 工具选型:XShell和它的替代方案怎么选
目前主流的连接方案其实不止XShell一种,但我个人最常用的还是它。简单对比一下,方便你选择:
| 工具 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| XShell | 轻量、启动快、会话管理好用、免费版够用 | 只在Windows下体验好,免费版标签页有限制 | Windows连Linux、日常运维 |
| VS Code Remote-SSH | 编辑器集成,能直接改文件、跑调试 | 重,吃内存,启动慢 | 开发为主、需要改代码的场景 |
| Tabby | 开源跨平台,颜值高 | 偶尔有卡顿,资源占用略高 | 跨平台统一终端 |
| 系统自带终端 | 零成本 | 无会话管理,无配色,操作繁琐 | 临时用一次 |
| VNC/Web控制台 | 能看到图形界面 | 卡顿、吃资源、不适合命令操作 | 图形安装、桌面环境 |
为什么多数人最终还是会回到XShell?核心竞争力是会话管理。你可以把每一台机器存成一个会话,双击就连,每个会话可以单独保存字体、编码、配色,还能在会话之间快速切换。这种体验,在频繁切换开发机、测试机、虚拟机的时候,是其他工具很难比的。而且个人版是免费的,日常完全够用,官方直接就能下载,我待会儿会说下载和安装的注意事项。
1.3 一条完整的连接链路长什么样
很多人连不上虚拟机,是因为脑子里没有把这条链路拆清楚。完整链路是这样的:
宿主机上的XShell → 宿主机的虚拟网卡 → VMware的虚拟交换机 → 虚拟机内的网卡 → 虚拟机内的SSH服务(端口22)→ 返回一个命令行终端给你
拆成三段看就明白问题出在哪了。第一段是“宿主机能不能到虚拟机”,这由虚拟机的网络模式决定,NAT、桥接、仅主机模式走的路不一样。第二段是“虚拟机开没开SSH服务”,很多精简版Linux默认根本没装openssh-server,你连100次也是拒绝。第三段是“XShell这头填的IP对不对”、用户名密码对不对。后面我会按照这三段来排查,效率非常高。你现在就可以记住这个思路,剩下的就是照着做。
2. 虚拟机侧准备:SSH服务与网络配置
2.1 安装Linux系统时的几个易错点
我假设你已经有一台VMware虚拟机,里面装了Linux。如果没有,装的时候有几个地方要注意,踩坑概率极高。
第一,虚拟机操作系统的选择。镜像建议直接下官方版,Ubuntu Server、CentOS Stream、Debian都可以,别因为图省事下那种“精简优化版”,真的出过太多莫名其妙的问题,xy问题非常难排查。第二,安装过程中到软件选择那一步,如果用的Ubuntu Server版,默认不会装图形界面,这反而是好事,因为你要的是终端。第三,也是最容易被忽视的一点,安装向导里会让设置用户名和密码,这个密码一定要记好,后面SSH登录就是用它。第四,网络配置建议先选“使用DHCP自动获取”,把系统装好,后面再改成静态IP。
关于VMware版本的选择,我用的是VMware Workstation Pro,免费版对个人使用已经开放了,直接在官网注册个账号就能拿到密钥,不用再到处找注册机。安装路径和虚拟机存放路径尽量不要放在C盘,后面虚拟磁盘会越来越大,C盘满了虚拟机很容易各种报错。
2.2 开启SSH服务:两条命令解决90%的问题
装好系统第一件事,就是确认SSH服务有没有起来。很多新手折腾半天连不上,结果虚拟机里压根没有SSHD。你在虚拟机里打开终端,先用一条命令看看SSH服务监听状态:
systemctl status sshd # 或者Ubuntu上可能是 systemctl status ssh如果没有这个服务,会有明确报错提示找不到。这时分系统安装:
# Debian/Ubuntu系列 sudo apt update sudo apt install openssh-server -y sudo systemctl enable --now ssh # RHEL/CentOS系列 sudo yum install openssh-server -y sudo systemctl enable --now sshd装完后再次执行systemctl status ssh,看到绿色的active(running),说明服务已经正常了。这里有个很容易忽略的细节,有些云镜像甚至精简版系统会装sshd但默认不让root通过密码登录,配置文件/etc/ssh/sshd_config里有一行PermitRootLogin,默认是prohibit-password(只允许密钥登录),如果你要用root直接连,需要改成yes然后重启服务。这个我后面在排错章节还会细讲。先记住一件事:SSH服务没启动,外面怎么连都是白搭。
2.3 网络配置:静态IP、网卡模式和防火墙
接下来是重头戏,网络部分。连不上的原因,十有八九出在这里。
先看VMware的三种网络模式:
| 模式 | 原理 | 能不能被宿主机直达 | 虚拟机能不能上网 | 推荐度 |
|---|---|---|---|---|
| 桥接模式 | 虚拟机直接占用局域网IP,和宿主机平级 | 能,前提是IP在同一网段 | 能 | 最推荐,最直观 |
| NAT模式 | 虚拟机走宿主机共享IP出网,虚拟机和宿主机有独立网段 | 能,但IP在VMnet8网段 | 能 | 次选,够用 |
| 仅主机模式 | 虚拟机只和宿主机通信,不访问外网 | 能,IP在VMnet1网段 | 不能 | 调试用 |
我个人的建议:在家用路由器环境下直接选桥接模式,因为虚拟机和宿主机就在同一个局域网,IP分配最直观,而且虚拟机和外部设备(比如手机、其他电脑)也能互通。如果你是在公司内网或者网络环境比较复杂,用NAT模式就行,稳定性更好,不太依赖外部网络策略。
然后是给虚拟机设静态IP。为什么要静态IP?因为DHCP分到的地址是动态的,可能重启后IP就变了。你XShell里存的会话是全IP的,IP一换就会连接失败。所以装完系统、确认SSH开启后,第一件事就是固定IP。
以Ubuntu 22.04以上版本为例,用Netplan配置文件:
sudo vi /etc/netplan/00-installer-config.yaml内容改成这样(以NAT模式/VMnet8网段为例,VMware NAT默认网段一般是192.168.x.0,具体在虚拟机里执行ip addr就能看到实际网段):
network: ethernets: ens33: dhcp4: false addresses: [192.168.80.10/24] routes: - to: default via: 192.168.80.2 nameservers: addresses: [192.168.80.2, 8.8.8.8] version: 2然后应用配置:
sudo netplan apply注意这里route的via填的是VMware NAT网关的IP,也就是VMnet8网卡的IP,默认是192.168.x.2。如果用的桥接模式,网关就要填你家里路由器的地址(比如192.168.1.1),这个别搞混。
再说防火墙。Ubuntu装了ufw之类的防火墙的话,需要放行22端口:
sudo ufw allow 22/tcp sudo ufw enableCentOS系默认firewalld:
sudo firewall-cmd --permanent --add-port=22/tcp sudo firewall-cmd --reload配置完,在虚拟机里自查一下:
ip addr ping 宿主机IP ping 8.8.8.8这三条都通,说明虚拟机网络没问题。到这里,虚拟机侧的工作就基本完成了,剩下的活交给XShell。
3. XShell侧配置:会话建立与终端体验
3.1 新建会话的参数填写与连接流程
XShell下载安装我就简单说两句。官网下载个人免费版(Home/School),填个名字和邮箱,下载链接会发到邮箱。安装过程一路Next,有个地方可能会被捆绑安装,注意勾选去掉即可。装好后打开,界面很简洁。
新建会话的路径:菜单栏的“新建”图标(或快捷键Alt+N),然后在弹出的窗口里填关键参数:
| 参数项 | 填写内容 | 补充说明 |
|---|---|---|
| 名称 | 随便起,比如“Ubuntu虚拟机” | 主要为了会话管理好辨认 |
| 主机 | 虚拟机静态IP(如192.168.80.10) | 这一步填错就直接拒绝 |
| 端口 | 22 | 除非你改了sshd的端口 |
| 协议 | SSH | 默认就是SSH |
| 用户名 | 虚拟机里的登录用户名 | 先别急着填密码,第一次建议先填用户 |
填完先不急着点连接,到左侧“用户身份验证”那里,勾选“使用SSH密钥”或“密码”方式。日常测试直接密码就行,生产环境才建议用密钥。
然后点连接,第一次会弹一个“SSH安全警告”,提示远程主机的指纹Key,这是正常的,选“接受并保存”即可,相当于把虚拟机的主机指纹记在本地,防止以后中间人伪装。接着输密码,连上后你就能看到类似这样的界面:
Welcome to Ubuntu 22.04.3 LTS root@ubuntu:~#看到这个提示符,就说明XShell和虚拟机之间的通道已经打通了,你现在敲的每条命令,实际上都跑在虚拟机里。
3.2 中文乱码和字体问题怎么处理
这是个几乎每个人都会遇到的小坑。你连上虚拟机后,执行命令输出中文,或者用cat看一个中文配置文件,结果满屏是乱码,比如这种:
▒▒▒▒▒▒▒▒▒▒原因很简单——编码不一致。Linux系统默认locale是UTF-8,XShell默认传输编码如果不是UTF-8,中文自然就乱了。
解决办法:打开XShell顶部菜单“工具→选项→查看”,找到“终端”,把编码改成Unicode(UTF-8);或者更直接,在当前会话里右键窗口标题栏,选择“会话属性”→“终端”→“编码”,选“UTF-8”。改完退出重新连接,乱码基本就消失。个别老系统(比如CentOS 6)用的可能是GBK,那就把编码改成“Simplified Chinese(GBK)”,对症处理。
字体也很影响体验。默认字体在中文环境下显示中文比较丑,还容易重叠。我的建议是:会话属性→外观→字体,选“Consolas”或“JetBrains Mono”,字号14或15,颜色方案选“Linux”或“Solarized”。这样看着舒服很多,长时间盯终端也不累。
3.3 会话管理、快捷键和日常习惯
XShell真正值钱的地方是会话管理。左侧会话栏右键,可以新建文件夹,把你手头所有的机器分类整理,比如开发环境、测试环境、生产环境,每个环境里放对应的会话。双击会话直接连,不用重输IP和密码(密码可以选择保存)。
几个我几乎每天在用的快捷键,值得背下来:
| 快捷键 | 作用 |
|---|---|
| Alt+N | 新建会话 |
| Ctrl+Alt+N | 快速建立连接(输入IP直接连) |
| Ctrl+Shift+C / Ctrl+Shift+V | 复制/粘贴(注意和普通终端有区别) |
| Ctrl+Tab | 切换多个打开的会话标签 |
| Alt+数字 | 快速切换对应标签页 |
还有一个很容易被忽略的习惯:XShell里敲命令,想回到上一行或者上一条命令,直接用↑方向键就行(这是终端历史记录,不是XShell特有的),在命令行里想改词首,按Ctrl+A到行首,Ctrl+E到行尾。有人问我“linux终端怎么换到上一行”,其实就是按↑键,或者用快捷键history,如果你觉得翻历史不方便,直接在终端输history就能看到所有敲过的命令,配合!命令号还能重复执行。
另外一个建议是:多用“快速命令”功能。XShell有个“快速命令”按钮,可以把常用命令存成按钮,点一下就执行。比如重启服务、看日志、磁盘占用,存成按钮后就不用重复敲了,这种高频操作节省的时间非常可观。
4. 实测排错:连接失败的六种典型场景
连接失败大概是这个主题下大家遇到最多的问题了,我把实际排查过程中最常踩的坑整理出来,按现象分类,直接给结论。
4.1 现象一:提示“远程计算机拒绝连接”
这个是最常见的错误,XShell弹窗会显示类似“无法连接远程主机,远程系统拒绝连接”或“Connection refused”。它的本质是TCP层都没建立成功,原因基本三种:虚拟机里根本没装/没启动SSH服务;装了但监听在非22端口;虚拟机防火墙把端口挡了。
排错顺序:
- 先在虚拟机里执行
netstat -tlnp | grep sshd,看sshd有没有监听在0.0.0.0:22上,如果有说明服务正常。 - 在宿主机CMD里执行
ping 虚拟机IP,通不通。不通说明网络层就断了,回虚拟机检查IP、网卡模式。 - 在宿主机CMD里执行
telnet 虚拟机IP 22,如果连接被拒绝,那问题基本就在防火墙或SSH服务本身。
反复出现这种问题,我建议养成一个条件反射:看到拒绝连接,先回答一个问题——“SSH服务到底有没有监听在22端口?”这个答案占了80%以上的根因。
4.2 现象二:提示“认证失败”或一直要密码
能弹出密码框,说明IP和端口对了,是走到了最后一步但密码不对或者权限受限。常见原因:用户名打错;密码记错(Linux密码不分大小写问题不大,但要注意是否开了大写锁定);root用户被禁止直接登录。
针对最后一条,如果你确定密码正确但root连不上,编辑虚拟机里的sshd_config:
sudo vi /etc/ssh/sshd_config # 找到这一行,改成 PermitRootLogin yes # 重启服务 sudo systemctl restart sshd还有一个原因容易忽略:虚拟机系统时间不对。SSH认证对时间敏感,如果虚拟机时间比现实时间差太远,某些认证方式会失败。先date看一下,不对就:
sudo timedatectl set-ntp true4.3 现象三:提示“正在加密远程连接”后卡住
XShell会显示“正在加密远程连接…”,然后一直转圈,最后超时。这个现象通常是网络丢包或防火墙策略把长连接切断了。桥接模式下最容易出现,因为宿主机无线网卡频繁切换或者路由器开了AP隔离。
解决思路:
- 先把XShell的连接超时时间调大:会话属性→连接→“连接超时”改成30秒以上。
- 检查宿主机和虚拟机的网关是否一致。最常见的问题是虚拟机配了错误网关,能通局域网但出不去,外面的包进不来。
- 如果用的是无线网络,建议把虚拟机网络模式从桥接改成NAT。NAT模式下虚拟机和宿主机之间的通道是内部虚拟网卡,不受外部WiFi影响,稳定得多。
4.4 现象四:能连上但操作卡顿、敲命令响应慢
连上了不代表万事大吉。如果敲一个字符要等一秒才有回显,那基本上说明网络延迟高或DNS解析拖慢了命令处理。先检查虚拟机/etc/ssh/sshd_config里的UseDNS,默认yes的话建议改成no,让sshd不用反向解析客户端域名,然后重启服务。
另外还有一类卡顿是XShell自身渲染问题,特别是当你开启了“新式终端”里的一些高级效果(比如透明度、反锯齿),在虚拟机负载高的场景会觉得卡。关掉会话属性里的“高级→功能→启用新式终端模拟”试试,立竿见影。
4.5 现象五:连上了但中文乱码
这个前面细讲过了,核心就一句话:XShell的终端编码和Linux系统locale保持一致。排查时在虚拟里执行locale,看看输出是不是UTF-8。如果查出的结果是POSIX或C,需要显式改一下:
export LANG=en_US.UTF-8 # 或者永久写进~/.bashrc echo "export LANG=en_US.UTF-8" >> ~/.bashrc4.6 现象六:XShell安装失败或打开没界面
有用户在装XShell时遇到安装失败,常见原因:被杀毒软件拦截;下载的不是官方包;以前装过旧版没卸载干净。我的建议是去官网下载最新版,安装时暂时退出杀毒软件实时监控,如果提示权限就右键“以管理员身份运行”。如果安装完成后双击没反应,首先看进程管理器里有没有XShell进程在后台,有的话先结束进程,再检查是不是显卡兼容问题——Windows上遇到过个别版本和老的Intel核显驱动冲突,更新显卡驱动或者右键兼容性设为“Windows 7兼容模式”就能解决。
最后放一个总的排查速查表:
| 现象 | 优先检查 | 处理动作 |
|---|---|---|
| 拒绝连接 | SSH服务是否监听 | systemctl start sshd |
| 拒绝连接 | IP/端口是否正确 | ip addr、netstat |
| 超时无响应 | 网络模式是否被AP隔离 | 改NAT |
| 认证失败 | 用户名密码错误 | 用有权限的用户登录 |
| 认证失败 | root被禁止 | sshd_config改PermitRootLogin |
| 中文乱码 | 编码不一致 | XShell改为UTF-8 |
| 命令卡顿 | UseDNS或网络延迟 | 改UseDNS no |
5. 从虚拟机到远程开发环境:延伸玩法
连接只是一个开始,真正让这台虚拟机变成生产力工具,还需要打通几个周边环节。
5.1 用XShell配合Xmanager/Xftp传文件
XShell默认只有命令行,想要图形化传输文件,可以用同门的Xftp。通常在XShell工具栏上有个“新建文件传输”图标,点一下就能呼出Xftp,直接以当前会话的账号连接到虚拟机,把本地文件拖进去就上传完成了。没有Xftp也没关系,直接用命令行scp即可,XShell本身就是个高效的Shell:
scp /本地路径/文件名 root@虚拟机IP:/目标路径或者从虚拟机下拉文件到本地,方向反过来:
scp root@虚拟机IP:/远程路径 /本地路径日常我传jar包、配置文件都是这么干的,不用虚拟机自带的图形界面,快得多。
5.2 VS Code Remote-SSH接管远程开发
如果你的日常是写代码,强烈建议把VS Code的Remote-SSH插件用起来。这个插件的原理是:在VS Code里基于SSH通道,把本地的编辑器变成一个远程机器的前端,代码在虚拟机里跑,编译、调试都在虚拟机里,但编辑体验是本地化的,非常舒服。
配置方法:
- VS Code装“Remote - SSH”扩展。
- Ctrl+Shift+P输入Remote-SSH: Connect to Host。
- 输入用户名的IP,回车选择配置文件(一般~/.ssh/config)。
- 它会自动连上虚拟机并让你打开文件夹,之后再打开文件、终端都直接操作远程机器。
它和XShell不冲突,日常命令我还在XShell里敲,写代码就切到VS Code,两个工具各干各的。如果VS Code终端里中文乱码,也可以按前面说的在设置里搜“terminal.integrated.profiles.linux”,配置好locale。
5.3 数据库客户端直连虚拟机内的数据库
再往外扩展一步,虚拟机里装了MySQL或PostgreSQL以后,Windows上的数据库工具(比如Navicat、PL/SQL Developer)想直接连进虚拟机里的数据库,要改的不是SSH,而是数据库的监听端口和权限。以MySQL为例:
# 登录mysql mysql -uroot -p # 允许远程连接 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '你的密码'; FLUSH PRIVILEGES; # 改配置文件,让mysqld监听所有地址 sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf # bind-address = 127.0.0.1 改成 0.0.0.0改完记得重启mysql服务,然后在Windows上用Navicat填虚拟机IP、3306端口,就能直连了。这里常见的坑:云安全组或VMware的防火墙没放行3306;MySQL密码策略太强导致密码设置不通过;还有如果虚拟机上面跑着Docker映射了端口,端口冲突也会导致连不上。建议在虚拟机上用netstat确认数据库端口已经监听在0.0.0.0上再排查外部网络。
5.4 我的日常操作习惯
我自己用得最多的习惯,是每次搭建新环境时都会先在XShell里把会话文件夹规划好。比如我手头有三台虚拟机,一台跑数据库,一台跑后端服务,一台跑前端构建,我在会话列表里建了三个文件夹,每个文件夹里对应具体的IP。存好密码后,以后重装系统、换电脑,只要把XShell导出的会话包(文件→导出会话)导入新电脑,所有连接配置直接恢复,不用再记IP。
另一个习惯是善用XShell的日志功能。会话属性里有“日志”选项卡,可以把当前会话的所有输入输出记录到文件里。排查线上问题的时候,回头翻日志比回忆到底敲了什么命令要可靠得多。这个大部分人都没开过,建议打开。
如果你以后要面对几十台机器,光靠XShell的会话列表也不够了,那就该考虑配置管理工具(比如Ansible)去批量分发密钥和管理配置,把SSH当底层的通道来用。但那已经是另一套玩法了。
我从第一次用命令行连虚拟机到现在,踩过最多的坑还是IP配错和防火墙拦截。说句实在话,XShell这个工具本身没什么学习成本,真正的成本在于理解“为什么连不上”——这个思路一旦建立起来,以后不管你换什么工具、连什么机器,都不会再被这个问题卡住。希望这篇内容能帮你少走几步弯路,把这台虚拟机真正变成顺手的工具。