comm/ssh: Add support for using SSH Agent auth towards a bastion host.

Adds `ssh_bastion_agent_auth`

Fixes: #4732
This commit is contained in:
Rickard von Essen 2017-05-28 14:05:03 +02:00
parent 69daca2a33
commit 2164700162
No known key found for this signature in database
GPG Key ID: E0C0327388876CBA
3 changed files with 21 additions and 1 deletions

View File

@ -28,6 +28,7 @@ type Config struct {
SSHHandshakeAttempts int `mapstructure:"ssh_handshake_attempts"` SSHHandshakeAttempts int `mapstructure:"ssh_handshake_attempts"`
SSHBastionHost string `mapstructure:"ssh_bastion_host"` SSHBastionHost string `mapstructure:"ssh_bastion_host"`
SSHBastionPort int `mapstructure:"ssh_bastion_port"` SSHBastionPort int `mapstructure:"ssh_bastion_port"`
SSHBastionAgentAuth bool `mapstructure:"ssh_bastion_agent_auth"`
SSHBastionUsername string `mapstructure:"ssh_bastion_username"` SSHBastionUsername string `mapstructure:"ssh_bastion_username"`
SSHBastionPassword string `mapstructure:"ssh_bastion_password"` SSHBastionPassword string `mapstructure:"ssh_bastion_password"`
SSHBastionPrivateKey string `mapstructure:"ssh_bastion_private_key_file"` SSHBastionPrivateKey string `mapstructure:"ssh_bastion_private_key_file"`
@ -159,7 +160,7 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error {
} }
} }
if c.SSHBastionHost != "" { if c.SSHBastionHost != "" && !c.SSHBastionAgentAuth {
if c.SSHBastionPassword == "" && c.SSHBastionPrivateKey == "" { if c.SSHBastionPassword == "" && c.SSHBastionPrivateKey == "" {
errs = append(errs, errors.New( errs = append(errs, errors.New(
"ssh_bastion_password or ssh_bastion_private_key_file must be specified")) "ssh_bastion_password or ssh_bastion_private_key_file must be specified"))

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"log" "log"
"net" "net"
"os"
"strings" "strings"
"time" "time"
@ -13,6 +14,7 @@ import (
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
gossh "golang.org/x/crypto/ssh" gossh "golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
) )
// StepConnectSSH is a step that only connects to SSH. // StepConnectSSH is a step that only connects to SSH.
@ -213,6 +215,20 @@ func sshBastionConfig(config *Config) (*gossh.ClientConfig, error) {
auth = append(auth, gossh.PublicKeys(signer)) auth = append(auth, gossh.PublicKeys(signer))
} }
if config.SSHBastionAgentAuth {
authSock := os.Getenv("SSH_AUTH_SOCK")
if authSock == "" {
return nil, fmt.Errorf("SSH_AUTH_SOCK is not set")
}
sshAgent, err := net.Dial("unix", authSock)
if err != nil {
return nil, fmt.Errorf("Cannot connect to SSH Agent socket %q: %s", authSock, err)
}
auth = append(auth, gossh.PublicKeysCallback(agent.NewClient(sshAgent).Signers))
}
return &gossh.ClientConfig{ return &gossh.ClientConfig{
User: config.SSHBastionUsername, User: config.SSHBastionUsername,
Auth: auth, Auth: auth,

View File

@ -58,6 +58,9 @@ the SSH agent to the remote host.
The SSH communicator has the following options: The SSH communicator has the following options:
- `ssh_bastion_agent_auth` (boolean) - If true, the local SSH agent will
be used to authenticate with the bastion host. Defaults to false.
- `ssh_bastion_host` (string) - A bastion host to use for the actual - `ssh_bastion_host` (string) - A bastion host to use for the actual
SSH connection. SSH connection.