golang / go

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

x/crypto/ssh: connect to centos with cipher aes128-cbc , get an error ssh: handshake failed: ssh: packet too large #64779

Open zouxinjiang opened 8 months ago

zouxinjiang commented 8 months ago

Go version

go1.21.1 windows/amd64

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

set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\xxx\AppData\Local\go-build
set GOENV=C:\Users\xxx\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=D:\xxx\gopath\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=D:\xxx\gopath
set GOPRIVATE=
set GOPROXY=https://goproxy.cn
set GOROOT=D:\xxx\env\go\install
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=D:\xxx\env\go\install\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.21.1
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=0
set GOMOD=NUL
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\xxx\AppData\Local\Temp\go-build1140378664=/tmp/go-build -gno-record-gcc-switches

What did you do?

I want to connect a ssh server (a centos device) with cipher aes128-cbc, but get an error. my code:

cfg := &ssh.ClientConfig{
    User: "xxx",
    Auth: []ssh.AuthMethod{ssh.Password("xxx")},
    HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
        return nil
    },
}

cfg.SetDefaults()

cfg.Ciphers = []string{"aes128-cbc"}
cfg.KeyExchanges = []string{"curve25519-sha256@libssh.org"}

ssh.Dial("tcp", "xxx:22", cfg)

my console output:

panic: ssh: handshake failed: ssh: packet too large

I try to write a ssh server by github.com/gliderlabs/ssh and set the server cipher is aes128-cbc only. then the above code is work。

its looks like different implement for aes128-cbc between golang and other program language。

What did you expect to see?

no any more

What did you see instead?

no any more

thanm commented 8 months ago

@drakkan @golang/security per owners

drakkan commented 8 months ago

Hello,

please remove this line

cfg.KeyExchanges = []string{"curve25519-sha256@libssh.org"}

A version of OpenSSH that supports aes-128-cbc (insecure cipher) is unlikely to also support curve25519-sha256@libssh.org.

If this doesn't help, please specify the version of OpenSSH you are trying to connect to and provide a full, compilable, example to reproduce the issue. Thank you

zouxinjiang commented 8 months ago

hello, I try remove this line and get same error again.

cfg.KeyExchanges = []string{"curve25519-sha256@libssh.org"}

this server support other cipher such as aes128-ctr aes192-ctr etc, but some server must connect with aes128-cbc cipher.

my destnation ssh server info as follow:

[root@harbor ~]# sshd -v
unknown option -- v
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]
            [-E log_file] [-f config_file] [-g login_grace_time]
            [-h host_key_file] [-o option] [-p port] [-u len]

[root@harbor ~]# sshd -T
port 22
addressfamily any
listenaddress [::]:22
listenaddress 0.0.0.0:22
usepam yes
logingracetime 120
x11displayoffset 10
x11maxdisplays 1000
maxauthtries 6
maxsessions 10
clientaliveinterval 0
clientalivecountmax 3
streamlocalbindmask 0177
permitrootlogin yes
ignorerhosts yes
ignoreuserknownhosts no
hostbasedauthentication no
hostbasedusesnamefrompacketonly no
pubkeyauthentication yes
kerberosauthentication no
kerberosorlocalpasswd yes
kerberosticketcleanup yes
gssapiauthentication yes
gssapicleanupcredentials no
gssapikeyexchange no
gssapistrictacceptorcheck yes
gssapistorecredentialsonrekey no
gssapikexalgorithms gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1-
passwordauthentication yes
kbdinteractiveauthentication no
challengeresponseauthentication no
printmotd yes
printlastlog yes
x11forwarding yes
x11uselocalhost yes
permittty yes
permituserrc yes
strictmodes yes
tcpkeepalive yes
permitemptypasswords no
permituserenvironment no
compression yes
gatewayports no
showpatchlevel no
usedns yes
allowtcpforwarding yes
allowagentforwarding yes
disableforwarding no
allowstreamlocalforwarding yes
streamlocalbindunlink no
useprivilegeseparation sandbox
kerberosusekuserok yes
gssapienablek5users no
exposeauthenticationmethods never
fingerprinthash SHA256
pidfile /var/run/sshd.pid
xauthlocation /usr/bin/xauth
ciphers chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,cast128-cbc,3des-cbc
macs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
banner none
forcecommand none
chrootdirectory none
trustedusercakeys none
revokedkeys none
authorizedprincipalsfile none
versionaddendum none
authorizedkeyscommand none
authorizedkeyscommanduser none
authorizedprincipalscommand none
authorizedprincipalscommanduser none
hostkeyagent none
kexalgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
hostbasedacceptedkeytypes ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss
hostkeyalgorithms ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss
pubkeyacceptedkeytypes ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss
loglevel INFO
syslogfacility AUTHPRIV
authorizedkeysfile .ssh/authorized_keys
hostkey /etc/ssh/ssh_host_rsa_key
hostkey /etc/ssh/ssh_host_ecdsa_key
hostkey /etc/ssh/ssh_host_ed25519_key
acceptenv LANG
acceptenv LC_CTYPE
acceptenv LC_NUMERIC
acceptenv LC_TIME
acceptenv LC_COLLATE
acceptenv LC_MONETARY
acceptenv LC_MESSAGES
acceptenv LC_PAPER
acceptenv LC_NAME
acceptenv LC_ADDRESS
acceptenv LC_TELEPHONE
acceptenv LC_MEASUREMENT
acceptenv LC_IDENTIFICATION
acceptenv LC_ALL
acceptenv LANGUAGE
acceptenv XMODIFIERS
authenticationmethods any
subsystem sftp /usr/libexec/openssh/sftp-server
maxstartups 10:30:100
permittunnel no
ipqos lowdelay throughput
rekeylimit 0 0
permitopen any

[root@harbor ~]# uname -a
Linux harbor 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

[root@harbor ~]# cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
drakkan commented 8 months ago

thanks for the additional information I can replicate the problem by connecting to OpenSSH 7.4p1 (centos 7) while it works fine with OpenSSH 5.3p1 (centos 6). Further investigations are needed

zouxinjiang commented 8 months ago

thank you. can show your code for me?

import (
    "fmt"
    "golang.org/x/crypto/ssh"
)

func main() {

    cfg := &ssh.ClientConfig{
        User:            "root",
        Auth:            []ssh.AuthMethod{ssh.Password("123456")},
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    cfg.SetDefaults()
    cfg.Ciphers = []string{"aes128-cbc"}

    cli, err := ssh.Dial("tcp", "192.168.238.128:22", cfg)

    if err != nil {
        fmt.Println("err:===========", err)
        return
    }
    cli.Close()
    fmt.Println("success")
}

go.mod :

go 1.21.1

require golang.org/x/crypto v0.16.0

require golang.org/x/sys v0.15.0 // indirect

console output:

err:=========== ssh: handshake failed: ssh: packet too large

drakkan commented 8 months ago

@zouxinjiang the problem is that our CBC cipher does not implemet ETM mode so it works if you use non-ETM MACs, for example:

MACs: []string{"hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96"},

I'll send a PoC patch adding ETM support later today. It would also be interesting to know more about your use case/target devices to give the right context and priority to this issue. Thank you

gopherbot commented 8 months ago

Change https://go.dev/cl/552495 mentions this issue: ssh: implement ETM mode for AES CBC cipher

zouxinjiang commented 8 months ago

thank you