golang goroutine 使用 SSHAgent 身份验证效果不佳并引发一些意外的恐慌

我正在编写一个小工具,用于在许多不同的主机上并行执行命令。所有主机都可以使用相同的私钥登录。所以,我想使用 SSHAgent 来获得登录权限。当我将它用于单个主机时,它运行良好。但是当我在很多 goroutine 中使用它时,它不起作用。我很困惑,有人可以帮助我吗?非常感谢。sshagent 使用的代码如下:


func ExcuteRemote(uname,host,cmd string) (bool,error) {

        ip,err := GetIp(host)

        if err != nil {

                fmt.Println(err)

                return false,err

        }


        auths := []ssh.AuthMethod{}

        if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {

                fmt.Println("get sock")

                auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers))

                defer sshAgent.Close()

        }


        config := &ssh.ClientConfig{

                User: uname,

                Auth: auths,

        }

        fmt.Println("after config")


        client, err := ssh.Dial("tcp", ip+":"+"22", config)

        if err != nil {

                fmt.Println("something wrong when dial")

                fmt.Println(err)

                return false,err

        }


        session, err := client.NewSession()

        if err != nil {

                return false,err

        }

        defer session.Close()


        var b bytes.Buffer

        session.Stdout = &b

        err = session.Run(cmd)

        if err != nil {

            return false,err

        }


        fmt.Println(b.String())

        return true,nil

}

使用的代码通道如下:


func testchannel(ch chan int, uname,host,cmd string) error{

        result,err := ExcuteRemote(uname,host,cmd)

        if result {

                fmt.Println(host + " ok")

        } else {

                fmt.Println(err)

                fmt.Println(host + " failed")

        }

        ch <- 1

        return nil



白板的微信
浏览 241回答 1
1回答

翻阅古今

我自己解决了这个问题。据我了解,panic 是多个 goroutine 想使用 sshagent 连接本地服务器造成的。现在,我只设置一次连接,并保持连接直到程序结束。函数 main 中的代码:&nbsp; &nbsp; //get config&nbsp; &nbsp; var config *ssh.ClientConfig&nbsp; &nbsp; if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; config = GetConfig(uname,sshAgent)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer sshAgent.Close()&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }当我需要 goroutine 中的配置时,我将配置作为参数传递给它,它运行良好!我在 goroutine 中的功能如下:func RunInChannel(ch chan int, host,cmd string,config *ssh.ClientConfig) error{&nbsp; &nbsp; result,_ := ExcuteRemote(host,cmd,config)&nbsp; &nbsp; if result {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("\n" + host + "\t\tok\n")&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; ret,err := ExcuteRemote(host,cmd,config)&nbsp; &nbsp; &nbsp; &nbsp; if ret {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("\n" + host + "\t\tok\n")&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("\n" + host + "\t\tfailed\n")&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; ch <- 1&nbsp; &nbsp; return nil}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go