2015-06-09 03:00
浏览 110

golang goroutine使用SSHAgent身份验证无法正常工作,并引发一些意外情况

I am writing a little tool for executing commands in parallel on many different hosts. All the hosts could login with a same private key. So, I want to use SSHAgent to get auth to login. When I use it for a single host, it works well. But when I use it in many goroutines, it doesn't work. I am very confused, is there somebody can help me? Thanks very much. The code used sshagent are as below:

func ExcuteRemote(uname,host,cmd string) (bool,error) {
        ip,err := GetIp(host)
        if err != nil {
                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")
                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

        return true,nil

And the code used channel are as below :

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(host + " failed")
        ch <- 1
        return nil

in main:

if *list != "" {
       hosts,err := ReadLine(*list)
       if nil != err {
       chs := make([]chan int, len(hosts))
       for index := 0; index < len(hosts); index++ {
               chs[index] = make(chan int)
               go testchannel(chs[index],uname,hosts[index],*cmd)
       for _, ch := range(chs) {

the panic like this :

panic: unreachable

goroutine 5 [running]:*client).Sign(0xc20801e440, 0x7f053381a9f8, 0xc208094100, 0xc208121b00, 0x201, 0x240, 0xc2080a6009, 0x0, 0x0)
        /usr/local/gosrc/src/ +0x472*agentKeyringSigner).Sign(0xc20801e560, 0x7f053380fb38, 0xc20803c2d0, 0xc208121b00, 0x201, 0x240, 0xe, 0x0, 0x0)
        /usr/local/gosrc/src/ +0x71, 0xc2080a4040, 0x14, 0x20, 0xc20802a954, 0x4, 0x7f053381a998, 0xc2080ca000, 0x7f053380fb38, 0xc20803c2d0, ...)
        /usr/local/gosrc/src/ +0x5ee*connection).clientAuthenticate(0xc2080b8080, 0xc2080b2000, 0x0, 0x0)
        /usr/local/gosrc/src/ +0x4e3*connection).clientHandshake(0xc2080b8080, 0xc20801e4c0, 0x11, 0xc2080b2000, 0x0, 0x0)
        /usr/local/gosrc/src/ +0x62e, 0xc2080aa000, 0xc20801e4c0, 0x11, 0xc2080420a0, 0x0, 0x0, 0x0, 0x41be71, 0x0, ...)
        /usr/local/gosrc/src/ +0x140, 0x3, 0xc20801e4c0, 0x11, 0xc2080420a0, 0x11, 0x0, 0x0)
        /usr/local/gosrc/src/ +0xf9
main.ExcuteRemote(0xc20802a954, 0x4, 0xc20802a9a0, 0xe, 0x7fffa171b7fd, 0x6, 0xc200000000, 0x0, 0x0)
        /home/myname/easyssh/r.go:126 +0x83f
main.testchannel(0xc208036120, 0xc20802a954, 0x4, 0xc20802a9a0, 0xe, 0x7fffa171b7fd, 0x6, 0x0, 0x0)
        /home/myname/easyssh/r.go:217 +0x8c
created by main.main
        /home/myname/gocode/easyssh/r.go:262 +0x638

1条回答 默认 最新

相关推荐 更多相似问题