SSH.NET无法借助Machine A的SSH连接中转访问Machine B的问题
解决SSH.NET通过中转机器访问目标机器的问题
你遇到的问题很典型——你的代码现在是尝试直接建立到Machine B的独立连接,但因为没有直接权限,所以必须借助已连接的Machine A作为跳板。下面是两种可行的解决方案,和你之前用PuTTY中转的逻辑完全匹配:
方法一:本地端口转发(最直观,和PuTTY操作逻辑一致)
这个方法的核心是利用SSH的端口转发功能,把本地的一个端口映射到Machine B的SSH端口(默认22),所有流量通过已连接的Machine A中转。修改后的代码如下:
using (var clientA = new SshClient("hostMachineA", "usernameMachineA", "passwordMachineA")) { clientA.Connect(); try { if (clientA.IsConnected) { // 创建本地端口转发:将本地127.0.0.1:2222的流量转发到Machine B的22端口,通过Machine A using (var forwardedPort = new ForwardedPortLocal("127.0.0.1", 2222, "hostMachineB", 22)) { clientA.AddForwardedPort(forwardedPort); forwardedPort.Start(); // 现在连接本地的2222端口,实际就是通过Machine A中转到Machine B using (var clientB = new SshClient("127.0.0.1", 2222, "usernameMachineB", "passwordMachineB")) { clientB.Connect(); try { var command = clientB.CreateCommand("ls -ltr"); command.Execute(); MessageBox.Show(command.Result); } finally { // 确保断开Machine B的连接 clientB.Disconnect(); } } // 停止端口转发 forwardedPort.Stop(); } } } catch (Exception ex) { MessageBox.Show($"连接或执行命令出错:{ex.Message}"); } finally { // 确保断开Machine A的连接 clientA.Disconnect(); } }
原理说明:
ForwardedPortLocal会在你的本地机器上打开指定端口(这里是2222),所有发送到这个端口的SSH请求,都会通过已建立的Machine A的SSH连接,转发到Machine B的22端口。- 这和你之前用PuTTY连接A后,手动配置端口转发再连接B的逻辑完全一致。
注意事项:
- 如果本地2222端口被占用,可以换成其他未被使用的端口(比如2223、2224等),记得同步修改
clientB连接的端口号。 - 确保Machine A能够正常访问Machine B的22端口(你之前用PuTTY能中转,这个条件已经满足)。
方法二:使用SSH代理直接中转
如果你不想手动管理端口转发,也可以用SSH.NET的代理功能,让连接Machine B的请求自动通过Machine A中转:
using (var proxyClient = new SshProxyClient("hostMachineA", "usernameMachineA", "passwordMachineA")) { proxyClient.Connect(); try { // 创建Machine B的连接信息,并指定代理为Machine A var connectionInfo = new ConnectionInfo( "hostMachineB", 22, "usernameMachineB", new PasswordAuthenticationMethod("usernameMachineB", "passwordMachineB") ) { Proxy = proxyClient }; using (var clientB = new SshClient(connectionInfo)) { clientB.Connect(); try { var command = clientB.CreateCommand("ls -ltr"); command.Execute(); MessageBox.Show(command.Result); } finally { clientB.Disconnect(); } } } catch (Exception ex) { MessageBox.Show($"连接或执行命令出错:{ex.Message}"); } finally { proxyClient.Disconnect(); } }
这个方法更简洁,不需要手动处理端口转发,SSH.NET会自动处理中转逻辑。
内容的提问来源于stack exchange,提问作者Valantis Stergiopoulos
相关产品推荐
相关产品推荐

