Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: golang.org/x/crypto/ssh panic error #46544

Closed
SLusenti opened this issue Jun 3, 2021 · 4 comments
Closed

net: golang.org/x/crypto/ssh panic error #46544

SLusenti opened this issue Jun 3, 2021 · 4 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@SLusenti
Copy link

SLusenti commented Jun 3, 2021

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

> go version
go version go1.16.4 linux/amd64

Does this issue reproduce with the latest release?

yes, currently I use the latest release

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

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

What did you do?

I create 3 project
the main project is the starting point of the program with a cli interface. The main purpose of this project is to parse command line args, load the plugin, and run a function inside the plugin by passing all the parsed args.

the second project is just a lib that wraps the ssh client and provide a easy way to run ssh commands.

the third project is the plugin that use the ssh lib.
it just call the GetSshClient function defined in the above lib and run some commands by using the SshRunCommand function defined in the same lib.
it has two functions:

  • doSsh : the entry-point and it spawn a gorutine for each passed hostname
  • SshWorker: the function of the gorutine that create the ssh client and exec some ssh commands.

all three projects are located in a different git repository
the main cli and the lib ones have their own go.mod file.
the lib is loaded the main cli project with the go get command
the plugin project is loaded in the main cli project as a git submodule and it doesn't have a go.mod file.

I create a plugin_test.go file to test the plugin "entry-point" function and all works great!
but when i build with the command go build -buildmode=plugin -o build/ssh.so the plugin and use it with the cli compiled command I get the strange error reported below (I run it by passing only one hostname in the cli command).

the code below rappresent the functions defined in the lib

func GetSshClient(host string, user string, key string) (*ssh.Client, error) {
	sshConf, err := getSshConfig(user, key)
	if err != nil {
		return nil, err
	}

	connection, err := ssh.Dial("tcp", host, sshConf)
	if err != nil {
		return nil, err
	}

	return connection, nil
}

//create a ssh client configuration with kay auth
func getSshConfig(user string, keyfile string) (*ssh.ClientConfig, error) {
	buffer, err := ioutil.ReadFile(keyfile)
	if err != nil {
		return nil, err
	}

	key, err := ssh.ParsePrivateKey(buffer)
	if err != nil {
		return nil, err
	}

	sshConfig := &ssh.ClientConfig{
		User:            user,
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(key),
		},
	}
	return sshConfig, nil
}

//run command on provided client and return the stdout
func SshRunCommand(client *ssh.Client, command string) (string, error) {
	session, err := client.NewSession()
	if err != nil {
		return "", err
	}
	defer session.Close()

	out, err := session.Output(command)
	if err != nil {
		return "", err
	}
	outs := string(out)
	return outs, nil
}

What did you expect to see?

no error

What did you see instead?

here the mentioned error

panic: interface conversion: *net.TCPConn is not io.Closer: missing method Close

goroutine 21 [running]:
golang.org/x/crypto/ssh.newTransport(0x7f7e11701e58, 0xc0001db410, 0x7a93c0, 0xc0001145d0, 0xc0001db401, 0xc00001f4c0)
       xxx/vendor/golang.org/x/crypto/ssh/transport.go:210 +0x2a8
golang.org/x/crypto/ssh.(*connection).clientHandshake(0xc000074c80, 0x7ffeb5f890c8, 0xc, 0xc000206410, 0x0, 0x0)
        xxx/vendor/golang.org/x/crypto/ssh/client.go:106 +0x1a5
golang.org/x/crypto/ssh.NewClientConn(0x7f7e1149b588, 0xc0001db410, 0x7ffeb5f890c8, 0xc, 0xc0000be000, 0x7f7e1149b588, 0xc0001db410, 0x0, 0x0, 0x7f7e1064e1c0, ...)
       xxxl/vendor/golang.org/x/crypto/ssh/client.go:83 +0x126
golang.org/x/crypto/ssh.Dial(0x7f7e1057e1c8, 0x3, 0x7ffeb5f890c8, 0xc, 0xc0000be000, 0x0, 0x0, 0x0)
       xxx/vendor/golang.org/x/crypto/ssh/client.go:177 +0xb8
xxx/lib.GetSshClient(0x7ffeb5f890c8, 0xc, 0xc000021c58, 0x8, 0xc00015ed80, 0x1a, 0x24, 0x0, 0x0)
        xxx/vendor/xxx/lib/ssh.go:20 +0x9c
xxx/plugin/juju.(*SshPkg).SshWorker(0xc00019cfa0, 0x7ffeb5f890c8, 0xc, 0xc0001f00c0)
       xxx/plugin/ssh/ssh_exec.go:48 +0x359
created by xxx/plugin/ssh.(*SshPkg).doSsh
       xxx/plugin/ssh/ssh_exec.go:100 +0xe5
@SLusenti SLusenti changed the title net: net: golang.org/x/crypto/ssh panic error Jun 3, 2021
@seankhliao
Copy link
Member

Can you provide a minimal reproducer for your setup?

@seankhliao seankhliao added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels Jun 3, 2021
@davecheney
Copy link
Contributor

This is a bug in the plugin package, it is unrelated to the ssh package. Somehow the type definition for *net.TCPConn has lost its Close method or is inconsistent between the plugin and the main program. I’d suggest bisecting or at least building with earlier versions of Go to try to narrow down the problem.

/cc @thanm @cherrymui

@SLusenti
Copy link
Author

SLusenti commented Jun 4, 2021

hi all,
I've fix it by removing all golang reference on the system and reinstall it again

@davecheney
Copy link
Contributor

yeah, that could explain it. the plugin package requires that the compiler that built the main package and builds each plugin must match exactly.

I’m going to close this as solved for the moment. please comment if the issue occurs again.

@golang golang locked and limited conversation to collaborators Jun 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

4 participants