GoLang ssh : Getting "Must specify HosKeyCallback" error despite setting it to nil
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()
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.