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.

Tags:

Ssh

Go