首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#多跳SSH (SSH到SSH)

C#多跳SSH (SSH到SSH)
EN

Stack Overflow用户
提问于 2021-10-18 13:35:12
回答 1查看 138关注 0票数 0

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

  • I正在为C#

使用Renci.SshNet

Destination

  • I创建了一个具有.Connect().Disconnect().Execute()扩展方法的类Server,然后创建了两个类实例Broker.Execute()

  • 我的代码如下所示:

if (Broker.Connect()) { Broker.Execute("pwd");if (Destination.Connect()) { Destination.Execute("pwd");Destination.Disconnect();} Broker.Disconnect();}

创建与var broker = new SftpClient("Ip", Port, "User", "Pass")类似的Ssh连接表

然后,我在内部使用

  • ,在Renci.Ssh.Net库中使用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.ExitStatus

我的代码用于第一部分,因为我设法获得了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的输出,但是它没有连接到返回消息的Destination.Connect()上。

  • 我的目标是使用C#内部的自动化进程进行多跳:用户不能与任何控制台交互,而i不能在Linux站点

上修改或存储任何文件。

知道问题出在哪里吗?

提前谢谢你,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-25 14:58:59

我想在这里总结一下我是如何在网上收集到的一些有价值的提示和@jeb的帮助下解决这个问题的:

打开一个cmd.exe控制台,键入ssh userC@hostC -p portC-J userB@hostB - p portB (如果它们是默认端口22,则可以将portBportC排除在外),然后将提示您输入passwordBpasswordC --按照这个顺序。如果连接成功,那么您将在hostC控制台上,并设法执行您想做的任何事情。

您需要的代码是:

代码语言:javascript
复制
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);
    }
}

你可以这样称呼它:

代码语言:javascript
复制
static void Main(string[] args)
{
    RunSshHop(
       "ssh userC@hostC -p portC-J userB@hostB - p portB",
       "pwd",
       //"...",
       "ls"
    );
}

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

ssh-keygen -t rsa

  • choose路径中保存要生成的公共和私钥(按下enter以使用默认的destination)

  • copy -目的地,您将需要它稍后得到yxour键:-)

  • 来管理一个自动化的过程,您必须让passphrase空的-once键是生成的,通过ssh (如22)

  • type ssh-copy-id youruser@firsthost -p hostport

  • accept

  • repeat )登录到第一个主机(如果端口是默认的22)

  • typessh-copy-id youruser@firsthost -p hostport

  • accept

  • repeat,则可以忽略-p hostport部分,这是第二个主机

的进程)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69617079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档