golang 实现ssh公钥登录

禹鼎侯
English

我有一个需求,需要实现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
}
阅读 511

OLAP数据库开发。跨平台数据采集。

127 声望
124 粉丝
0 条评论
你知道吗?

OLAP数据库开发。跨平台数据采集。

127 声望
124 粉丝
宣传栏