sshnet / SSH.NET

SSH.NET is a Secure Shell (SSH) library for .NET, optimized for parallelism.
http://sshnet.github.io/SSH.NET/
MIT License
3.88k stars 917 forks source link

Able to Connect but Unable to Execute command #1368

Open emilycanas opened 2 months ago

emilycanas commented 2 months ago

Hello!

I am able to connect using SshClient, but I am unable to execute commands. Does anyone know why this might be? The target framework I am using is net6.0. I have tried using different encoding methods, as well as default encoding, but that doesn't seem to make a difference. Does anyone know why this might be and how it can be fixed?

This is the exception that is raised: Renci.SshNet.Common.SshConnectionException: An established connection was aborted by the server. at Renci.SshNet.SshCommand.WaitOnHandle(WaitHandle waitHandle) at Renci.SshNet.SshCommand.EndExecute(IAsyncResult asyncResult) at line 26

Screenshot 2024-04-03 170731

WojciechNagorski commented 2 months ago

You have to provide more info, versions of server, library and dotnet. How your ssh server is configutated. Can you able to use ssh CLI?

Rob-Hague commented 2 months ago

Can you inspect the value of command.Error when the exception is thrown (either by breaking when it's thrown or printing the value in a catch block)? edit: even just command.Result

My guess is that you need to supply an argument to the ping command, and it's telling you that through "standard error" stream and then rudely disconnecting. command.Result is "standard out".

If command.Error doesn't show anything, you can try ssh user@host ping at the command line to see if that works or not.

emilycanas commented 2 months ago

I am currently using the default server of Welotec's TK525L-v2 router. I am able to connect using ssh on puTTy and run commands on there. I am also able to connect and run commands via command prompt using "ssh user@host".

I am using this library (ssh.net) with the target framework being net6.0.

I do have a bit of an update. Since yesterday the router was updated to Welotec's TK525L-v2 . Although I am still able to create a client and connect using SshNet I am still not able to successfully run a command. Yesterday, when I tried to run a command the above exception was thrown. Now when I try to run a command, the connection is not aborted or timed out, but I am not able to move forward with the program even after 10 min of trying to execute a command. Because of this reason I am not able to read out command.Error or command.Result. I have tried using ssh commands, commands available in puTTy, as well as non-existent command when running for client.RunCommand("INSERTCOMMANDHERE"); and client.CreateCommand("INSERTCOMMANDHERE"); and regardless I am not able to move forward with the program.

Also(fyi) these are the commands available when connected on puTTY or on command prompt: help -- get help for commands language -- Set language show -- show system information exit -- exit current mode/console ping -- ping test comredirect -- COM redirector telnet -- telnet to a host ssh -- ssh to a host traceroute -- trace route to a host enable -- turn on privileged commands

Rob-Hague commented 2 months ago

This is some dumb, untested code but you could try it for debugging:


using (SshCommand command = ...)
{
    IAsyncResult result = command.BeginExecute();
    Thread.Sleep(5000);
    command.OutputStream.Flush();
    command.ExtendedOutputStream.Flush();
    byte[] readBuffer = new byte[1024];
    string stdout = Encoding.UTF8.GetString(readBuffer, 0, command.OutputStream.Read(readBuffer, 0, readBuffer.Length));
    string stderr = Encoding.UTF8.GetString(readBuffer, 0, command.ExtendedOutputStream.Read(readBuffer, 0, readBuffer.Length));
    _ = command.EndExecute(result);
}

If nothing comes of that, perhaps you could fill out this table to help with understanding?

Command What happens
ssh user@host ping
ssh -t user@host ping
ssh -T user@host ping
darkoperator commented 2 months ago

I would recommend a shellstream since it seems to require a interactive session and commands in ssh.net are more like plink that PuTTY

emilycanas commented 2 months ago

Thank you guys for your help! It is much appreciated!

@Rob-Hague I plugged in the code you sent over and printed out stdout and stderr onto the console. I was able to see the correct router details in the same format in which it is printed onto puTTy terminal. Nonetheless, I was not able to see that the command was ran or any results from the command. Using the same code you sent over I plugged in commands you sent over "ssh -t/-T user@host ping" both had the same result as when running with a "regular" commands (commands available when connected to puTTy as described above). I am not sure if these are the correct commands to use for ssh.net. Is there a list of commands I can try out? Also, I should mention that "_ = command.EndExecute(result);" makes it so that the program does not end.

@darkoperator Thank you for your suggestion. I was able to run commands and retrieve results using a shellstream similar to : https://stackoverflow.com/questions/30883237/how-to-run-commands-on-ssh-server-in-c .

Rob-Hague commented 2 months ago

Glad you got it working

I was unclear, but I was looking for the results of running e.g. ssh -T user@host ping from the command line, rather than from SSH.NET. In theory, this command would emulate your original code. As @darkoperator refers to, the device probably requires a "pseudo- (interactive) terminal" to be allocated in order to run commands remotely. ShellStream does this but SshCommand does not. ssh -T disables the pseudo-terminal allocation so I was expecting that command to fail at the command line just like the C# code.

As for a "list of commands to try", this would be whatever command can run on the device i.e. the ones you posted earlier, and not something SSH.NET specific.

emilycanas commented 2 months ago

@Rob-Hague

Thank you for the clarification. I retried the commands using a cli. I was able to connect and run the commands you sent earlier. There was not a difference between using ssh and ssh -t. With each command, I was prompted to enter a password in the cli and then was able to run commands in the same way I am able to run commands using puTTy. So this makes the issue with running commands using Ssh.NET a bit more confusing. When using the cli to connect and run commands there was mention of server's rsa2(ssh-rsa sha256) key fingerprint before connecting.

mojmik commented 2 months ago

I had the same issue. Also with a router/switch. Had to use:

ShellStream _shellStream = client.CreateShellStream("input", 255, 50, 400, 600, 4096, terminalMode);
_shellStream.WriteLine(command);
var output = _shellStream.Expect(promptRegex);

instead of:

var cmd = client.CreateCommand(command);
var result = cmd.Execute();
LadderLogic commented 1 month ago

@emilycanas was there a root cause / workaround to your issue?

Rob-Hague commented 1 month ago

@LadderLogic as above, the root cause is that the device requires an interactive session (pseudo-termainal) to be allocated, which SshCommand does not do. The workaround is to use ShellStream, which does

LadderLogic commented 1 month ago

@LadderLogic as above, the root cause is that the device requires an interactive session (pseudo-termainal) to be allocated, which SshCommand does not do. The workaround is to use ShellStream, which does

@Rob-Hague thank you. I have access to my linux device configuration, and I would rather change the SSH configuration to not require an interactive session than using the workaround, but I am unable to locate where in my config does it actually enable interactive session. I've posted the sshd config here on SO

Rob-Hague commented 1 month ago

From reading your StackOverflow post it sounds like your problem is that commands are working but taking a long time. This issue is about commands not working at all, so it sounds like a different problem.

Perhaps you could start by narrowing down whether the problem occurs only in Posh-SSH, or also when using SSH.NET directly. If the latter, I can only suggest running with a debug build of SSH.NET, and trying to see where things are getting stuck. You can get some logs with https://github.com/sshnet/SSH.NET/wiki/Troubleshooting-SSH.NET#net-tracesource-and-tracelisteners

If it does indeed sound like a different problem to this issue, it would be best to open a new one

LadderLogic commented 1 month ago

From reading your StackOverflow post it sounds like your problem is that commands are working but taking a long time. This issue is about commands not working at all, so it sounds like a different problem.

Perhaps you could start by narrowing down whether the problem occurs only in Posh-SSH, or also when using SSH.NET directly. If the latter, I can only suggest running with a debug build of SSH.NET, and trying to see where things are getting stuck. You can get some logs with https://github.com/sshnet/SSH.NET/wiki/Troubleshooting-SSH.NET#net-tracesource-and-tracelisteners

If it does indeed sound like a different problem to this issue, it would be best to open a new one

I'll attempt a debug build. FWIW, while Posh-SSH times out with default timeout setting, using SSH.NET directly causes it respond 4-8 minutes later, which for the most part I though it was hung and not responding, until I forgot to stop the debug run one of the times and noticed the execution eventually continue :) I was assuming that OP went through similar conclusion since it is not a norm to wait 4-8 minutes for a command to complete.