☰
XShell跳板机连内网:SSH隧道、ProxyJump与排错
2026/10/1 3:50:58 网站建设 项目流程

内网那台跑着业务库的机器,你在跳板机上 ping 得通、22 端口也开着,可回到自己笔记本上用 XShell 新建会话,主机名一填内网地址,连接就是卡着不动。这不是网络坏了,而是它从一开始就没有对外的入口。中大型公司的网络里,涉及跳板机、XShell、内网机器这三样东西的坑几乎都源于同一个前提:你的电脑和内网之间只留了一扇门,门后站着的那台机器就是跳板机。这篇就把跳板机到底是什么掰开揉碎讲清楚,再说透 XShell 这类 Windows 下的终端工具要经过哪些配置,才能穿过它落到真正的目标机器上。内容偏实操,从原理到配置到排错都覆盖,刚接手运维工作的朋友照着做能直接跑通,干了几年的人也可以看看排错那几节的思路对不对路。

1. 跳板机的本质是把 N 个入口收敛成 1 个

1.1 内网机器为什么天生"连不上"

私有地址段这东西,10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 只在局域网内部有意义。你的笔记本在公司网络之外时,路由表里根本没有通往这些网段的下一跳,数据包发出去就被运营商的路由器丢掉了。所以不是目标机拒绝你,而是你的请求压根到不了它门口。

那给每台机器都配一个公网 IP 行不行?技术上可行,管理上是灾难。每暴露一个 22 端口就多一个被扫描和尝试登录的目标,运维要维护的防火墙规则、账号密码、密钥轮换全部乘以机器数量,人员离职时还得挨个改。审计上更麻烦:出了问题要回答"上周三晚上谁登过这台库、执行了什么",如果没有统一入口,这个答案基本凑不出来。

跳板机的思路很朴素——既然管不住 N 台,那就只管 1 台。所有对内网机器的 SSH 访问一律先落到跳板机,再从跳板机往内发起。外网只需要放行跳板机的一个端口,正规做法还会把它改成非标准端口并限制来源 IP,把能敲这扇门的人数压到最小。

1.2 跳板机、堡垒机、跳转主机到底是不是一回事

这三个词经常被混着用,但能力差别不小。跳板机(Jump Server)通常就是一台普通 Linux 服务器,装了 sshd,运维在上面有自己的账号,密钥登录,从它往内网发 ssh。它不理解你在干什么,只负责搬运字节流。优点是搭起来半小时就能用,缺点全靠自觉——有人把跳板机的私钥拷回家,整个体系就废了一半。

堡垒机(Bastion Host,也常被叫运维审计系统)是在跳板机之上加了强制管控:会话必须通过 Web 或专用客户端发起,目标机的密码由系统托管,运维自己都不知道明文;全程录屏,高危命令实时阻断或告警,操作要工单审批。开源和商业产品都有,Jumpserver 这类在国内用得多。

我自己的判断标准很直接:团队不到五个人、机器不到二十台,一台跳板机加规范的密钥管理就够了,没必要上重装备;一旦涉及等保测评或者甲方的安全审计要求,直接上堡垒机,别自己造轮子,因为审计要的不是功能而是可查验的证据链。

1.3 一次连接里其实串着两段 TCP

在跳板机上执行ssh root@10.0.0.15,背后发生的事是:你的终端到跳板机 sshd 建立第一段 TCP 连接,跳板机上的 ssh 客户端到目标机 sshd 建立第二段 TCP 连接。两段是串联关系,第一段断了第二段必然跟着断,因为第二段的所有数据都要靠第一段来搬运。

这个串联结构是所有配置方式的共同底层。理解它之后,XShell 里那些"隧道""转发"之类的设置就很好懂了:无非是让 XShell 在建立第一段连接之后,替你把第二段也接上,而且接的起点放在你自己的笔记本上,用起来就像直接连了目标机。下面几节的配置差异,说到底都是在不同的位置做这件事。

2. XShell 本地隧道:配一次,之后直接连 127.0.0.1

2.1 先把跳板机这一跳彻底打通

新建会话,连接协议选 SSH,端口 22,主机填跳板机的公网地址。身份验证优先用 Public Key,在"工具 → 用户密钥管理者"里生成一把 ed25519 或 RSA 密钥,把公钥内容追加到跳板机的~/.ssh/authorized_keys。为什么优先密钥而不是密码:密码会被暴力破解、会在多处复用、离职后难以轮换,而密钥可以单独吊销一把。

第一次连接 XShell 会弹主机密钥确认框,把显示的指纹和运维给的指纹对一遍。我习惯让对方在跳板机上执行ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub把结果发过来核对。这一步别嫌麻烦,跳板机是整个内网的门,指纹对不上就该停下来问清楚,而不是点"接受并保存"。

连上之后先做三件小事确认身份和通路:whoami看自己是谁,hostname看落在哪台机器,nc -vz 10.0.0.15 22看跳板机到目标机的 22 端口通不通。第三件事特别重要,因为后面隧道连不上时,你需要知道问题出在跳板机到目标机这一段,还是出在你到跳板机这一段。

2.2 会话属性里那五行参数,每一项都有讲究

在跳板机会话上右键进属性,路径是"连接 → SSH → 隧道",点添加,会看到这样一组字段:

字段建议填写说明
类型Local (Outgoing)本机开侦听口,数据经 SSH 送出
源主机127.0.0.1只允许本机接入,不要写 0.0.0.0
侦听端口2222建议 2000 以上,按目标机编号规划
目标主机10.0.0.15从跳板机视角看的目标地址
目标端口22目标机 sshd 的端口

类型必须选 Local,它的含义是"在我本机开一个侦听端口,收到的数据通过这条 SSH 连接送出去"。别选 Remote,那是反向给别人开入口用的,除非你明确知道自己在做端口回连。

源主机写 127.0.0.1 就够了。写 0.0.0.0 意味着同办公室的同事也能借你的隧道钻进内网,而所有操作在日志上都会记成你的账号,这个责任不该背。

侦听端口为什么不用 22?两个原因:本机可能已经装了 OpenSSH 服务端占用了 22;Windows 上监听 1024 以下的端口在部分策略下需要管理员权限。我一般按目标机编号来规划,2222 给第一台,2223 给第二台,配合会话备注,两年后回来看还能对上号。

目标主机和端口填的是"从跳板机的视角看过去"的地址,也就是内网 IP,不是你家宽带的公网 IP。这一点是新手最容易填错的地方,填错了会得到一连串莫名其妙的超时。

2.3 目标会话为什么必须连 127.0.0.1

再新建第二个会话:主机127.0.0.1,端口 2222,用户名填目标机上的账号,认证方式按目标机的配置来。连接时 XShell 连的是你自己笔记本上的 2222,数据经由那条已经建立的 SSH 连接送到跳板机,跳板机再替你连 10.0.0.15:22。整个过程里,跳板机扮演的是"替你敲门的人",你的目标机永远不会看到你的真实来源 IP,它看到的是跳板机。

注意:目标会话里绝对不要填目标机的内网 IP。填了就是绕过隧道直连,结果必然是连不上,而且会让你误以为是网络或防火墙问题,白白排查半天。

这样配置之后,目标会话在 XShell 里就像一台本机服务,所有功能都能用:日志记录、登录脚本、Xftp 传输、命令发送到多个会话、会话分组。密码或密钥只需要交给目标机一次,跳板机那一跳的事务 XShell 已经代办了,日常使用几乎感觉不到中间隔了一层。

真正能感觉到的只有延迟。多一跳就多一个 RTT,跳板机如果架在异地机房,敲命令时的回显会有肉眼可见的迟滞。所以选跳板机的位置时尽量靠近你的办公网络,这一跳的延迟会放大到后面所有的操作上。

2.4 隧道是"活"在第一个会话里的

本地转发不是配好就永久存在的东西,它的生命周期绑定在跳板机会话上。跳板机那个窗口一关,隧道立即消失,第二个会话会卡在"Connecting to 127.0.0.1:2222"然后报连接被拒绝。

所以我的习惯是:跳板机会话开好之后最小化,不关;顺手在属性 → 日志里勾上"连接时开始记录",把终端输出落到本地文件,出问题时有据可查。同一条隧道可以支撑多个目标会话,只要目标地址在跳板机的可达范围内,一个跳板机窗口后面挂五个内网机器完全没问题。

如果要在无人值守的场景下长期保持隧道,XShell 本身不提供常驻能力,得靠命令行工具配合计划任务来做,那属于另一套玩法,第 5 节会提一句。日常办公场景下,最小化窗口这个土办法其实最省事。

3. 不配隧道也能跳:登录脚本和 ssh 自带的跳转能力

3.1 登录脚本:最省配置,也最脆

在跳板机会话的属性里找到"登录脚本",勾选"执行登录脚本",然后加两条规则:第一条是等待,匹配串写]$或者#;第二条是发送,内容是ssh root@10.0.0.15,可以勾上"发送前等待"。

连接跳板机后,XShell 一旦在输出里看到匹配的提示符,就自动把 ssh 命令敲进去,等于替你完成了第二次跳转。这个办法的好处是零隧道配置,登录脚本还能串好几级,跳两级三级的场景下很好用。

但它脆在哪里呢?匹配串是基于提示符的,跳板机的 PS1 一改就失效,而且失效的时候不会有明显报错,只是命令没发出去,你会盯着一个空白的跳板机终端发愣。更麻烦的是 scp、sftp、Xftp 全都用不了,因为本机压根没有侦听端口可供连接;断线重连后脚本会再执行一次,如果你之前已经在目标机里,就会叠出一层 ssh 嵌套,退出时要按两次exit。

所以我的用法是:登录脚本只用于临时排障、只连一两台机器的场景;凡是需要长期反复访问的,老老实实配隧道。

3.2 用 ssh 自带的跳转能力,把配置写在文本里

如果你本机有 WSL2 或者装了 Windows 版 OpenSSH,可以在~/.ssh/config里用 OpenSSH 自带的多级跳转指令把关系写清楚:

Host jump HostName 203.0.113.10 User ops Port 22 IdentityFile ~/.ssh/id_ed25519 Host db01 HostName 10.0.0.15 User root Port 22 ProxyJump jump

配好之后,ssh db01就等价于先连跳板机再连目标机,中间那一跳由 OpenSSH 自己完成,不需要你开隧道也不需要跳板机上装任何额外软件。更关键的是,scp、rsync、git这些走 ssh 协议的工具全都能直接吃到这份配置,这是它比 XShell 隧道更顺手的地方。

临时用一次的话,连配置文件都不用写,命令行直接敲:

ssh -J ops@203.0.113.10 root@10.0.0.15 scp -J ops@203.0.113.10 ./app.log root@10.0.0.15:/tmp/

在 XShell 里也可以开一个本地 Shell 会话执行这些命令,但说实话,这种纯命令行的活儿用 Windows Terminal 或 WSL2 的终端体验更好,XShell 我留给需要图形化会话树管理的场景。工具各司其职,不用强求一个软件包打天下。

3.3 三种方式怎么选

配置复杂度、能力边界、断线行为都不一样,直接上表:

方式配置量能否传文件断线之后适合场景
本地隧道中等,一次配好能,Xftp 同样配隧道需重开隧道会话长期固定访问几台机器
登录脚本低,但依赖提示符不能脚本会重复执行临时排障、连跳两级以上
ssh 跳转配置低,纯文本可版本化能,scp/rsync 直接可用命令重跑即可习惯命令行、需要脚本化

实际工作中这三种我会混着用:日常巡检走隧道,临时上机器看日志用脚本,写自动化脚本和小工具时用第三种。它们的底层逻辑完全一样,都是把两段 TCP 串起来,没有哪个是"正确"答案。

4. 连不上时的排查顺序

4.1 卡在 Connecting to 127.0.0.1

先回头看跳板机会话在不在、有没有报错信息。最常见的两种报错和处理方式:

第一种,Could not open local port 2222。这是本机端口被占用。Windows 上执行netstat -ano | findstr :2222找到占用进程,要么换端口,要么把占用的程序停掉。还有个隐蔽情况是上一次的 XShell 进程没退干净还占着端口,任务管理器里清一遍就好。

第二种,Connection refused或者channel open failed。这说明隧道本身通了,但跳板机往目标机那一段不通。去跳板机上执行nc -vz 10.0.0.15 22或者timeout 3 bash -c "</dev/tcp/10.0.0.15/22"验证;不通就依次查目标机 sshd 是否在跑(systemctl status sshd)、是否监听 0.0.0.0(ss -tlnp | grep 22)、内网安全策略是否放行。

排查顺序的原则是从近到远:自己笔记本 → 跳板机 → 目标机。每一段都验证过,问题必然定位在中间某一跳,不用瞎猜。

4.2 No matching key exchange method:老 XShell 撞上新服务器

这是老版本 XShell 用户最常撞的墙,报错长这样:

no matching key exchange method found. Their offer: sntrup761x25519-sha512@openssh.com,curve25519-sha256,...

或者:

no matching host key type found. Their offer: ssh-ed25519,rsa-sha2-512,rsa-sha2-256

原因不难理解:较新的 OpenSSH 默认关掉了 diffie-hellman-group1-sha1、diffie-hellman-group14-sha1、ssh-rsa(SHA-1 签名)这些已经不够安全的算法,而 XShell 4、5 能够提议的恰恰就是这些。注意报错里的 "Their offer" 是服务器列出的算法清单,它告诉你服务器支持什么,反过来说明客户端提议的都不在列表里。

