GoLang ssh:尽管将其设置为nil,仍然出现“必须指定HosKeyCallback”错误

huangapple go评论140阅读模式
英文:

GoLang ssh : Getting "Must specify HosKeyCallback" error despite setting it to nil

问题

我正在尝试使用GoLang连接到远程服务器。在客户端配置中,除了用户和密码之外,我将HostKeyCallback设置为nil,以便接受任何主机。

config := &ssh.ClientConfig{
User: user,
HostKeyCallback: nil,
Auth: []ssh.AuthMethod{
publicKey,
},
}

但是我一直收到这个错误。

Failed to dial: ssh: must specify HostKeyCallback

我该如何解决这个问题?

英文:

I am trying to connect to a remote server using GoLang. In the client configuration, apart from user and password, I set HostKeyCallback to nil so that it accepts every host

config := &ssh.ClientConfig{

	    User: user,

	    HostKeyCallback: nil,

	    Auth: []ssh.AuthMethod{
		    
		publicKey,
	},
}

But I keep getting this error.

Failed to dial: ssh: must specify HostKeyCallback

How do I solve this ?

答案1

得分: 25

HostKeyCallback的nil行为已更改:https://github.com/golang/go/issues/19767

如果你想允许任何主机:

HostKeyCallback: ssh.InsecureIgnoreHostKey()
英文:

The behavior of nil for HostKeyCallback was changed: https://github.com/golang/go/issues/19767

If you want to allow any host:

HostKeyCallback: ssh.InsecureIgnoreHostKey()

答案2

得分: 9

请注意,ssh.InsecureIgnoreHostKey附带的警告:

> ...不应在生产代码中使用。

因此,考虑强制执行SSH密钥验证。实际上,实现起来并不那么困难:

// 创建可读的SSH密钥字符串
func keyString(k ssh.PublicKey) string {
return k.Type() + " " + base64.StdEncoding.EncodeToString(k.Marshal()) // 例如:"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY...."
}

func trustedHostKeyCallback(trustedKey string) ssh.HostKeyCallback {

if trustedKey == "" {
    return func(_ string, _ net.Addr, k ssh.PublicKey) error {
        log.Printf("警告:SSH密钥验证*未生效*:要修复,请添加此trustedKey:%q", keyString(k))
        return nil
    }
}

return func(_ string, _ net.Addr, k ssh.PublicKey) error {
    ks := keyString(k)
    if trustedKey != ks {
        return fmt.Errorf("SSH密钥验证:期望的密钥为%q,但得到的密钥为%q", trustedKey, ks)
    }

    return nil
}

}

使用方法:

// 其中conf是主应用程序配置
sc := &ssh.ClientConfig{
User: conf.Username,
Auth: []ssh.AuthMethod{ssh.Password(conf.Password)},
HostKeyCallback: trustedHostKeyCallback(conf.HostKey), // <- 服务器密钥放在这里
Timeout: conf.Timeout,
}

如果conf.HostKey为空 - 它仍然可以工作 - 但会记录一个警告,其中包含要填写的密钥字符串以启用SSH密钥验证。

英文:

Please heed the warning that comes with ssh.InsecureIgnoreHostKey:

> ... It should not be used for production code.

So instead, consider enforcing SSH-key verification. It's actually not that difficult to implement:

// create human-readable SSH-key strings
func keyString(k ssh.PublicKey) string {
	return k.Type() + &quot; &quot; + base64.StdEncoding.EncodeToString(k.Marshal()) // e.g. &quot;ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY....&quot;
}


func trustedHostKeyCallback(trustedKey string) ssh.HostKeyCallback {

	if trustedKey == &quot;&quot; {
		return func(_ string, _ net.Addr, k ssh.PublicKey) error {
			log.Printf(&quot;WARNING: SSH-key verification is *NOT* in effect: to fix, add this trustedKey: %q&quot;, keyString(k))
			return nil
		}
	}

	return func(_ string, _ net.Addr, k ssh.PublicKey) error {
		ks := keyString(k)
		if trustedKey != ks {
			return fmt.Errorf(&quot;SSH-key verification: expected %q but got %q&quot;, trustedKey, ks)
		}

		return nil
	}
}

And to use:

// where `conf` is the main app config
sc := &amp;ssh.ClientConfig{
	User:            conf.Username,
	Auth:            []ssh.AuthMethod{ssh.Password(conf.Password)},
	HostKeyCallback: trustedHostKeyCallback(conf.HostKey), // &lt;- server-key goes here
	Timeout:         conf.Timeout,
}

if conf.HostKey is blank - it will still work - but will log a warning with the key-string to fill in to enable SSH-key verification.

huangapple
  • 本文由 发表于 2017年5月31日 02:12:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/44269142.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定