go x/crypto/ssh: connection.session.Close() 返回一个EOF作为错误而不是nil,

8hhllhi2  于 4个月前  发布在  Go
关注(0)|答案(7)|浏览(47)

你正在使用的Go版本是什么( go version )?

$ go version
go version go1.14.1 darwin/amd64
$

这个问题在最新版本的发布中是否会重现?
是的,我相信我正在使用最新的稳定版本。

你正在使用什么操作系统和处理器架构( go env )?
go env 输出

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/my_username/Library/Caches/go-build"
GOENV="/Users/my_username/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/my_username/Learn/go_learn"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/my_username/Learn/go_learn/src/my_stuff/ssh_test/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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/17/vmjmghsj28d4lzrx7mqshr9r0000gp/T/go-build681325874=/tmp/go-build -gno-record-gcc-switches -fno-common"
$

你做了什么?
我的程序连接到一个ssh服务器(在这个例子中只是我的笔记本电脑),发出一个ssh命令,关闭SSH会话和连接:

package main

import (
    "bytes"
    "fmt"
    "strings"

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

func main() {
    sshConfig := &ssh.ClientConfig{
        User: “my_username”,
        Auth: []ssh.AuthMethod{
            ssh.Password(“my password”),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    connection, err := ssh.Dial("tcp", "localhost:22", sshConfig)
    if err != nil {
        fmt.Printf("Failed to dial: %s\n", err)
        return
    }

    defer func() {
        if err := connection.Close(); err != nil {
            fmt.Println("Received an error closing the ssh connection: ", err)
        } else {
            fmt.Println("No error found closing ssh connection")
        }
    }()

    session, err := connection.NewSession()
    if err != nil {
        fmt.Printf("Failed to create session: %s\n", err)
        return
    }

    defer func() {
        if err := session.Close(); err != nil {
            fmt.Println("Received an error closing the ssh session: ", err)
        } else {
            fmt.Println("No error found closing ssh session")
        }
    }()
    fmt.Println("created session")
    var stdOut bytes.Buffer
    var stdErr bytes.Buffer

    session.Stdout = &stdOut
    session.Stderr = &stdErr
    err = session.Run("pwd")
    fmt.Println("Executed command")

    fmt.Println("Command stdOut is:", strings.TrimRight(stdOut.String(), "\n"), " --- stdError is:", strings.TrimRight(stdErr.String(), "\n"))
}

你期望看到什么?
在session.close()中,我期望看到'nil'作为输出,而不是任何错误。

你看到了什么?
我在session.Close()中得到了EOF错误。在论坛上查看了其他已解决的问题( #16194 )后,似乎在Run()结束时得到EOF是合理的。然而,对于Close()来说,将其作为错误返回而不是返回nil似乎是奇怪的。
可能是我没有正确处理缓冲区管理、执行命令或关闭它。但是上面粘贴的代码来自在线示例,看起来像是工作模式。
EOF在close时是可以处理的,但要非常清楚和精确,我认为Close()应该返回nil。EOF似乎也不像是一个错误。

zvms9eto

zvms9eto1#

你好,
这似乎是一个问题,而不是关于实现中bug的报告(至少目前还没有)。
与许多项目不同,Go项目不使用GitHub Issues进行一般讨论或提问。GitHub Issues仅用于跟踪bug和proposals
提问请参考:

请在上述论坛之一提问。
(摘自https://golang.org/wiki/Questions)

btxsgosb

btxsgosb2#

你好,
我在stackoverflow上提出了一个问题:https://stackoverflow.com/questions/60879023/getting-eof-as-error-in-golang-ssh-session-close
然而,这被认为是一个bug。

efzxgjgh

efzxgjgh3#

听起来不错。重新开放。
@FiloSottile@hanwen

ia2d9nvy

ia2d9nvy4#

看起来这是在运行OpenSSH时发生的情况。你能提供一个Go SSH针对自身的重现案例吗?
我之所以这么问,是因为可能有一些配置在SSH服务器上,如果会话结束,就会断开连接。

6qqygrtg

6qqygrtg5#

有没有一个Go SSH服务器的示例,我可以尝试运行或者它可能对你进行调试有帮助?我从来没有运行过SSH服务器,通常针对另一个我可以ssh到的主机进行测试(我猜通常运行OpenSSH)。
我尝试了这个 https://gist.github.com/jpillora/b480fde82bff51a06238 ,但它在我的电脑上打开bash会话时遇到了麻烦。不确定是否是权限问题或其他问题。

tquggr8v

tquggr8v6#

我遇到了同样的问题
go版本:go1.16.6 linux/amd64

a0x5cqrl

a0x5cqrl7#

我注意到*ssh.channel数据类型的Close方法也存在类似的问题(返回了无意义的io.EOF)。
可能的原因是从channel.Close到channel.sendMessage到channel.writePacket,如果已经发生了关闭,它会返回EOF,这表明应用程序中存在错误,但在这种情况下,EOF是错误的错误。
https://cs.opensource.google/go/x/crypto/+/32db7946:ssh/channel.go;l=208;drc=32db794688a5a24a23a43f2a984cecd5b3d8da58
[更新:经过进一步调查,sentClose字段为true,因为ssh mux循环从对等方接收到了一个关闭数据包,并通过发送一个关闭数据包进行处理,然后调用ch.close,设置sentClose。应用程序只在OpenChannel的结果上调用了一次Close。]

相关问题