我正在尝试连接到远程主机,并检查文件是否存在。在此阶段,我仅尝试连接,但是出现错误:
2017/08/01 18:16:39 unable to connect: ssh: handshake failed: ssh: required host key was nil
我试图找出其他人是否有像我一样的问题,但我却找不到。
我知道我需要在此过程中以某种方式检查knowns_hosts,但我只是想不通如何…
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() }
您在这里寻找的是:
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定义行替换为
hostKey, err := getHostKey("host.com") if err != nil { log.Fatal(err) }
有关此主题的更多信息:
编辑:还请查看Anton有关golang.org/x/crypto/ssh/knownhosts包装的以下答案。
Anton
golang.org/x/crypto/ssh/knownhosts