我写了一个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
,然后创建了两个类实例Broker
和Destination
-
代码如下:
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.Net
lib给定方法中内部使用broker.Connect()
和broker.Disconnect()
-
To
broker.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
(portB
和portC
可以提交,如果它们是默认端口22),然后您将被提示输入passwordB
和passwordC
-按此顺序。如果连接成功,那么您将在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
- 对第二台主机重复此过程