Browse Source

refactor: more robust SSH connection handling

decentral1se 2 years ago
parent
commit
481891b077
No known key found for this signature in database GPG Key ID: 3789458B3D0C410
  1. 3
      README.md
  2. 36
      distribusi.go

3
README.md

@ -196,7 +196,8 @@ Host varia.zone
`distribusi-go` will read the `User` and `Port` values from this configuration.
It won't try to parse private key files or prompt for passwords, it will simply
interface with `ssh-agent` which handles all that.
interface with `ssh-agent` which handles all that. If there is no
`~/.ssh/config` entry, default values will be attempted.
If all else fails, try `-d/--debug` for extra help figuring out what SSH
connection details are used. You can [open a ticket] and we can try and help.

36
distribusi.go

@ -15,6 +15,7 @@ import (
"net/http"
"os"
"os/exec"
"os/user"
"path"
"path/filepath"
"sort"
@ -915,19 +916,24 @@ func scpPublish(c *cli.Context, root, pubTarget string) error {
split := strings.Split(pubTarget, ":")
server, remotePath := split[0], split[1]
logrus.Debugf("parsed server: %s remotePath: %s from %s", server, remotePath, pubTarget)
logrus.Debugf("parsed server: %s, remotePath: %s from %s", server, remotePath, pubTarget)
if hostname := ssh_config.Get(server, "Hostname"); hostname == "" {
return fmt.Errorf("missing Hostname entry for %s in ~/.ssh/config, cannot continue", server)
}
sshUser := ssh_config.Get(server, "User")
if sshUser == "" {
logrus.Debugf("no ssh user discovered for %s, using system user as default", server)
user := ssh_config.Get(server, "User")
port := ssh_config.Get(server, "Port")
sysUser, err := user.Current()
if err != nil {
return fmt.Errorf("unable to determine current system user")
}
sshUser = sysUser.Username
}
logrus.Debugf("read user: %s, port: %s for %s in ~/.ssh/config", user, port, server)
sshPort := ssh_config.Get(server, "Port")
sshConf := &ssh.ClientConfig{
User: user,
User: sshUser,
HostKeyCallback: ssh.InsecureIgnoreHostKey(), // awful, i know
Timeout: 5 * time.Second,
}
@ -936,22 +942,24 @@ func scpPublish(c *cli.Context, root, pubTarget string) error {
if identityFile != "" && identityFile != "~/.ssh/identity" {
sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
if err != nil {
return err
return fmt.Errorf("unable to connect to local ssh-agent, is it running?")
}
agentCl := agent.NewClient(sshAgent)
authMethod := ssh.PublicKeysCallback(agentCl.Signers)
sshConf.Auth = []ssh.AuthMethod{authMethod}
logrus.Debugf("read identityFile: %s for %s in ~/.ssh/config, using ssh-agent for auth", identityFile, server)
logrus.Debugf("choosing ssh key: %s to connect to %s using ssh-agent", identityFile, server)
} else {
logrus.Debugf("no ssh key discovered for %s", server)
}
logrus.Debug("attempting to construct SSH client for publishing logic")
logrus.Debugf("connecting with user: %s, port: %s to connect to %s", sshUser, sshPort, server)
serverAndPort := fmt.Sprintf("%s:%s", server, port)
serverAndPort := fmt.Sprintf("%s:%s", server, sshPort)
scpClient, err := scp.NewClient(serverAndPort, sshConf, &scp.ClientOption{})
if err != nil {
return err
return fmt.Errorf("unable to make SSH connection to %s, have you configured your SSH client?", server)
}
defer scpClient.Close()
@ -963,7 +971,7 @@ func scpPublish(c *cli.Context, root, pubTarget string) error {
fmt.Printf(fmt.Sprintf("publishing %s to %s...", filepath.Base(root), server))
if err := scpClient.CopyDirToRemote(root, remotePath, opts); err != nil {
return err
return fmt.Errorf("woops, publishing failed, saw this error: %s", err.Error())
}
fmt.Println(" done!")

Loading…
Cancel
Save