为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
白板的微信 2021-10-11 18:49:22
我正在编写一个小工具,用于在许多不同的主机上并行执行命令。所有主机都可以使用相同的私钥登录。所以,我想使用 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} 
查看完整描述

1 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

我自己解决了这个问题。据我了解,panic 是多个 goroutine 想使用 sshagent 连接本地服务器造成的。现在,我只设置一次连接,并保持连接直到程序结束。函数 main 中的代码:


    //get config

    var config *ssh.ClientConfig

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

            config = GetConfig(uname,sshAgent)

            defer sshAgent.Close()

    } else {

            panic(err)

    }

当我需要 goroutine 中的配置时,我将配置作为参数传递给它,它运行良好!


我在 goroutine 中的功能如下:


func RunInChannel(ch chan int, host,cmd string,config *ssh.ClientConfig) error{

    result,_ := ExcuteRemote(host,cmd,config)

    if result {

        fmt.Println("\n" + host + "\t\tok\n")

    } else {

        ret,err := ExcuteRemote(host,cmd,config)

        if ret {

            fmt.Println("\n" + host + "\t\tok\n")

        } else {

            fmt.Println(err)

            fmt.Println("\n" + host + "\t\tfailed\n")

        }

    }

    ch <- 1

    return nil

}


查看完整回答
反对 回复 2021-10-11
  • 1 回答
  • 0 关注
  • 240 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信