Go SSH握手抱怨缺少主机密钥
我正在尝试连接到远程主机并检查文件是否存在 在这个阶段,我只是尝试连接,但我遇到了一个错误:Go SSH握手抱怨缺少主机密钥,go,ssh,Go,Ssh,我正在尝试连接到远程主机并检查文件是否存在 在这个阶段,我只是尝试连接,但我遇到了一个错误: 2017/08/01 18:16:39 unable to connect: ssh: handshake failed: ssh: required host key was nil 我试着找出别人是否有我这样的问题,但我就是找不到 我知道在这个过程中我需要检查knowns_主机,但我就是不知道如何 var hostKey ssh.PublicKey // A public key
2017/08/01 18:16:39 unable to connect: ssh: handshake failed: ssh: required host key was nil
我试着找出别人是否有我这样的问题,但我就是找不到
我知道在这个过程中我需要检查knowns_主机,但我就是不知道如何
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, err := getHostKey("host.com")
if err != nil {
log.Fatal(err)
}
有关此主题的更多信息:
- 我从中提取了部分代码
还可以查看下面Anton关于
golang.org/x/crypto/ssh/knownhosts
包的回答。我建议使用knownhosts子包
import knownhosts "golang.org/x/crypto/ssh/knownhosts"
...
hostKeyCallback, err := knownhosts.New("/Users/user/.ssh/known_hosts")
if err != nil {
log.Fatal(err)
}
...
config := &ssh.ClientConfig{
User: "user",
Auth: []ssh.AuthMethod{
// Use the PublicKeys method for remote authentication.
ssh.PublicKeys(signer),
},
HostKeyCallback: hostKeyCallback,
}
这样您就可以避免自己解析已知的\u主机
hth,您的主机密钥在ssh上为空。FixedHostKey(hostKey)我认为hostKey=signer.PublicKey()可能会有所帮助。@BayRinat有一个进展,现在我得到一个不匹配的“2017/08/01 19:15:47无法连接:ssh:握手失败:ssh:主机密钥不匹配”虽然我100%确定我的密钥是正确的,因为我可以通过TerminalTransks使用相同的密钥进行SSH,现在它抛出了一个错误,我的主机名没有hostkey我已经删除了已知的\u主机文件,然后在我的终端上运行了一个SSH到服务器并确认了指纹-所以它是我已知的\u主机中目前唯一的服务器,它仍然抱怨…我对编码非常陌生,所以调试可以有不同的解释:)我做了什么正在读取文件,然后使用读卡器将其打印出来(只是为了确保它包含指纹[它确实存在]),接下来,我在for scanner.Scan()中添加了几个fmt.Println打印出字段和字段的len,发现字段包含指纹,len是3。我已经更改了代码,使用ssh.unsecureIgnoreHostKey,现在我可以连接了,但是我们都知道不建议这样做。当然比解析我们自己要好。