github.phpd.cn/hashicorp/packer@v1.3.2/communicator/ssh/connect.go (about) 1 package ssh 2 3 import ( 4 "fmt" 5 "net" 6 "time" 7 8 "golang.org/x/crypto/ssh" 9 "golang.org/x/net/proxy" 10 ) 11 12 // ConnectFunc is a convenience method for returning a function 13 // that just uses net.Dial to communicate with the remote end that 14 // is suitable for use with the SSH communicator configuration. 15 func ConnectFunc(network, addr string) func() (net.Conn, error) { 16 return func() (net.Conn, error) { 17 c, err := net.DialTimeout(network, addr, 15*time.Second) 18 if err != nil { 19 return nil, err 20 } 21 22 if tcpConn, ok := c.(*net.TCPConn); ok { 23 tcpConn.SetKeepAlive(true) 24 tcpConn.SetKeepAlivePeriod(5 * time.Second) 25 } 26 27 return c, nil 28 } 29 } 30 31 // ProxyConnectFunc is a convenience method for returning a function 32 // that connects to a host using SOCKS5 proxy 33 func ProxyConnectFunc(socksProxy string, socksAuth *proxy.Auth, network, addr string) func() (net.Conn, error) { 34 return func() (net.Conn, error) { 35 // create a socks5 dialer 36 dialer, err := proxy.SOCKS5("tcp", socksProxy, socksAuth, proxy.Direct) 37 if err != nil { 38 return nil, fmt.Errorf("Can't connect to the proxy: %s", err) 39 } 40 41 c, err := dialer.Dial(network, addr) 42 if err != nil { 43 return nil, err 44 } 45 46 return c, nil 47 } 48 } 49 50 // BastionConnectFunc is a convenience method for returning a function 51 // that connects to a host over a bastion connection. 52 func BastionConnectFunc( 53 bProto string, 54 bAddr string, 55 bConf *ssh.ClientConfig, 56 proto string, 57 addr string) func() (net.Conn, error) { 58 return func() (net.Conn, error) { 59 // Connect to the bastion 60 bastion, err := ssh.Dial(bProto, bAddr, bConf) 61 if err != nil { 62 return nil, fmt.Errorf("Error connecting to bastion: %s", err) 63 } 64 65 // Connect through to the end host 66 conn, err := bastion.Dial(proto, addr) 67 if err != nil { 68 bastion.Close() 69 return nil, err 70 } 71 72 // Wrap it up so we close both things properly 73 return &bastionConn{ 74 Conn: conn, 75 Bastion: bastion, 76 }, nil 77 } 78 } 79 80 type bastionConn struct { 81 net.Conn 82 Bastion *ssh.Client 83 } 84 85 func (c *bastionConn) Close() error { 86 c.Conn.Close() 87 return c.Bastion.Close() 88 }