Add ssh agent to enable SSH-CA authentication.

This commit is contained in:
Larry Bordowitz 2017-03-10 08:45:13 -08:00
parent f8a8952231
commit c5b8a1069a
3 changed files with 31 additions and 2 deletions

View File

@ -110,7 +110,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
computeClient, computeClient,
b.config.SSHInterface, b.config.SSHInterface,
b.config.SSHIPVersion), b.config.SSHIPVersion),
SSHConfig: SSHConfig(b.config.RunConfig.Comm.SSHUsername, SSHConfig: SSHConfig(
b.config.RunConfig.Comm.SSHAgentAuth,
b.config.RunConfig.Comm.SSHUsername,
b.config.RunConfig.Comm.SSHPassword), b.config.RunConfig.Comm.SSHPassword),
}, },
&common.StepProvision{}, &common.StepProvision{},

View File

@ -4,6 +4,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"log" "log"
"net"
"os"
"time" "time"
"github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud"
@ -12,6 +14,7 @@ import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
packerssh "github.com/mitchellh/packer/communicator/ssh" packerssh "github.com/mitchellh/packer/communicator/ssh"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
) )
// CommHost looks up the host for the communicator. // CommHost looks up the host for the communicator.
@ -63,8 +66,26 @@ func CommHost(
// SSHConfig returns a function that can be used for the SSH communicator // SSHConfig returns a function that can be used for the SSH communicator
// config for connecting to the instance created over SSH using a private key // config for connecting to the instance created over SSH using a private key
// or a password. // or a password.
func SSHConfig(username, password string) func(multistep.StateBag) (*ssh.ClientConfig, error) { func SSHConfig(useAgent bool, username, password string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
return func(state multistep.StateBag) (*ssh.ClientConfig, error) { return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
if useAgent {
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)
}
return &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers),
},
}, nil
}
privateKey, hasKey := state.GetOk("privateKey") privateKey, hasKey := state.GetOk("privateKey")

View File

@ -147,6 +147,12 @@ builder.
[`ssh_private_key_file`](/docs/templates/communicator.html#ssh_private_key_file) [`ssh_private_key_file`](/docs/templates/communicator.html#ssh_private_key_file)
must be specified with this. must be specified with this.
- `ssh_agent_auth` (boolean) - If true, the local SSH agent will be used to
authenticate connections to the source instance. No temporary key pair will
be used, and the values of `ssh_password` and `ssh_private_key_file` will
be ignored. Useful for when a temporary keypair can't be used, or when using
a certificate authority for SSH authentication.
- `tenant_id` or `tenant_name` (string) - The tenant ID or name to boot the - `tenant_id` or `tenant_name` (string) - The tenant ID or name to boot the
instance into. Some OpenStack installations require this. If not specified, instance into. Some OpenStack installations require this. If not specified,
Packer will use the environment variable `OS_TENANT_NAME`, if set. Tenant Packer will use the environment variable `OS_TENANT_NAME`, if set. Tenant