两条路可选。推荐的当然是升级 XShell,7 以上的版本对 ed25519 和 rsa-sha2 系列都支持,装完就没事了。如果因为某些原因短期内换不了客户端,只能在服务端临时放开旧算法,编辑/etc/ssh/sshd_config:

KexAlgorithms +diffie-hellman-group14-sha1 HostKeyAlgorithms +ssh-rsa PubkeyAcceptedAlgorithms +ssh-rsa

改完systemctl reload sshd生效。注意 OpenSSH 9.0 之后PubkeyAcceptedKeyTypes改名为PubkeyAcceptedAlgorithms,写旧名字会直接报配置错误导致 sshd 起不来,reload 之前务必用sshd -t检查一遍。

注意:这是主动降低安全等级的做法,只能作为迁移期的过渡,而且最好在安全策略上限制来源 IP。至于热词里有人问的"XShell 4 的 key exchange 算法在哪配",答案是 XShell 4 的会话属性里压根没有暴露算法选择项,只能靠服务端配合,这也是我建议直接换新版本的核心原因。

4.3 三类认证报错,认准关键字就能定位

报错关键字常见原因处理方向
Host key verification failed服务器重装或指纹变更,也可能中间有别的东西在应答跳板机上ssh-keyscan -t ed25519取指纹核对
Permission denied (publickey)密钥未被识别、权限不对、服务端关了密钥认证检查~/.ssh权限 700、authorized_keys600、属主正确
Too many authentication failures本机私钥太多,逐个尝试超过上限配置里加IdentitiesOnly yes并指定唯一密钥

第一类要特别当心。指纹变了有两种可能:机器确实重装过系统,或者有人在中途冒充服务器。稳妥做法是走另一条可信通道(比如让同事在机房直接看)拿到真实指纹再比对,别图省事直接清掉 known_hosts。

第二类的排查有个常被忽略的点:Windows 上从别处拷过来的密钥文件,XShell 的用户密钥管理器里虽然显示了,但会话属性里没勾选它,等于没加载。这个设置藏在会话属性的"身份验证 → Public Key → 属性"里,翻一下就知道。

第三类是本地密钥太多的副作用。ssh 客户端会逐个试所有密钥,服务端一般限制 6 次尝试,超过就直接断开,表现出来的现象是明明正确的密钥却认证失败。指定唯一密钥是最干净的解法。

4.4 连上了但用着别扭,这几个设置调一下

中文字体是高频抱怨点。会话属性 → 外观 → 字体里,选一款等宽且带中文字形的字体,比如等距更纱黑体(Sarasa Mono SC)、思源等宽,编码设成 UTF-8。这样ls输出中文文件名时列宽不会错位,也不会出现方块字。如果只是某台机器上乱码,多半是那台机器的 locale 没配好,locale -a看看有没有 C.UTF-8 或 zh_CN.UTF-8,那是服务端的问题,不是 XShell 的锅。

命令回退目录这个需求,答案就是cd -,它会切回上一个工作目录,反复执行就是在两个目录之间来回跳。如果需要在多个目录间跳转,用pushd/popd维护一个目录栈,dirs -v可以看栈里的内容。再配合Ctrl+R反向搜索历史命令、Ctrl+A跳到行首、Ctrl+E跳到行尾、Ctrl+W删掉一个词、Ctrl+U清空整行,多级跳转下的操作效率会明显不一样。

这些快捷键在跳板机场景下尤其重要,因为每一层 shell 的历史记录和环境变量都是独立的。你在跳板机上敲过的命令,进了目标机之后按上箭头是找不到的,这是正常现象,不是配置出错了。

5. 传文件、虚拟机与云主机、还有那个忘不掉的密码

5.1 走跳板机传文件比你想的麻烦

Xftp 的会话里同样有隧道配置,照着 XShell 那几个参数再填一遍(127.0.0.1:2222 指向目标机的 22),填完就能直接拖拽。这是隧道方案最舒服的地方,一次配置两处受益。

如果只是偶尔传个小文件,可以在目标机上用 lrzsz:敲sz 文件名,XShell 会弹出保存对话框,靠的是终端串流,不需要额外端口也不需要隧道,在跳板机套娃的场景下特别方便。缺点是速度受终端渲染影响,几十兆以内还行,上百兆就别这么干,容易断在半路还得重来。

还有一招scp -3,让跳板机作为中转把文件从 A 推到 B,前提是跳板机能同时连上两边。但这条命令的数据会经过跳板机两次,路径不好理解,出错也不好查,我一般不用,宁可分两步走。

5.2 WSL2、VMware 虚拟机、云主机这三类目标的连接要点

热词里这几类问题问的人最多,本质都是网络可达性的问题,但处理方式完全不同。

