Enable ssh agent forwarding #1066
This commit is contained in:
parent
74b9da5b23
commit
b2f8eb68e8
|
@ -17,6 +17,8 @@ FEATURES:
|
||||||
being built. This should be used for template-relative paths. [GH-54]
|
being built. This should be used for template-relative paths. [GH-54]
|
||||||
* **Disable SSH:** Set `communicator` to "none" in any builder to disable SSH
|
* **Disable SSH:** Set `communicator` to "none" in any builder to disable SSH
|
||||||
connections. Note that provisioners won't work if this is done. [GH-1591]
|
connections. Note that provisioners won't work if this is done. [GH-1591]
|
||||||
|
* **SSH Agent Forwarding:** SSH Agent Forwarding will now be enabled
|
||||||
|
to allow access to remote servers such as private git repos. [GH-1066]
|
||||||
|
|
||||||
IMPROVEMENTS:
|
IMPROVEMENTS:
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
"golang.org/x/crypto/ssh/agent"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -226,10 +227,59 @@ func (c *comm) reconnect() (err error) {
|
||||||
if sshConn != nil {
|
if sshConn != nil {
|
||||||
c.client = ssh.NewClient(sshConn, sshChan, req)
|
c.client = ssh.NewClient(sshConn, sshChan, req)
|
||||||
}
|
}
|
||||||
|
c.connectToAgent()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *comm) connectToAgent() {
|
||||||
|
if c.client == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// open connection to the local agent
|
||||||
|
socketLocation := os.Getenv("SSH_AUTH_SOCK")
|
||||||
|
if socketLocation == "" {
|
||||||
|
log.Printf("no local agent socket")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
agentConn, err := net.Dial("unix", socketLocation)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("could not connect to local agent socket: %s", socketLocation)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// create agent and add in auth
|
||||||
|
forwardingAgent := agent.NewClient(agentConn)
|
||||||
|
if forwardingAgent == nil {
|
||||||
|
log.Printf("could not create agent client")
|
||||||
|
agentConn.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// add callback for forwarding agent to SSH config
|
||||||
|
// XXX - might want to handle reconnects appending multiple callbacks
|
||||||
|
auth := ssh.PublicKeysCallback(forwardingAgent.Signers)
|
||||||
|
c.config.SSHConfig.Auth = append(c.config.SSHConfig.Auth, auth)
|
||||||
|
agent.ForwardToAgent(c.client, forwardingAgent)
|
||||||
|
|
||||||
|
// Setup a session to request agent forwarding
|
||||||
|
session, err := c.newSession()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err = agent.RequestAgentForwarding(session)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("RequestAgentForwarding:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("agent forwarding enabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (c *comm) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) error) error {
|
func (c *comm) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) error) error {
|
||||||
session, err := c.newSession()
|
session, err := c.newSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -146,6 +146,33 @@ on reboot or in your shell script. For example, on Gentoo:
|
||||||
/etc/init.d/net.eth0 stop
|
/etc/init.d/net.eth0 stop
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## SSH Agent Forwarding
|
||||||
|
|
||||||
|
Some provisioning requires connecting to remote SSH servers from within the
|
||||||
|
packer instance. The below example is for pulling code from a private git
|
||||||
|
repository utilizing openssh on the client. Make sure you are running
|
||||||
|
`ssh-agent` and add your git repo ssh keys into it using `ssh-add /path/to/key`.
|
||||||
|
When the packer instance needs access to the ssh keys the agent will forward
|
||||||
|
the request back to your `ssh-agent`.
|
||||||
|
|
||||||
|
Note: when provisioning via git you should add the git server keys into
|
||||||
|
the `~/.ssh/known_hosts` file otherwise the git command could hang awaiting
|
||||||
|
input. This can be done by copying the file in via the
|
||||||
|
[file provisioner](/docs/provisioners/file.html) (more secure)
|
||||||
|
or using `ssh-keyscan` to populate the file (less secure). An example of the
|
||||||
|
latter accessing github would be:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"inline": [
|
||||||
|
"sudo apt-get install -y git",
|
||||||
|
"ssh-keyscan github.com >> ~/.ssh/known_hosts",
|
||||||
|
"git clone git@github.com:exampleorg/myprivaterepo.git"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
*My shell script doesn't work correctly on Ubuntu*
|
*My shell script doesn't work correctly on Ubuntu*
|
||||||
|
|
Loading…
Reference in New Issue