69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
package sshutil
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
"golang.org/x/crypto/ssh/knownhosts"
|
|
)
|
|
|
|
// SecureConfig returns the currently supported non-legacy SSH algorithms from
|
|
// x/crypto/ssh. This keeps SHA-1-era algorithms out without hardcoding a list
|
|
// that can drift behind the library.
|
|
func SecureConfig() ssh.Config {
|
|
algorithms := ssh.SupportedAlgorithms()
|
|
return ssh.Config{
|
|
KeyExchanges: algorithms.KeyExchanges,
|
|
Ciphers: algorithms.Ciphers,
|
|
MACs: algorithms.MACs,
|
|
}
|
|
}
|
|
|
|
func HostKeyAlgorithms() []string {
|
|
return ssh.SupportedAlgorithms().HostKeys
|
|
}
|
|
|
|
func PublicKeyAuthAlgorithms() []string {
|
|
return ssh.SupportedAlgorithms().PublicKeyAuths
|
|
}
|
|
|
|
func ExistingPath(paths ...string) string {
|
|
for _, path := range paths {
|
|
if path == "" {
|
|
continue
|
|
}
|
|
if _, err := os.Stat(path); err == nil {
|
|
return path
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func HostKeyCallback(knownHostsPath string, strict bool, label string) (ssh.HostKeyCallback, string, error) {
|
|
if knownHostsPath != "" {
|
|
cb, err := knownhosts.New(knownHostsPath)
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("load %s known_hosts %s: %w", label, knownHostsPath, err)
|
|
}
|
|
return cb, fmt.Sprintf("known_hosts:%s", knownHostsPath), nil
|
|
}
|
|
|
|
if strict {
|
|
return nil, "", fmt.Errorf("%s strict host key checking requires a known_hosts file", label)
|
|
}
|
|
|
|
return func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
|
log.Printf(
|
|
"WARN: %s SSH host key is not verified for %s (%s); fingerprint=%s",
|
|
label,
|
|
hostname,
|
|
remote.String(),
|
|
ssh.FingerprintSHA256(key),
|
|
)
|
|
return nil
|
|
}, "insecure-unverified-host-key", nil
|
|
}
|