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:
parent
69daca2a33
commit
2164700162
|
@ -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"))
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue