SSH connections are left dangling after use (#668)

This commit is contained in:
Frederik Ring
2025-11-09 17:28:31 +01:00
committed by GitHub
parent 95bf34280d
commit 9cb2ae1893
2 changed files with 22 additions and 11 deletions

View File

@@ -177,10 +177,20 @@ func (s *script) init() error {
IdentityPassphrase: s.c.SSHIdentityPassphrase,
RemotePath: s.c.SSHRemotePath,
}
sshBackend, err := ssh.NewStorageBackend(sshConfig, logFunc)
sshBackend, closeSSHConnection, err := ssh.NewStorageBackend(sshConfig, logFunc)
s.registerHook(hookLevelPlumbing, func(err error) error {
if err := closeSSHConnection(); err != nil {
return errwrap.Wrap(err, "failed to close ssh connection")
}
return nil
})
if err != nil {
return errwrap.Wrap(err, "error creating ssh storage backend")
}
s.storages = append(s.storages, sshBackend)
}

View File

@@ -36,8 +36,10 @@ type Config struct {
RemotePath string
}
var noop = func() error { return nil }
// NewStorageBackend creates and initializes a new SSH storage backend.
func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error) {
func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, func() error, error) {
var authMethods []ssh.AuthMethod
if opts.Password != "" {
@@ -47,20 +49,20 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
if _, err := os.Stat(opts.IdentityFile); err == nil {
key, err := os.ReadFile(opts.IdentityFile)
if err != nil {
return nil, errwrap.Wrap(nil, "error reading the private key")
return nil, noop, errwrap.Wrap(nil, "error reading the private key")
}
var signer ssh.Signer
if opts.IdentityPassphrase != "" {
signer, err = ssh.ParsePrivateKeyWithPassphrase(key, []byte(opts.IdentityPassphrase))
if err != nil {
return nil, errwrap.Wrap(nil, "error parsing the encrypted private key")
return nil, noop, errwrap.Wrap(nil, "error parsing the encrypted private key")
}
authMethods = append(authMethods, ssh.PublicKeys(signer))
} else {
signer, err = ssh.ParsePrivateKey(key)
if err != nil {
return nil, errwrap.Wrap(nil, "error parsing the private key")
return nil, noop, errwrap.Wrap(nil, "error parsing the private key")
}
authMethods = append(authMethods, ssh.PublicKeys(signer))
}
@@ -72,13 +74,12 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", opts.HostName, opts.Port), sshClientConfig)
if err != nil {
return nil, errwrap.Wrap(err, "error creating ssh client")
if err != nil || sshClient == nil {
return nil, noop, errwrap.Wrap(err, "error creating ssh client")
}
_, _, err = sshClient.SendRequest("keepalive", false, nil)
if err != nil {
return nil, err
return nil, sshClient.Close, err
}
sftpClient, err := sftp.NewClient(sshClient,
@@ -87,7 +88,7 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
sftp.MaxConcurrentRequestsPerFile(64),
)
if err != nil {
return nil, errwrap.Wrap(err, "error creating sftp client")
return nil, sshClient.Close, errwrap.Wrap(err, "error creating sftp client")
}
return &sshStorage{
@@ -98,7 +99,7 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
client: sshClient,
sftpClient: sftpClient,
hostName: opts.HostName,
}, nil
}, sshClient.Close, nil
}
// Name returns the name of the storage backend