C# 使用Renci.SshNet实现multi-hop SSH跳板机无法连接目标机问题
问题原因与解决方案
核心问题点
- 连接逻辑错误:你当前代码中
Destination.Connect()是直接从Windows设备A发起对目标机C的连接请求,没有通过已建立的跳板机B的SSH通道。如果A和C之间网络不可达,自然会触发连接超时报错。你手动操作是在B的终端环境中执行SSH连接C的命令,流量走B的网络链路,和当前代码的连接逻辑完全不同。 - 客户端类型选择错误:你实例化跳板机连接用的是
SftpClient类,该类仅支持SFTP文件传输操作,不支持SSH端口转发/隧道功能,无法为后续目标机连接提供跳板通道。 - 命令执行逻辑不适用:你封装的
Execute方法调用RunCommand是单次执行命令,执行完成后就会销毁当前会话上下文,无法保持交互终端用来运行后续的SSH连接命令。
推荐实现方案(符合无服务器修改、无手动操作要求)
使用本地端口转发的SSH隧道方案实现多跳连接,步骤如下:
- 改用
SshClient实例化跳板机B的连接 - 跳板机连接成功后,建立本地端口转发规则:将设备A本地的空闲端口流量,通过B的SSH隧道转发到目标机C的22端口
- 实例化目标机C的连接对象时,连接地址填本地回环地址
127.0.0.1,端口填刚才绑定的本地空闲端口,使用C的正常凭据登录即可,此时连接流量会自动通过跳板机B转发到C
示例核心代码:
// 1. 实例化跳板机连接(用SshClient而非SftpClient) using var brokerClient = new SshClient("跳板机B的IP", 跳板机SSH端口, "B的用户名", "B的密码"); brokerClient.Connect(); // 2. 建立本地端口转发,本地用55555端口(可换任意空闲端口),转发到C的22端口 var portForward = new ForwardedPortLocal("127.0.0.1", 55555, "目标机C的IP", 22); brokerClient.AddForwardedPort(portForward); portForward.Start(); // 3. 连接目标机,直接连本地转发端口即可 using var destClient = new SshClient("127.0.0.1", 55555, "C的用户名", "C的密码"); destClient.Connect(); // 4. 执行目标机命令 var result = destClient.RunCommand("pwd").Result; Console.WriteLine(result); // 5. 清理资源 destClient.Disconnect(); portForward.Stop(); brokerClient.RemoveForwardedPort(portForward); brokerClient.Disconnect();
如果需要使用SFTP操作目标机,将第三步的SshClient替换为SftpClient即可,其他逻辑不变。
内容的提问来源于stack exchange,提问作者Paul Efford
相关产品推荐
相关产品推荐

