diff --git a/ssh/go.mod b/ssh/go.mod index a9f24343..a98fce32 100644 --- a/ssh/go.mod +++ b/ssh/go.mod @@ -5,11 +5,11 @@ go 1.22.0 require ( github.com/onsi/gomega v1.34.2 golang.org/x/crypto v0.27.0 + golang.org/x/net v0.29.0 ) require ( github.com/google/go-cmp v0.6.0 // indirect - golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/ssh/host_key.go b/ssh/host_key.go index e3b2e8d3..e603d168 100644 --- a/ssh/host_key.go +++ b/ssh/host_key.go @@ -17,6 +17,7 @@ limitations under the License. package ssh import ( + "context" "encoding/base64" "fmt" "net" @@ -24,6 +25,7 @@ import ( "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/knownhosts" + "golang.org/x/net/proxy" ) // ScanHostKey collects the given host's preferred public key for the @@ -45,16 +47,33 @@ func ScanHostKey(host string, timeout time.Duration, clientHostKeyAlgos []string config.HostKeyAlgorithms = clientHostKeyAlgos } - client, err := ssh.Dial("tcp", host, config) - if err == nil { - defer client.Close() - } + err := sshDial(host, config) + if len(col.knownKeys) > 0 { return col.knownKeys, nil } + return col.knownKeys, err } +func sshDial(host string, config *ssh.ClientConfig) error { + ctx, cancel := context.WithTimeout(context.Background(), config.Timeout) + defer cancel() + // this reads the ALL_PROXY environment varaible + conn, err := proxy.Dial(ctx, "tcp", host) + if err != nil { + return err + } + c, chans, reqs, err := ssh.NewClientConn(conn, host, config) + if err != nil { + return err + } + client := ssh.NewClient(c, chans, reqs) + defer client.Close() + + return nil +} + // HostKeyCollector offers a StoreKey method which provides an // HostKeyCallBack to collect public keys from an SSH server. type HostKeyCollector struct {