C# multi-hop SSH (SSH through SSH)



我写了一个c#控制台程序,通过SSH从a (Windows 10,控制台c#应用程序)连接到B (Linux服务器),然后从那里连接到C (Linux服务器),但我不能从B连接到C(从a到B是ok的)。当我通过Windows终端从A连接到B,从B的终端连接到C时,它工作了,所以我证明了我的凭证是好的。

  • 我使用Renci。SshNet for c#

  • 我用.Connect(),.Disconnect().Execute()扩展方法创建了一个类Server,然后创建了两个类实例BrokerDestination

  • 代码如下:

    if (Broker.Connect())
    {
    Broker.Execute("pwd");
    if (Destination.Connect())
    {
    Destination.Execute("pwd");
    Destination.Disconnect();
    }
    Broker.Disconnect();
    }
    
  • Ssh连接对象像var broker = new SftpClient("Ip", Port, "User", "Pass")一样创建

  • 然后我在Renci.Ssh.Netlib给定方法中内部使用broker.Connect()broker.Disconnect()

  • Tobroker.Execute("cmd")我基本上做

    var output = host.Ssh.RunCommand(str);
    var res0 = output.ExitStatus;
    var res1 = output.Result;
    var res2 = output.Error;
    
  • 我的代码为第一部分工作,因为我设法获得Broker.Execute("pwd")的输出,但它没有连接到Destination.Connect()返回消息A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

  • 我的目标是在c#中使用自动过程进行多跳:用户不能与任何控制台交互,I不能在Linux站点上修改或存储任何文件

你知道问题出在哪里吗?

提前感谢,

我想在这里总结一下我是如何在网上和@jeb:

收集的一些有价值的提示的帮助下解决这个问题的。打开cmd.exe控制台,输入ssh userC@hostC -p portC-J userB@hostB - p portB(portBportC可以提交,如果它们是默认端口22),然后您将被提示输入passwordBpasswordC-按此顺序。如果连接成功,那么您将在hostC控制台上,并将设法做您想做的任何事情。

你需要的代码是:

static void RunSshHop(params string[] cmds)
{
try
{
using (Process p = new Process())
{
p.StartInfo = new ProcessStartInfo("cmd.exe")
{
RedirectStandardInput = true,
UseShellExecute = false,
//WorkingDirectory = @"d:" // dir of your "cmd.exe"
};
p.OutputDataReceived += p_DataReceived;
p.ErrorDataReceived += p_DataReceived;
p.Start();
// way 1: works
foreach (var e in cmds)
p.StandardInput.Write($"{e}n"); // cannot use 'WriteLine' because Windows is 'r' and Linux is 'n'
/* way 2: works as well
using (var sw = p.StandardInput)
{
foreach (var e in cmds)
if (sw.BaseStream.CanWrite)
sw.Write($"{e}n"); // cannot use 'WriteLine' because Windows is 'r' and Linux is 'n'
}
//*/
p.WaitForExit();
if (p.HasExited)
{
Console.WriteLine($"ExitCode: {p.ExitCode}");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}

你可以这样命名它:

static void Main(string[] args)
{
RunSshHop(
"ssh userC@hostC -p portC-J userB@hostB - p portB",
"pwd",
//"...",
"ls"
);
}

为了避免为每台主机输入密码,您还可以创建一个SSH密钥对,如下所示:

  • 打开cmd.exe控制台
  • 类型ssh-keygen -t rsa
  • 选择要生成的公钥和私钥的存放路径(按enter使用默认目的地)
  • 复制目标,你以后会需要它来拿回你的密钥:-)
  • 要管理自动化过程,必须将passphrase保留为空-一旦密钥生成,通过ssh登录到第一台主机,如ssh youruser@firsthost -p hostport(-p hostport部分可以忽略,如果端口是默认的22)
  • 类型ssh-copy-id youruser@firsthost -p hostport
  • 对第二台主机重复此过程

相关内容

  • 没有找到相关文章

最新更新