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

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

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

  1. config := &ssh.ClientConfig{
  2. User: user,
  3. HostKeyCallback: nil,
  4. Auth: []ssh.AuthMethod{
  5. publicKey,
  6. },
  7. }

But I keep getting this error.

  1. Failed to dial: ssh: must specify HostKeyCallback

How do I solve this ?

答案1

得分: 25

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

如果你想允许任何主机:

  1. 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:

  1. 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 {

  1. if trustedKey == "" {
  2. return func(_ string, _ net.Addr, k ssh.PublicKey) error {
  3. log.Printf("警告:SSH密钥验证*未生效*:要修复,请添加此trustedKey:%q", keyString(k))
  4. return nil
  5. }
  6. }
  7. return func(_ string, _ net.Addr, k ssh.PublicKey) error {
  8. ks := keyString(k)
  9. if trustedKey != ks {
  10. return fmt.Errorf("SSH密钥验证:期望的密钥为%q,但得到的密钥为%q", trustedKey, ks)
  11. }
  12. return nil
  13. }

}

使用方法:

// 其中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:

  1. // create human-readable SSH-key strings
  2. func keyString(k ssh.PublicKey) string {
  3. return k.Type() + &quot; &quot; + base64.StdEncoding.EncodeToString(k.Marshal()) // e.g. &quot;ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY....&quot;
  4. }
  5. func trustedHostKeyCallback(trustedKey string) ssh.HostKeyCallback {
  6. if trustedKey == &quot;&quot; {
  7. return func(_ string, _ net.Addr, k ssh.PublicKey) error {
  8. log.Printf(&quot;WARNING: SSH-key verification is *NOT* in effect: to fix, add this trustedKey: %q&quot;, keyString(k))
  9. return nil
  10. }
  11. }
  12. return func(_ string, _ net.Addr, k ssh.PublicKey) error {
  13. ks := keyString(k)
  14. if trustedKey != ks {
  15. return fmt.Errorf(&quot;SSH-key verification: expected %q but got %q&quot;, trustedKey, ks)
  16. }
  17. return nil
  18. }
  19. }

And to use:

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

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:

确定