Skip to content

Troubleshooting SSH.NET

Rob Hague edited this page May 5, 2024 · 10 revisions

If you encounter problems using the library, use this page as a reference on how to try find the source of the problem.

Please ensure you are using the latest release of SSH.NET. If you are already using the latest release, then download and compile the latest source code. Don't forget to update your project(s) reference(s).

Table of Contents

  1. Frequently experienced SSH.NET exceptions
  2. System.Net.Socket exceptions
  3. NET TraceSource and TraceListeners
  4. Wireshark

How to narrow your problem down

By creating the simplest possible code that reproduce the problem you are having, it will be easier to debug and to pinpoint exactly where and why the problem is happening. So take some time to create code that can reproduce the problem.

Frequently experienced SSH.NET exceptions

"Key exchange negotiation failed"

The client and the server cannot find a common algoritm for exchanging keys.

To find out what kind of algorithms the server supports, you can put a breakpoint in the Start(Session, KeyExchangeInitMessage) method in Security\KeyExchange.cs.

"No suitable authentication method found to complete authentication."

The server is expecting a password/key authentication, but the client is sending a key/password, or an authentication mechanism that is not commonly supported by both client and server.

System.Net.Socket exceptions

Sometimes the server doesn't know what to do, and it just closes the connection and you'll get An existing connection was forcibly closed by the remote host exception.

If you get any of the following exception descriptions, it might be a problem on the computer you are running the program from, or the network you are on, and you should try your program on a different computer and network:

  • A blocking operation was interrupted by a call to WSACancelBlockingCall
  • Connection was lost
  • A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied

.NET TraceSource and TraceListeners

SSH.NET contains some tracing functionality via System.Diagnostics, but at the time of writing, this is very limited.

You need a debug build of the library:

git clone https://github.com/sshnet/SSH.NET.git

cd SSH.NET

dotnet build

In your project, remove any NuGet reference to SSH.NET and add a reference to Renci.SshNet.dll in SSH.NET/src/Renci.SshNet/bin/Debug/{TARGET}/.

Configuration on .NET Core must be done programmatically, as follows:

using Renci.SshNet.Abstractions;

Trace.AutoFlush = true;
DiagnosticAbstraction.Source.Switch = new SourceSwitch("sourceSwitch", "Verbose");
DiagnosticAbstraction.Source.Listeners.Remove("Default");
DiagnosticAbstraction.Source.Listeners.Add(new TextWriterTraceListener("trace.sshnet.log"));

On .NET Framework it is possible to configure via app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <trace autoflush="true"/>
        <sources>
            <source name="SshNet.Logging" switchValue="Verbose">
                <listeners>
                    <remove name="Default"/>
                    <add name="SshNet.Logfile"
                         type="System.Diagnostics.TextWriterTraceListener"
                         initializeData="trace.sshnet.log" />
                    <add name="console"
                         type="System.Diagnostics.ConsoleTraceListener"  />
                </listeners>
            </source>
            <!-- 
            It is also possible to configure the built in network tracing, which can be helpful to see the data
            passing through the sockets. See 
            https://learn.microsoft.com/en-us/dotnet/framework/network-programming/how-to-configure-network-tracing
            for more details.
            -->
            <source name="System.Net.Sockets" switchValue="Verbose">
                <listeners>
                    <add name="System.Net.Sockets.Logfile"
                      type="System.Diagnostics.TextWriterTraceListener"
                      initializeData="trace.system.net.sockets.log" />
                </listeners>
            </source>
        </sources>
    </system.diagnostics>
</configuration>

After you run your application, you can find trace.sshnet.log in your bin/Debug folder.

Wireshark

Wireshark is able to dissect initial connection packets, such as key exchange, before encryption happens. Enter "ssh" as the display filter. See https://wiki.wireshark.org/SSH.md for more information.

image