golang/go

x/crypto/ssh: can't establish ssh connection using signed key

kt97679 opened this issue · 22 comments

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

$ go version
go version go1.18.4 linux/amd64

Does this issue reproduce with the latest release?

yes

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

ubuntu 18.04 amd64

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/XXX/.cache/go-build"
GOENV="/home/XXX/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/var/tmp/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/var/tmp/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/XXX/bin/go1.18.4"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/XXX/bin/go1.18.4/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18.4"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/XXX/work/go/go.mod"
GOWORK=""
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-build2094095442=/tmp/go-build -gno-record-gcc-switches"

What did you do?

$ go run 001-ssh-test.go 127.0.0.1:22
2022/07/24 08:44:16 Connecting to 127.0.0.1:22
2022/07/24 08:44:16 We've got a live session!
$ go run 001-ssh-test.go 10.19.197.10:22
2022/07/24 08:44:25 Connecting to 10.19.197.10:22
2022/07/24 08:44:28 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
exit status 1
$ cat 001-ssh-test.go 
package main

import (
        "log"
        "net"
        "os"
        "os/user"

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

func logFatal(err error) {
        if err != nil {
                log.Fatal(err)
        }
}

func main() {

        sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
        logFatal(err)

        u, err := user.Current()
        logFatal(err)

        cfg := &ssh.ClientConfig{
                User: u.Username,
                Auth: []ssh.AuthMethod{ssh.PublicKeysCallback(agent.NewClient(sock).Signers)},
                HostKeyCallback: ssh.InsecureIgnoreHostKey(),
        }

        log.Printf("Connecting to %s\n", os.Args[1])
        client, err := ssh.Dial("tcp", os.Args[1], cfg)
        logFatal(err)

        _, err = client.NewSession()
        logFatal(err)

        log.Println("We've got a live session!")
}
$ cat go.mod 
module test
require golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
require golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
go 1.18
$

What did you expect to see?

Connection is established using signed key.

What did you see instead?

Connection is not established with an error message:

ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain

Additional information

I have 2 keys in the agent and I can connect ok via ssh command to 127.0.0.1 (accepts only unsigned keys) and 10.19.197.10 (accepts only signed keys):

$ ssh-add -l
4096 SHA256:m+Hthc93TjF0wcAoq8OyrKZjDl8LE5ddhQwzwnBA02c /home/XXX/.ssh/id_rsa (RSA)
4096 SHA256:m+Hthc93TjF0wcAoq8OyrKZjDl8LE5ddhQwzwnBA02c /home/XXX/.ssh/id_rsa (RSA-CERT)
$ ssh 127.0.0.1 "dpkg -l|grep openssh"
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
ii  openssh-client                        1:7.6p1-4ubuntu0.7                     amd64        secure shell (SSH) client, for secure access to remote machines
ii  openssh-server                        1:7.6p1-4ubuntu0.7                     amd64        secure shell (SSH) server, for secure access from remote machines
ii  openssh-sftp-server                   1:7.6p1-4ubuntu0.7                     amd64        secure shell (SSH) sftp server module, for SFTP access from remote machines
$ ssh 10.19.197.10 "dpkg -l|grep openssh"
ii  openssh-client                        1:7.6p1-4ubuntu0.6                  amd64        secure shell (SSH) client, for secure access to remote machines
ii  openssh-server                        1:7.6p1-4ubuntu0.6                  amd64        secure shell (SSH) server, for secure access from remote machines
ii  openssh-sftp-server                   1:7.6p1-4ubuntu0.6                  amd64        secure shell (SSH) sftp server module, for SFTP access from remote machines
$

Versions of the ssh components are in the output above.

Hi @FiloSottile , here is an issue I filed per your request. Thanks!

cc @FiloSottile @golang/security

Folks, do you have any news on this by any chance?

Any help with resolving this issue will be very much appreciated.

@kt97679 Can you run ssh-agent with -d option and test running your program again?

$ ssh-agent -d -a $SSH_AUTH_SOCK
...
$ go run 001-ssh-test.go 10.19.197.10:22
# wait until exit

and copy-paste the output once the program exit.

@shuLhan please find output below. Please let me know if there is anything else I can do to help with debugging.

# shell session 1
$ ssh-agent -d -a /tmp/test-agent
SSH_AUTH_SOCK=/tmp/test-agent; export SSH_AUTH_SOCK;
echo Agent pid 5944;
debug2: fd 3 setting O_NONBLOCK
debug2: fd 4 setting O_NONBLOCK
debug1: process_message: socket 1 (fd=4) type 11
debug2: fd 4 setting O_NONBLOCK
debug1: process_message: socket 1 (fd=4) type 17
debug1: process_message: socket 1 (fd=4) type 17
debug2: fd 4 setting O_NONBLOCK
debug1: process_message: socket 1 (fd=4) type 11
debug2: fd 4 setting O_NONBLOCK
debug1: process_message: socket 1 (fd=4) type 11

# shell session 2
$ SSH_AUTH_SOCK=/tmp/test-agent; export SSH_AUTH_SOCK;
$ ssh-add -L
The agent has no identities.
$ ssh-add
Enter passphrase for /home/XXX/.ssh/id_rsa:
Identity added: /home/XXX/.ssh/id_rsa (/home/XXX/.ssh/id_rsa)
Certificate added: /home/XXX/.ssh/id_rsa-cert.pub (midway)
$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCuXW2Nc1St7rocbyi3RCOvkxRazi3cmt7oOjHbYciq4/ZkC5kDx/n/xG5k9OOL90pQ3kaIwqHeJZ5ET6nJ1sQAy7i2BlPHbSipX4wJkzBOZfEeQUzNu6U8owdO0MZEfOnez7bhT0lHlh1DCUq0bj07gfKxpxTICqqlBJ3Z9oCfQTeFmVLX/b/GOvVlU9l9XaEy6VTszecdyj8H08PNpVzyKpzbD58b1oKvLLtoVlsZQJahj9ZGe6F+Qb6wUNKUhdb7qyy7/FoDQBNjwZEG1WuNbE1UtwWdiCT7x0Amv/k+weEqlha50iUnqCAurituQBWenl7vMVSoU//PZsNw7H5qVqwNGJdNr+XHZkw9invUbcCT/GSDRA33teW8xRYxB/cZlEITG4sXYUjJJXCMbybaVhCr1Iarb1giVSQVmuAiHdnCByiEU3nXkw1gNbUDOLnqUJDJWi9KbPT1RpHpDTzVWBgb6igyr4txWq6EDdtwJ4nBvcJFwuzdhis6RIdTVpokyor3zvfZRPpPA/wahtUy09SKps97wf8dNiYWId7dbx/2NcEpk8gDGUgE403JbkwyZZOEZojxmQ1h0K6CgjfD8rkcx4kO2DEkomkMaGDZtm8a/84RpoiH2LJ9KRVtiE267hQckFrv2kf+/5qPr2ATKiwDBiB8S7g1sDdWHLb3mw== /home/XXX/.ssh/id_rsa
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgxrMEpOWf7tnCerqWi4QL83pVLStKQ1aKcY3DB9bXpkIAAAADAQABAAACAQCuXW2Nc1St7rocbyi3RCOvkxRazi3cmt7oOjHbYciq4/ZkC5kDx/n/xG5k9OOL90pQ3kaIwqHeJZ5ET6nJ1sQAy7i2BlPHbSipX4wJkzBOZfEeQUzNu6U8owdO0MZEfOnez7bhT0lHlh1DCUq0bj07gfKxpxTICqqlBJ3Z9oCfQTeFmVLX/b/GOvVlU9l9XaEy6VTszecdyj8H08PNpVzyKpzbD58b1oKvLLtoVlsZQJahj9ZGe6F+Qb6wUNKUhdb7qyy7/FoDQBNjwZEG1WuNbE1UtwWdiCT7x0Amv/k+weEqlha50iUnqCAurituQBWenl7vMVSoU//PZsNw7H5qVqwNGJdNr+XHZkw9invUbcCT/GSDRA33teW8xRYxB/cZlEITG4sXYUjJJXCMbybaVhCr1Iarb1giVSQVmuAiHdnCByiEU3nXkw1gNbUDOLnqUJDJWi9KbPT1RpHpDTzVWBgb6igyr4txWq6EDdtwJ4nBvcJFwuzdhis6RIdTVpokyor3zvfZRPpPA/wahtUy09SKps97wf8dNiYWId7dbx/2NcEpk8gDGUgE403JbkwyZZOEZojxmQ1h0K6CgjfD8rkcx4kO2DEkomkMaGDZtm8a/84RpoiH2LJ9KRVtiE267hQckFrv2kf+/5qPr2ATKiwDBiB8S7g1sDdWHLb3m37JrlBlPlWYAAAAAQAAAAZtaWR3YXkAAAAMAAAACGt0aW1vZmVlAAAAAGNRZLUAAAAAY1J98gAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQC7xeCqpx6k/LfD0/r/KbupvYyyIs1fwgZyMlNwld5CgBKbwlbO+wDzhRVv0jfOgcuZQqXXOgAO1Z9bViaYb92aRV+yBE5K6XjnT2dIoQZ/c1b0H2eMsEvE6t5bwDC0fpVOXFELa9Z18+3NPWQQbr6igSPsjji1OxV1OpWNPZcV3gSI+Gawazawya+Xh5625CaZ5ww0+I85wpCcsPIAskXu+JH83ihsLCgmN1jLmi+Z3FORtk5PwjwH0xSGlIWIqiy9c7YvXgTfP4IJVSm+7Da5/TYFhyKTEQ/dR5pPDl0w+6+bu4iOouA5kihSlQ8l8lhTnmQTlPJMnir53k+QtmcrAAABDwAAAAdzc2gtcnNhAAABAHR3hspEwFw9SNlz5ADqPQLawucavSuWSUimEVulWazkc8SioaBV6Zk1fPxa186cb2lu6jaresD0eRc0NuxHXsHN7bjgLgg2Hn3ctgX7a+z+Y693jnVsZgfGi/jLsIxg1gTFxQ+qIWKYOR2N1L/o6ZN8Nfy0pQoXYZCXd7MCXw9T8pTB8VEQgVCYu9Fn97DttgSAsejprfIErEVYsrq5dbXKxCADHchl2UzcF0DTvSnoudhDBgWNen1Q331drUsObmqUli14jCBpb8p3/0E7jkXUr36bN6dvmT6bbOvIf7VgzFkoLRf9dmHfs7ZP/uTlQ3pz/3OUphyHEi620XMPbIU= /home/XXX/.ssh/id_rsa
$ go run 001-ssh-test.go 10.19.197.10:22
2022/10/20 08:32:37 Connecting to 10.19.197.10:22
2022/10/20 08:32:39 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
exit status 1
$

Tried today, still see failure:

go: downloading golang.org/x/crypto v0.3.0
go: downloading golang.org/x/sys v0.2.0
go: downloading golang.org/x/term v0.2.0
go: upgraded golang.org/x/crypto v0.1.0 => v0.3.0
go: upgraded golang.org/x/sys v0.1.0 => v0.2.0
2022/11/16 18:44:55 Connecting to 10.19.197.10:22
2022/11/16 18:44:57 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
exit status 1

Can I provide more details to help with the fix of this issue?

Issue is still there:

$ cat 001-ssh-test.sh
#!/bin/bash

go get -u
go mod tidy
go run 001-ssh-test.go 10.19.197.10:22
$ ./001-ssh-test.sh
go: downloading golang.org/x/crypto v0.4.0
go: downloading golang.org/x/sys v0.3.0
go: downloading golang.org/x/term v0.3.0
go: upgraded golang.org/x/crypto v0.3.0 => v0.4.0
go: upgraded golang.org/x/sys v0.2.0 => v0.3.0
2023/01/02 11:40:54 Connecting to 10.19.197.10:22
2023/01/02 11:40:56 ssh: handshake failed: ssh: unable to authenticate,
attempted methods [none publickey], no supported methods remain
exit status 1
$

It seems that this is a regression. I have old binary that works with signed keys ok and here is dependency:

$ strings ossh|grep ssh/client.go
/go/pkg/mod/golang.org/x/crypto@v0.0.0-20210817164053-32db794688a5/ssh/client.go
$

issue is reproducible with golang.org/x/crypto v0.5.0

$ ./001-ssh-test.sh
go: downloading golang.org/x/crypto v0.5.0
go: downloading golang.org/x/sys v0.4.0
go: downloading golang.org/x/term v0.4.0
go: upgraded golang.org/x/crypto v0.4.0 => v0.5.0
go: upgraded golang.org/x/sys v0.3.0 => v0.4.0
2023/01/06 10:01:55 Connecting to 10.19.197.10:22
2023/01/06 10:01:57 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
exit status 1
$

Hi folks, I found list of versions here: https://deps.dev/go/golang.org%2Fx%2Fcrypto/v0.0.0-20151201002508-7b85b097bf75/versions and was able to identify versions where issue was introduced:

$ for x in v0.0.0-20220314234659-1baeb1ce4c0b v0.0.0-20220314234724-5d542ad81a58 v0.0.0-20220315160706-3147a52a75dd; do echo $x && sed -ie "s@\(require golang.org/x/crypto \).*@\1$x@" go.mod && go mod tidy && go run 001-ssh-test.go 10.19.197.10:22; done
v0.0.0-20220314234659-1baeb1ce4c0b
2023/02/06 20:58:16 Connecting to 10.19.197.10:22
2023/02/06 20:58:19 We've got a live session!
v0.0.0-20220314234724-5d542ad81a58
2023/02/06 20:58:19 Connecting to 10.19.197.10:22
2023/02/06 20:58:22 ssh: handshake failed: agent: unsupported algorithm "ssh-rsa"
exit status 1
v0.0.0-20220315160706-3147a52a75dd
2023/02/06 20:58:22 Connecting to 10.19.197.10:22
2023/02/06 20:58:24 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
exit status 1
$ 

I really hope this will help with fixing this issue. Thank you.

href commented

I see the same issue as you, and I was so far unable to get a workaround. To me this seems pretty much broken.

- golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a + golang.org/x/crypto v0.12.0

now i am stuck too

Hey, I just this exact same case. agent.NewClient(conn).Signers() returns nothing.

$ ssh USER@IP
// OK - working as expected
$ echo $SSH_AUTH_SOCK
/private/tmp/com.apple.launchd.REDACTED/Listeners

$ ssh-add -l
The agent has no identities.

$ cat ~/.ssh/config
Host *
    IdentityAgent "~/Library/Group Containers/REDACT.com.1password/t/agent.sock"

Minimal reproducible code snippet adopted from: https://cs.opensource.google/go/x/crypto/+/master:ssh/agent/example_test.go;drc=ac88ee75c92c889b97e05591e9a39b6480c538b3

package main

import (
	"log"
	"net"
	"os"

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

func main() {
	socket := os.Getenv("SSH_AUTH_SOCK")
	conn, err := net.Dial("unix", socket)
	if err != nil {
		log.Fatalf("Failed to open SSH_AUTH_SOCK: %v", err)
	}

	agentClient := agent.NewClient(conn)

	signers, err := agentClient.Signers()
	if err != nil {
		log.Fatal(err)
	}
	
	println("signers", len(signers))
	
	config := &ssh.ClientConfig{
		User: "USER",
		Auth: []ssh.AuthMethod{
			ssh.PublicKeysCallback(agentClient.Signers),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	sshc, err := ssh.Dial("tcp", "IP:22", config)
	if err != nil {
		log.Fatal(err)
	}

	sshc.Close()
}

go run main.go

Resulting with error:

signers 0
2023/09/19 18:01:26 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain

Issue still persist with v0.0.0-20220314234659-1baeb1ce4c0b crypto package 1.

Environment: macOS 13.5.2, M1 Max, go1.21.1

Could someone please confirm if this is a known BUG?


EDIT:

  1. According to debugger, it seems reply does not contain any items: https://github.com/golang/crypto/blob/3f0842a46434ea6f56bf6e684c2b83d90e9cff07/ssh/agent/client.go#L327
NumKeys = 0
Keys = 0
  1. io.ReadFull(c.conn, buf) returns something like NULLNULLNULLSOHVT: https://github.com/golang/crypto/blob/3f0842a46434ea6f56bf6e684c2b83d90e9cff07/ssh/agent/client.go#L358

EDIT2:

OK. Found the issue. $SSH_AUTH_SOCK was set to wrong path: 2

echo $SSH_AUTH_SOCK:

- /private/tmp/com.apple.launchd.REDACT/Listeners
+ SSH_AUTH_SOCK=~/Library/Group\ Containers/REDACT.com.1password/t/agent.sock
$ SSH_AUTH_SOCK=~/Library/Group\ Containers/REDACT.com.1password/t/agent.sock go run main.go
signers 5

$ echo $?
0

Sorry for inconveniences.


Keeping this here in case someone have similar case in the future.

Footnotes

  1. https://github.com/golang/go/issues/54027#issuecomment-1420211355

  2. https://developer.1password.com/docs/ssh/agent/config/

@Dentrax I think you are experiencing a different problem than initially reported.

@kt97679 @href @avron99 can you please try this CL? If it doesn't solve this issue as well, I'll take a closer look. Thank you

after upgrade these two pkgs, It finally works!

from

golang.org/x/crypto v0.0.0-20200208060501-ecb85df21340
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 // indirect

to

golang.org/x/crypto v0.14.0
golang.org/x/sys v0.13.0

después de actualizar estos dos paquetes, ¡finalmente funciona!

De

golang.org/x/crypto v0.0.0-20200208060501-ecb85df21340
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 // indirect

Para

golang.org/x/crypto v0.14.0
golang.org/x/sys v0.13.0

What are the commands to update it?

We're seeing the same issue and have bisected the cause back to the same commit as @kt97679 did above.

@drakkan we tested your linked CL and confirmed it did not fix the error.

We're seeing the same issue and have bisected the cause back to the same commit as @kt97679 did above.

@drakkan we tested your linked CL and confirmed it did not fix the error.

Hello,

the linked CL is included in v0.16.0. I used the test program provided and can't replicate the issue:

$ ssh-add -l
2048 SHA256:d0O4g73+vimS3esODdebewx7KlTw48PR7ZE9G2DbrU0 nicola@nicola-VirtualBox (RSA-CERT)
$ go run main.go 192.168.1.231:22
2023/12/08 10:28:48 Connecting to 192.168.1.231:22
2023/12/08 10:28:48 We've got a live session!

here is the go.mod

module 54027

go 1.21.5

require golang.org/x/crypto v0.16.0

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

If I set golang.org/x/crypto v0.15.0 in go.mod I can replicate the issue

$ go run main.go 192.168.1.231:22
2023/12/08 10:30:36 Connecting to 192.168.1.231:22
2023/12/08 10:30:36 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
exit status 1

so it seems fixed.

Please confirm that you are testing with x/crypto v0.16.0 and provide additional info if the issue is not fixed for you. Thank you

@drakkan thanks for the follow up. We've done more digging and uncovered the root cause. I've opened an issue with more details in #64785. The tl;dr is the remote server we're interacting with is not compliant with the RFC. The reason why we're able to bisect this error message back to the same commit as others is that the commit introduced the ext-info-c handling. With that new flow, we triggered the bad server behaviour based on the server-sig-algs response from the ext-info packet. As noted in my linked issue, OpenSSH handles this differently and without error. Commenting this here for others in case they encounter the same error, but otherwise, our issue is separate from the other comments above.

Its fixed the issue

después de actualizar estos dos paquetes, ¡finalmente funciona!
De

golang.org/x/crypto v0.0.0-20200208060501-ecb85df21340
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 // indirect

Para

golang.org/x/crypto v0.14.0
golang.org/x/sys v0.13.0

What are the commands to update it?

please use the below commands:

    go get golang.org/x/sys 
    go get golang.org/x/crypt
    go mod tidy

if possible update go version to latest

Change https://go.dev/cl/573360 mentions this issue: ssh: validate key type in SSH_MSG_USERAUTH_PK_OK response