我有一个需要,须要实现ssh应用公钥免密登录。在网上查了大量的材料,竟然没有找到对于这方面的实现,所以记录一下。
网上有应用SSH_AUTH_SOCK环境变量的办法实现的,然而一来这个SSH_AUTH_SOCK环境变量须要借助ssh-agent命令去生成,二来那段代码不明不白的,基本不能运行,所以就间接放弃了。
那段代码如下:

func SSHClient(hostport string, username string) (*ssh.Client, error) {    sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))    if err != nil {        logrus.Infof("error login,details: %s",err.Error())        return nil,err    }    agent := agent.NewClient(sock)   //这个agent.NewClient是啥?不清不楚的,无奈运行    signers, err := agent.Signers()    if err != nil {        logrus.Infof("error login,details: %s",err.Error())        return nil,err    }    auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)}    cfg := &ssh.ClientConfig{        User: username,        Auth: auths,        HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {            return nil        },    }    cfg.SetDefaults()    logrus.Infof("tcp dial to %s",hostport)    client, err := ssh.Dial("tcp", hostport, cfg)    if err != nil {        logrus.Infof("error login,details: %s",err.Error())        return nil,err    }    return client, nil}

找了良久,终于在官网的example_test.go的代码里找到了能够参考的中央。
以下是我的实现,亲测可用。欢送大家探讨:

func SSHConnect(user, host string, port int) (*ssh.Client, error) {    var (        addr         string        clientConfig *ssh.ClientConfig        client       *ssh.Client        err          error    )             homePath, err := os.UserHomeDir()    if err != nil {        return nil, err    }    key, err := ioutil.ReadFile(path.Join(homePath, ".ssh", "id_rsa"))    if err != nil {        return nil, err    }    signer, err := ssh.ParsePrivateKey(key)    if err != nil {        return nil, err    }        clientConfig = &ssh.ClientConfig{        User: user,        Auth: []ssh.AuthMethod{            ssh.PublicKeys(signer),        },        Timeout:         30 * time.Second,        HostKeyCallback: ssh.InsecureIgnoreHostKey(),    }    // connet to ssh    addr = fmt.Sprintf("%s:%d", host, port)    if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {        err = errors.Wrapf(err, "")        return nil, err    }    return client, nil}