我有一个需要,须要实现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}