英文:
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() + " " + base64.StdEncoding.EncodeToString(k.Marshal()) // e.g. "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY...."
}
func trustedHostKeyCallback(trustedKey string) ssh.HostKeyCallback {
if trustedKey == "" {
return func(_ string, _ net.Addr, k ssh.PublicKey) error {
log.Printf("WARNING: SSH-key verification is *NOT* in effect: to fix, add this 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-key verification: expected %q but got %q", trustedKey, ks)
}
return nil
}
}
And to use:
// where `conf` is the main app config
sc := &ssh.ClientConfig{
User: conf.Username,
Auth: []ssh.AuthMethod{ssh.Password(conf.Password)},
HostKeyCallback: trustedHostKeyCallback(conf.HostKey), // <- 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论