SOCKS5 proxy support
This commit is contained in:
parent
c85cf0483a
commit
d9b404fa00
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
// ConnectFunc is a convenience method for returning a function
|
||||
|
@ -27,6 +28,25 @@ func ConnectFunc(network, addr string) func() (net.Conn, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// ConnectFunc is a convenience method for returning a function
|
||||
// that connects to a host using SOCKS5 proxy
|
||||
func ProxyConnectFunc(socksProxy string, socksAuth *proxy.Auth, network, addr string) func() (net.Conn, error) {
|
||||
return func() (net.Conn, error) {
|
||||
// create a socks5 dialer
|
||||
dialer, err := proxy.SOCKS5("tcp", socksProxy, socksAuth, proxy.Direct)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can't connect to the proxy: %s", err)
|
||||
}
|
||||
|
||||
c, err := dialer.Dial(network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
// BastionConnectFunc is a convenience method for returning a function
|
||||
// that connects to a host over a bastion connection.
|
||||
func BastionConnectFunc(
|
||||
|
|
|
@ -33,6 +33,10 @@ type Config struct {
|
|||
SSHBastionPassword string `mapstructure:"ssh_bastion_password"`
|
||||
SSHBastionPrivateKey string `mapstructure:"ssh_bastion_private_key_file"`
|
||||
SSHFileTransferMethod string `mapstructure:"ssh_file_transfer_method"`
|
||||
SSHProxyHost string `mapstructure:"ssh_proxy_host"`
|
||||
SSHProxyPort int `mapstructure:"ssh_proxy_port"`
|
||||
SSHProxyUsername string `mapstructure:"ssh_proxy_username"`
|
||||
SSHProxyPassword string `mapstructure:"ssh_proxy_password"`
|
||||
|
||||
// WinRM
|
||||
WinRMUser string `mapstructure:"winrm_username"`
|
||||
|
@ -141,6 +145,12 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error {
|
|||
}
|
||||
}
|
||||
|
||||
if c.SSHProxyHost != "" {
|
||||
if c.SSHProxyPort == 0 {
|
||||
c.SSHProxyPort = 1080
|
||||
}
|
||||
}
|
||||
|
||||
if c.SSHFileTransferMethod == "" {
|
||||
c.SSHFileTransferMethod = "scp"
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/mitchellh/multistep"
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/agent"
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
// StepConnectSSH is a step that only connects to SSH.
|
||||
|
@ -88,6 +89,8 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
|
|||
// do this one before entering the retry loop.
|
||||
var bProto, bAddr string
|
||||
var bConf *gossh.ClientConfig
|
||||
var pAddr string
|
||||
var pAuth *proxy.Auth
|
||||
if s.Config.SSHBastionHost != "" {
|
||||
// The protocol is hardcoded for now, but may be configurable one day
|
||||
bProto = "tcp"
|
||||
|
@ -101,6 +104,16 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
|
|||
bConf = conf
|
||||
}
|
||||
|
||||
if s.Config.SSHProxyHost != "" {
|
||||
pAddr = fmt.Sprintf("%s:%d", s.Config.SSHProxyHost, s.Config.SSHProxyPort)
|
||||
if s.Config.SSHProxyUsername != "" {
|
||||
pAuth = new(proxy.Auth)
|
||||
pAuth.User = s.Config.SSHBastionUsername
|
||||
pAuth.Password = s.Config.SSHBastionPassword
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handshakeAttempts := 0
|
||||
|
||||
var comm packer.Communicator
|
||||
|
@ -146,6 +159,9 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
|
|||
// We're using a bastion host, so use the bastion connfunc
|
||||
connFunc = ssh.BastionConnectFunc(
|
||||
bProto, bAddr, bConf, "tcp", address)
|
||||
} else if pAddr != "" {
|
||||
// Connect via SOCKS5 proxy
|
||||
connFunc = ssh.ProxyConnectFunc(pAddr, pAuth, "tcp", address)
|
||||
} else {
|
||||
// No bastion host, connect directly
|
||||
connFunc = ssh.ConnectFunc("tcp", address)
|
||||
|
|
Loading…
Reference in New Issue