Documentation ¶
Overview ¶
Package knownhosts is a thin wrapper around golang.org/x/crypto/ssh/knownhosts, adding the ability to obtain the list of host key algorithms for a known host.
Index ¶
- func HostKeyAlgorithms(cb ssh.HostKeyCallback, hostWithPort string) []string
- func IsHostKeyChanged(err error) bool
- func IsHostUnknown(err error) bool
- func Line(addresses []string, key ssh.PublicKey) string
- func Normalize(address string) string
- func WriteKnownHost(w io.Writer, hostname string, remote net.Addr, key ssh.PublicKey) error
- type HostKeyCallback
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HostKeyAlgorithms ¶
func HostKeyAlgorithms(cb ssh.HostKeyCallback, hostWithPort string) []string
HostKeyAlgorithms is a convenience function for performing host key algorithm lookups on an ssh.HostKeyCallback directly. It is intended for use in code paths that stay with the New method of golang.org/x/crypto/ssh/knownhosts rather than this package's New method.
func IsHostKeyChanged ¶ added in v1.1.0
IsHostKeyChanged returns a boolean indicating whether the error indicates the host key has changed. It is intended to be called on the error returned from invoking a HostKeyCallback to check whether an SSH host is known.
func IsHostUnknown ¶ added in v1.1.0
IsHostUnknown returns a boolean indicating whether the error represents an unknown host. It is intended to be called on the error returned from invoking a HostKeyCallback to check whether an SSH host is known.
func Line ¶ added in v1.2.0
Line returns a line to append to the known_hosts files. This implementation uses the local patched implementation of Normalize in order to solve https://github.com/golang/go/issues/53463.
func Normalize ¶ added in v1.2.0
Normalize normalizes an address into the form used in known_hosts. This implementation includes a fix for https://github.com/golang/go/issues/53463 and will omit brackets around ipv6 addresses on standard port 22.
func WriteKnownHost ¶ added in v1.1.0
WriteKnownHost writes a known_hosts line to writer for the supplied hostname, remote, and key. This is useful when writing a custom hostkey callback which wraps a callback obtained from knownhosts.New to provide additional known_hosts management functionality. The hostname, remote, and key typically correspond to the callback's args.
Example ¶
package main import ( "fmt" "log" "net" "os" "github.com/skeema/knownhosts" "golang.org/x/crypto/ssh" ) func main() { sshHost := "yourserver.com:22" khPath := "/home/myuser/.ssh/known_hosts" kh, err := knownhosts.New(khPath) if err != nil { log.Fatal("Failed to read known_hosts: ", err) } // Create a custom permissive hostkey callback which still errors on hosts // with changed keys, but allows unknown hosts and adds them to known_hosts cb := ssh.HostKeyCallback(func(hostname string, remote net.Addr, key ssh.PublicKey) error { err := kh(hostname, remote, key) if knownhosts.IsHostKeyChanged(err) { return fmt.Errorf("REMOTE HOST IDENTIFICATION HAS CHANGED for host %s! This may indicate a MitM attack.", hostname) } else if knownhosts.IsHostUnknown(err) { f, ferr := os.OpenFile(khPath, os.O_APPEND|os.O_WRONLY, 0600) if ferr == nil { defer f.Close() ferr = knownhosts.WriteKnownHost(f, hostname, remote, key) } if ferr == nil { log.Printf("Added host %s to known_hosts\n", hostname) } else { log.Printf("Failed to add host %s to known_hosts: %v\n", hostname, ferr) } return nil // permit previously-unknown hosts (warning: may be insecure) } return err }) config := &ssh.ClientConfig{ User: "myuser", Auth: []ssh.AuthMethod{ /* ... */ }, HostKeyCallback: cb, HostKeyAlgorithms: kh.HostKeyAlgorithms(sshHost), } client, err := ssh.Dial("tcp", sshHost, config) if err != nil { log.Fatal("Failed to dial: ", err) } defer client.Close() }
Output:
Types ¶
type HostKeyCallback ¶
type HostKeyCallback ssh.HostKeyCallback
HostKeyCallback wraps ssh.HostKeyCallback with an additional method to perform host key algorithm lookups from the known_hosts entries.
func New ¶
func New(files ...string) (HostKeyCallback, error)
New creates a host key callback from the given OpenSSH host key files. The returned value may be used in ssh.ClientConfig.HostKeyCallback by casting it to ssh.HostKeyCallback, or using its HostKeyCallback method. Otherwise, it operates the same as the New function in golang.org/x/crypto/ssh/knownhosts.
Example ¶
package main import ( "log" "github.com/skeema/knownhosts" "golang.org/x/crypto/ssh" ) func main() { sshHost := "yourserver.com:22" kh, err := knownhosts.New("/home/myuser/.ssh/known_hosts") if err != nil { log.Fatal("Failed to read known_hosts: ", err) } config := &ssh.ClientConfig{ User: "myuser", Auth: []ssh.AuthMethod{ /* ... */ }, HostKeyCallback: kh.HostKeyCallback(), // or, equivalently, use ssh.HostKeyCallback(kh) HostKeyAlgorithms: kh.HostKeyAlgorithms(sshHost), } client, err := ssh.Dial("tcp", sshHost, config) if err != nil { log.Fatal("Failed to dial: ", err) } defer client.Close() }
Output:
func (HostKeyCallback) HostKeyAlgorithms ¶
func (hkcb HostKeyCallback) HostKeyAlgorithms(hostWithPort string) (algos []string)
HostKeyAlgorithms returns a slice of host key algorithms for the supplied host:port found in the known_hosts file(s), or an empty slice if the host is not already known. The result may be used in ssh.ClientConfig's HostKeyAlgorithms field, either as-is or after filtering (if you wish to ignore or prefer particular algorithms). For hosts that have multiple known_hosts entries (for different key types), the result will be sorted by known_hosts filename and line number.
func (HostKeyCallback) HostKeyCallback ¶
func (hkcb HostKeyCallback) HostKeyCallback() ssh.HostKeyCallback
HostKeyCallback simply casts the receiver back to ssh.HostKeyCallback, for use in ssh.ClientConfig.HostKeyCallback.
func (HostKeyCallback) HostKeys ¶ added in v1.1.0
func (hkcb HostKeyCallback) HostKeys(hostWithPort string) (keys []ssh.PublicKey)
HostKeys returns a slice of known host public keys for the supplied host:port found in the known_hosts file(s), or an empty slice if the host is not already known. For hosts that have multiple known_hosts entries (for different key types), the result will be sorted by known_hosts filename and line number.