SSH握手抱怨缺少主机密钥 [英] SSH Handshake complains about missing host key

查看:134
本文介绍了SSH握手抱怨缺少主机密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试连接到远程主机并检查文件是否存在在此阶段,我仅尝试连接,但出现错误:

I'm trying to connect to a remote host and check if a file exist At this stage I'm trying just to connect but I'm getting an error:

2017/08/01 18:16:39 unable to connect: ssh: handshake failed: ssh: required host key was nil

我试图找出其他人是否有我的问题,但我只是找不到.

I've tried to find out if others had issues as mine but I just couldn't find.

我知道我需要在此过程中以某种方式检查knowns_hosts,但我只是想不通...

I understand that I need to check the knowns_hosts somehow in the process but I just can't figure out how...

    var hostKey ssh.PublicKey
    // A public key may be used to authenticate against the remote
    // server by using an unencrypted PEM-encoded private key file.
    //
    // If you have an encrypted private key, the crypto/x509 package
    // can be used to decrypt it.
    key, err := ioutil.ReadFile("/home/user/.ssh/id_rsa")
    if err != nil {
        log.Fatalf("unable to read private key: %v", err)
    }

    // Create the Signer for this private key.
    signer, err := ssh.ParsePrivateKey(key)
    if err != nil {
        log.Fatalf("unable to parse private key: %v", err)
    }

    config := &ssh.ClientConfig{
        User: "user",
        Auth: []ssh.AuthMethod{
            // Use the PublicKeys method for remote authentication.
            ssh.PublicKeys(signer),
        },
        HostKeyCallback: ssh.FixedHostKey(hostKey),
    }

    // Connect to the remote server and perform the SSH handshake.
    client, err := ssh.Dial("tcp", "host.com:22", config)
    if err != nil {
        log.Fatalf("unable to connect: %v", err)
    }
    defer client.Close()
}

推荐答案

以下是您要查找的内容:

Here what you are looking for:

func getHostKey(host string) (ssh.PublicKey, error) {
    file, err := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts"))
    if err != nil {
        return nil, err
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    var hostKey ssh.PublicKey
    for scanner.Scan() {
        fields := strings.Split(scanner.Text(), " ")
        if len(fields) != 3 {
            continue
        }
        if strings.Contains(fields[0], host) {
            var err error
            hostKey, _, _, _, err = ssh.ParseAuthorizedKey(scanner.Bytes())
            if err != nil {
                return nil, errors.New(fmt.Sprintf("error parsing %q: %v", fields[2], err))
            }
            break
        }
    }

    if hostKey == nil {
        return nil, errors.New(fmt.Sprintf("no hostkey for %s", host))
    }
    return hostKey, nil
}

然后将您的hostKey定义行替换为

Then replace your hostKey definition line with

hostKey, err := getHostKey("host.com")
if err != nil {
    log.Fatal(err)
}

有关此主题的更多信息:

For more information on the subject:

  • official sample where I took parts of the code from
  • why a hostKey is necessary now

另外,请查看以下有关 golang.org/x/crypto/ssh/knownhosts 软件包的 Anton 答案.

Also check out Anton's answer below about the golang.org/x/crypto/ssh/knownhosts package.

这篇关于SSH握手抱怨缺少主机密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