golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.68k stars 17.49k forks source link

x/crypto/ssh: "ssh: handshake failed: EOF" with 3des-cbc #32075

Open eikenb opened 5 years ago

eikenb commented 5 years ago

What version of Go are you using (go version)?

$ go version
go version go1.12.5 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN="/home/jae/.local/bin"
GOCACHE="/home/jae/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/jae/projects/go/golib:/home/jae/projects/go/gotools:/home/jae/projects/go/mylib"
GOPROXY=""
GORACE=""
GOROOT="/home/jae/projects/go/goroot"
GOTMPDIR=""
GOTOOLDIR="/home/jae/projects/go/goroot/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/jae/notes/developement/programming/go/examples/misc-tests/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build225295978=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I help maintain the github.com/pkg/sftp library and am helping a user with an ssh issue. They have an SFTP server that only supports some older ciphers, like 3des-cbc and they can't connect successfully. I've tried to simplify and reproduce their issue with some success. I've configured my local openssh server to only accept that cipher, with Ciphers 3des-cbc in the sshd_config and was able to connect to it with the openssh client with ssh -c 3des-cbc localhost. If I don't specify -c 3des-cbc on the command line it won't connect with a negotiation error. So everything seems good on that side.

I then try to connect with a simple program using x/crypto/ssh set to use that same cipher and get the error ssh: handshake failed: EOF and the openssh server spits out the following in the log.

May 15 20:41:26 XXX sshd[12686]: Bad packet length 1474871687. [preauth]
May 15 20:41:26 XXX sshd[12686]: ssh_dispatch_run_fatal: Connection from 127.0.0.1 port 53234: Connection corrupted [preauth]

My simple program to reproduce is..

package main

import (
    "fmt"
    "net"
    "os"

    "golang.org/x/crypto/ssh"
    "golang.org/x/crypto/ssh/agent"
)

func main() {
    sshagent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
    if err != nil {
        panic(err)
    }
    signer := ssh.PublicKeysCallback(agent.NewClient(sshagent).Signers)

    sshConfig := &ssh.ClientConfig{
        User:            os.ExpandEnv("$USER"),
        Auth:            []ssh.AuthMethod{signer},
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    sshConfig.SetDefaults()
    sshConfig.Ciphers = []string{"3des-cbc"}

    _, err = ssh.Dial("tcp", "localhost:22", sshConfig)
    fmt.Printf("%v\n", err)
}

What did you expect to see?

No error and have it connect.

What did you see instead?

ssh: handshake failed: EOF

Thanks.

FiloSottile commented 5 years ago

/cc @hanwen

manhquyet-nguyen commented 5 years ago

Any update on this issue? I got the same problem. Connect from terminal is OK but failed via ssh. The server ssh version is SSH-2.0-OpenSSH_6.2

hanwen commented 5 years ago

I've been on hoidays. I'll try to have a look one of these weeks.

manhquyet-nguyen commented 5 years ago

I've debugged. Server accept: [aes128-ctr aes192-ctr aes256-ctr arcfour256 arcfour128 aes128-gcm@openssh.com aes256-gcm@openssh.com aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc arcfour rijndael-cbc@lysator.liu.se] Working algorithm are: [aes128-ctr aes192-ctr aes256-ctr arcfour256 arcfour128 arcfour] The other cause the ssh failed with EOF error

eikenb commented 4 years ago

@hanwen

I had another user file a bug about this. I don't want to nag as I know how hard it can be to find time to work on things but I just wanted to ping the issue again to help it stay on the radar. Thanks.

poojashete commented 3 years ago

I am facing similar issue where I cant connect to docker IP and getting ssh: handshake failed EOF error.

Copying snippet of my code

` func scp() (bool, error) {

    var hostKey ssh.PublicKey
    if err != nil {
            fmt.Println("Upload: Failed to Connect")
            return isUploaded, err
    }
    // Define the Client Config as :
    config := &ssh.ClientConfig{
            User: "root",
            Auth: []ssh.AuthMethod{
                    ssh.PublicKeys(key),
            },
            Config: ssh.Config{
                     KeyExchanges: []string{"diffie-hellman-group-exchange-sha256",
                                            "curve25519-sha256@libssh.org ecdh-sha2-nistp256",
                                            "ecdh-sha2-nistp384 ecdh-sha2-nistp521",
                                            "diffie-hellman-group14-sha1",
                                            "diffie-hellman-group1-sha1",
                                            "aes128-ctr",
                                            "aes192-ctr",
                                            "aes256-ctr",
                                            "arcfour256",
                                            "arcfour128",
                                            "arcfour",
                            },
            },
            HostKeyCallback: ssh.FixedHostKey(hostKey),
            }
     fmt.Println("Dialing .... ")
    client, err := ssh.Dial("tcp", ip1+":8080", config)
    if err != nil {
            fmt.Println("Failed to dial IP1: " + err.Error())
    }
    defer client.Close()

}`

Tried with and without default KeyExchanges.

Getting below error

Failed to dial IP1: ssh: handshake failed: EOF

4a6f656c commented 2 years ago

@eikenb the cause of this is most likely Encrypt-then-MAC (EtM) mode - 84bacda6 added support for hmac-sha2-256-etm@openssh.com, however only implemented it for stream ciphers (arcfour*) and not for CBC block ciphers (aes128-cbc and 3des-cbc). This means that the SSH client will advertise support for EtM, the SSH server will select a CBC cipher with EtM, then the client fails to handle the resulting packets correctly (these days it will likely appear in the form of an invalid packet length error, rather than EOF).

Until this is fixed, the workaround would be to specify one or more MACs, excluding EtM (e.g. hmac-sha2-256).

mhkyle commented 1 year ago

same issues happened, when try to use ssh key to execute some commands on the linux nodes by use net/dial.go to do it and

ssh: handshake failed: EOF

Most wired thing is that for some times it failed, while after reconciling and retry, it can work after retrying.

cserken commented 10 months ago

same issues happened, when try to use ssh key to execute some commands on the linux nodes by use net/dial.go to do it and

ssh: handshake failed: EOF

Most wired thing is that for some times it failed, while after reconciling and retry, it can work after retrying.

I have got the same issues and also work after retry. By the way, any updates or fixed plan about this issue? @4a6f656c

startergo commented 3 months ago

Same issue. The real machine will connect to server via diffie-hellman-group-exchange-sha256, but packer (using golang) would not. https://github.com/hashicorp/packer/issues/12994

LEVI-Tempset commented 3 months ago

Maybe multiple ssh connection refuse by remote server. sshd has default MaxStartups 10. try:

  1. modified /etc/ssh/sshd_config and set MaxStartups to 100
  2. restart sshd
LEVI-Tempset commented 3 months ago

Or just do: use 1 connection and mutilple sessions. Don't foget to modify MaxSessions in /etc/ssh/sshd_config and restart sshd