better-argo-tunnels/internal/sshutil/sshutil.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
}