SSH.NET icon indicating copy to clipboard operation
SSH.NET copied to clipboard

Unable to connect to a server using 2024.2.0: Key exchange negotiation failed

Open nkoudelia opened this issue 10 months ago • 6 comments

Unable to connect to a server when using SSH.NET 2024.2.0 and base64-encoded ed25519 private key. Version 2024.1.0 works fine.

This is the exception I'm getting:

Renci.SshNet.Common.SshConnectionException: Key exchange negotiation failed.
   at Renci.SshNet.Security.KeyExchange.Finish()
   at Renci.SshNet.Security.KeyExchangeECCurve25519.Finish()
   at Renci.SshNet.Security.KeyExchangeECCurve25519.Session_KeyExchangeEcdhReplyMessageReceived(Object sender, MessageEventArgs`1 e)
   at Renci.SshNet.Session.OnKeyExchangeEcdhReplyMessageReceived(KeyExchangeEcdhReplyMessage message)
   at Renci.SshNet.Messages.Transport.KeyExchangeEcdhReplyMessage.Process(Session session)
   at Renci.SshNet.Session.MessageListener()
--- End of stack trace from previous location ---
   at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout)
   at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle)
   at Renci.SshNet.Session.Connect()
   at Renci.SshNet.BaseClient.CreateAndConnectSession()
   at Renci.SshNet.BaseClient.Connect()
   at FSI_0002.main(String host, String user, String dir) in /home/vmadmin/temp/print-sftp-files.fsx:line 22
   at <StartupCode$FSI_0002>.$FSI_0002.main@() in /home/vmadmin/temp/print-sftp-files.fsx:line 30
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Stopped due to error

Here's my code:

#r "nuget: SSH.NET, 2024.2.0"

open Renci.SshNet
open System
open System.IO

let getAuthMethod (user : string) : AuthenticationMethod =
    let key = Environment.GetEnvironmentVariable "SSH_KEY"
    let pwd = Environment.GetEnvironmentVariable "SSH_PWD"

    if not (String.IsNullOrEmpty key) then
        new PrivateKeyAuthenticationMethod(user, new PrivateKeyFile(new MemoryStream(Convert.FromBase64String key)))
    else if not (String.IsNullOrEmpty pwd) then
        new PasswordAuthenticationMethod(user, pwd)
    else
        failwith "Environment variable SSH_PWD or SSH_KEY must be defined"

let main host user (dir: string) =
    let auth = getAuthMethod user
    use client = new SftpClient(new ConnectionInfo(host, user, auth))

    client.Connect()

    let res = client.ListDirectory dir

    for item in res do
        printfn "%s" item.FullName

match fsi.CommandLineArgs |> List.ofArray with
| [ _; host; user; dir ] -> main host user dir
| _ -> printfn "Usage: dotnet fsi %s <host> <user> <dir>" fsi.CommandLineArgs.[0]

nkoudelia avatar Mar 17 '25 12:03 nkoudelia

The error is happening at the initial handshake i.e. before authentication. There were some changes in 2024.2.0 related to Curve25519 key exchange. Can you get a packet capture, or is this server publicly accessible?

Rob-Hague avatar Mar 17 '25 21:03 Rob-Hague

Can you get a packet capture

I don't know how to do that :(

or is this server publicly accessible?

It is, kind of, but I don't want to advertise it publicly. Can I send you a private message somehow?

The server version is OpenSSH_9.9p2, OpenSSL 3.3.3 11 Feb 2025

nkoudelia avatar Mar 18 '25 06:03 nkoudelia

You can drop me a mail at the address in this commit message: https://github.com/sshnet/SSH.NET/commit/7a599e21c467c3366ba50f4d5f167b868d7123bf

Rob-Hague avatar Mar 18 '25 21:03 Rob-Hague

The problem was the server sending a host certificate (since 2024.2.0 added certificate support) which had an expired validity period, which we then rejected. It seems that ssh does not check the validity period as that worked fine, so perhaps we should do the same

Rob-Hague avatar Mar 25 '25 08:03 Rob-Hague

It seems that ssh does not check the validity period

ssh won't accept an expired certificate. It tries other host key algorithms. If the connection gets accepted by ssh I assume that is because the (non-certificate) host key is in known_hosts.

tmds avatar Apr 09 '25 07:04 tmds

I have also encountered this error since upgrading to 2024.2.0. We connect to 100s of vendor sites though and only 1 has the issue.

It's more than likely an expired host key on the vendors SFTP server then? Are there any other possibilities with this error?

If it's always an expired host key isn't the error message a little vague?

ecole avatar May 15 '25 16:05 ecole