WSL2 里的 Linux 是 NAT 网络,Windows 侧访问它靠的是 localhost 转发机制,所以 XShell 里主机填 127.0.0.1、端口 22 通常就能连上。连不上时先在 WSL2 里确认服务跑起来了,service ssh start或systemctl status ssh,再看/etc/ssh/sshd_config里的 ListenAddress 有没有被限死。取 IP 用wsl hostname -I或ip a。较新的 Windows 支持在.wslconfig里把网络模式设为 mirrored,这时 WSL2 直接共享宿主网络,行为就和你直觉一致了,虚拟机的地址和宿主机变成一个。

VMware 虚拟机要分模式讨论。桥接模式下虚拟机拿到的地址和宿主机同网段,XShell 直接填那个 IP 就行;NAT 模式下虚拟机躲在 VMware 的私有网段里,宿主机能通但同局域网的其他机器不通,要么改桥接,要么在虚拟网络编辑器里加端口转发;仅主机模式则只有宿主机能访问。不管哪种模式,都要检查虚拟机内 sshd 是否监听 0.0.0.0:22,以及 firewalld 或 ufw 有没有放行。

云主机是两个地方都要开:云平台控制台的安全组,以及机器自身的防火墙。安全组的来源 IP 别写 0.0.0.0/0,写上家里和公司出口的固定地址,能挡掉绝大多数扫端口的行为。如果打算拿云主机当跳板机用,选最低配的实例就够了,跳板机的负载只是转发字节流,真正的瓶颈在网络带宽和线路延迟上,CPU 和内存都不是问题。

5.3 密码这事,还有换客户端和授权的现实问题

XShell 保存的密码是加密后写进会话文件里的,位置在"文档\NetSarang Computer\Xshell\Sessions"目录下的 .xsh 文件。没有官方的明文导出途径,也不建议去找那些所谓的解密工具——把会话文件交给来路不明的程序处理,等于把整个内网的钥匙递出去,这笔账怎么算都不划算。忘了密码就找管理员重置,或者干脆把登录方式换成密钥,一次麻烦换长期省心。

换办公电脑的时候有个省事技巧:把整个 Sessions 目录打包拷到新机器同样的位置,会话、分组、隧道配置全都跟着走,只有保存的密码需要重新输一遍。这是我每次换设备时最先做的一步。

授权问题也说一句,XShell 对家庭和学校用途有免费版本,官网申请就行,公司环境该买授权还是得买,这个别含糊。热词里提到的"麒麟电脑上类似 XShell 的软件",如果是国产 Linux 桌面环境,系统自带的终端加 ssh 命令其实完全够用,需要的图形化客户端可以看看 Remmina、Termius、FinalShell 这一类,功能侧重点各不相同,挑顺手的用就行,没必要强行找 Windows 工具的替代品。

6. 用了几年跳板机之后,我固定下来的几条习惯

第一条,永远保留一个跳板机会话不关。隧道断掉的时候,第一件事是看跳板机窗口还在不在,这个信息能帮你省掉大半的排查时间。

第二条,多标签页的时候先看提示符。我见过也犯过一次:一边连着跳板机一边连着数据库,切错标签在跳板机上跑了一条清日志的命令,好在只是日志。现在我把跳板机的 PS1 配成带显著标识的样式,目标机用普通颜色,视觉上一眼就能分出来自己在哪一层。

第三条,能用密钥就别用密码,密钥一定加 passphrase,XShell 的密钥管理器能缓存一段时间,一天输一次就够了。跳板机的私钥绝不外带,也不要用同一把密钥同时开跳板机和目标机。

第四条,隧道端口按目标机编号规划,写进会话备注。半年后回来看还能对上号,这个习惯的收益会随着你维护的机器数量增长。

第五条,跳板机上不放自己的脚本、不存临时文件、不装额外软件。那台机器是全公司的公共入口,动它之前想清楚后果。

第六条,涉及生产环境的操作,敲回车前先hostname和whoami确认一遍身份。这条听起来像废话,但它确实是所有事故里出现频率最高的一条。

最后补一句关于版本选择的经验。如果团队还在用 XShell 4 或 5,找一次维护窗口换到 7 以上的版本。旧版本不只是算法协商受限,对 UTF-8 和多字节字符的处理也有历史包袱,中文列宽错位、粘贴多行命令时的奇怪行为在新版本上基本看不到了。换之前把老版本的 Sessions 目录整个备份一份,新版本首次启动会提示迁移,迁移完挑两个会话验证隧道和密钥,确认都对再把旧的删掉,这样出问题还能回滚。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询