SSH.NET
SSH.NET copied to clipboard
Able to Connect but Unable to Execute command
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
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?
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.
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
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 |
I would recommend a shellstream since it seems to require a interactive session and commands in ssh.net are more like plink that PuTTY
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 .
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.
@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.
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();
@emilycanas was there a root cause / workaround to your issue?
@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 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 useShellStream
, 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
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
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.