You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:38:09