Возможно ли, чтобы клиент С# SSH взаимодействовал с сервером NodeJS SSH?

У меня есть приложение C#, которому необходимо выполнять определенные команды на аппаратном обеспечении через SSH. Приложение использует SSH.Net для установления соединения, отправки команды и чтения результата. У меня это работает, если я подключаюсь к своей локальной машине с помощью OpenSSH. Наконец, я хотел сделать еще один шаг и настроить свой собственный SSH-сервер, чтобы я мог симулировать несколько аппаратных устройств одновременно (необходимо симулировать наличие более 50 устройств для SSH).

Для этого я настроил простой SSH-сервер, используя nodejs и пакет ssh2. На данный момент у меня подключен клиент, он аутентифицирован (на данный момент принимаются все подключения), и я вижу, что создается объект session. Хотя где я бью стену, так это с выполнением команд, отправленных клиентом. Я заметил, что ssh2 имеет событие для exec в объекте session, но оно никогда не срабатывает (независимо от того, что я вставил в SSH.Net в ShellStream).

Клиентский код C#, который инициирует соединение, выглядит следующим образом (command уже определено, что командная строка должна выполняться):

using(SshClient client = new SshClient(hostname, port, username, password))
{
    try
    {
        client.ErrorOccurred += Client_ErrorOccurred;
        client.Connect();

        ShellStream shellStream = client.CreateShellStream("xterm", Columns, Rows, Width, Height, BufferSize, terminalModes);

        var initialPrompt = await ReadDataAsync(shellStream);

        // The command I write to the stream will get executed on OpenSSH
        // but not on the nodejs SSH server
        shellStream.WriteLine(command);
        var output = await ReadDataAsync(shellStream);
        var results = $"Command: {command} \nResult: {output}";

        client.Disconnect();

        Console.WriteLine($"Prompt: {initialPrompt} \n{results}\n");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception during SSH connection: {ex.ToString()}");
    }
}

Код сервера nodejs, который настраивает сервер ssh2, следующий:

new ssh2.Server({
  hostKeys: [fs.readFileSync('host.key')]
}, function(client) {
  console.log('Client connected!');

  client.on('authentication', function(ctx) {
    ctx.accept();
  }).on('ready', function() {
    console.log('Client authenticated!');

    client.on('session', function(accept, reject) {
      var session = accept();

      // Code gets here but never triggers the exec
      session.once('exec', function(accept, reject, info) {
        console.log('Client wants to execute: ' + inspect(info.command));
        var stream = accept();
        stream.write('returned result\n');
        stream.exit(0);
        stream.end();
      });
    });
  }).on('end', function() {
    console.log('Client disconnected');
  });
}).listen(port, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

Я видел различные примеры клиентов ssh2, вызывающих функцию client.exec, но я полагал, что не имеет значения, что мой клиент не использует пакет узлов ssh2. Есть ли что-то, что мне здесь не хватает?


person Fizz    schedule 15.11.2018    source источник


Ответы (1)


событие сеанса сервера Node.js предназначено для неинтерактивный (exec ) выполнение команды. Под которым они, скорее всего, подразумевают канал SSH exec (предназначенный для неинтерактивного выполнения команд).

Чтобы выполнить команду, используя канал exec SSH в SSH.NET, используйте SshClient.RunCommand.


Напротив, SshClient.CreateShellStream использует канал оболочки SSH, который предназначен для реализации интерактивного сеанса оболочки.

Для этого вам необходимо обработать оболочку событие сеанса сервера Node.js.

person Martin Prikryl    schedule 15.11.2018
comment
Ах ха! Это именно то, чего мне не хватало. - person Fizz; 15.11.2018