From e589709cb012cec59f5e24eb38c5d857bf9d2151 Mon Sep 17 00:00:00 2001 From: decentral1se Date: Thu, 18 Nov 2021 21:16:10 +0100 Subject: [PATCH] fix: attempt to include IdentityFile if available This is part of trying to debug: https://git.coopcloud.tech/coop-cloud/organising/issues/250 And also part of: https://git.coopcloud.tech/coop-cloud/docs.coopcloud.tech/issues/27 Where I now try to specify the same logic as `ssh -i ` in the underlying connection logic. This should help with being more explicit about what key is being used via the SSH config file. --- pkg/ssh/ssh.go | 31 ++++++++++++++++++++++++-- pkg/upstream/commandconn/connection.go | 17 ++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/pkg/ssh/ssh.go b/pkg/ssh/ssh.go index d72c8d0e..c7132f88 100644 --- a/pkg/ssh/ssh.go +++ b/pkg/ssh/ssh.go @@ -563,11 +563,16 @@ func GetHostConfig(hostname, username, port string) (HostConfig, error) { } idf = ssh_config.Get(hostname, "IdentityFile") - - hostConfig.Host = host if idf != "" { + var err error + idf, err = identityFileAbsPath(idf) + if err != nil { + return hostConfig, err + } hostConfig.IdentityFile = idf } + + hostConfig.Host = host hostConfig.Port = port hostConfig.User = username @@ -575,3 +580,25 @@ func GetHostConfig(hostname, username, port string) (HostConfig, error) { return hostConfig, nil } + +func identityFileAbsPath(relPath string) (string, error) { + var err error + var absPath string + + if strings.HasPrefix(relPath, "~/") { + systemUser, err := user.Current() + if err != nil { + return absPath, err + } + absPath = filepath.Join(systemUser.HomeDir, relPath[2:]) + } else { + absPath, err = filepath.Abs(relPath) + if err != nil { + return absPath, err + } + } + + logrus.Debugf("resolved %s to %s to read the ssh identity file", relPath, absPath) + + return absPath, nil +} diff --git a/pkg/upstream/commandconn/connection.go b/pkg/upstream/commandconn/connection.go index d97e9e44..2554248e 100644 --- a/pkg/upstream/commandconn/connection.go +++ b/pkg/upstream/commandconn/connection.go @@ -2,6 +2,7 @@ package commandconn import ( "context" + "fmt" "net" "net/url" @@ -34,9 +35,25 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*connhelper.Conne if err != nil { return nil, errors.Wrap(err, "ssh host connection is not valid") } + if err := sshPkg.EnsureHostKey(ctxConnDetails.Host); err != nil { return nil, err } + + hostConfig, err := sshPkg.GetHostConfig( + ctxConnDetails.Host, + ctxConnDetails.User, + ctxConnDetails.Port, + ) + if err != nil { + return nil, err + } + if hostConfig.IdentityFile != "" { + msg := "discovered %s as identity file for %s, using for ssh connection" + logrus.Debugf(msg, hostConfig.IdentityFile, ctxConnDetails.Host) + sshFlags = append(sshFlags, fmt.Sprintf("-o IdentityFile=%s", hostConfig.IdentityFile)) + } + return &connhelper.ConnectionHelper{ Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) { return New(ctx, "ssh", append(sshFlags, ctxConnDetails.Args("docker", "system", "dial-stdio")...)...)