github.com/rothwerx/packer@v0.9.0/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 ) 10 11 // ConnectFunc is a convenience method for returning a function 12 // that just uses net.Dial to communicate with the remote end that 13 // is suitable for use with the SSH communicator configuration. 14 func ConnectFunc(network, addr string) func() (net.Conn, error) { 15 return func() (net.Conn, error) { 16 c, err := net.DialTimeout(network, addr, 15*time.Second) 17 if err != nil { 18 return nil, err 19 } 20 21 if tcpConn, ok := c.(*net.TCPConn); ok { 22 tcpConn.SetKeepAlive(true) 23 tcpConn.SetKeepAlivePeriod(5 * time.Second) 24 } 25 26 return c, nil 27 } 28 } 29 30 // BastionConnectFunc is a convenience method for returning a function 31 // that connects to a host over a bastion connection. 32 func BastionConnectFunc( 33 bProto string, 34 bAddr string, 35 bConf *ssh.ClientConfig, 36 proto string, 37 addr string) func() (net.Conn, error) { 38 return func() (net.Conn, error) { 39 // Connect to the bastion 40 bastion, err := ssh.Dial(bProto, bAddr, bConf) 41 if err != nil { 42 return nil, fmt.Errorf("Error connecting to bastion: %s", err) 43 } 44 45 // Connect through to the end host 46 conn, err := bastion.Dial(proto, addr) 47 if err != nil { 48 bastion.Close() 49 return nil, err 50 } 51 52 // Wrap it up so we close both things properly 53 return &bastionConn{ 54 Conn: conn, 55 Bastion: bastion, 56 }, nil 57 } 58 } 59 60 type bastionConn struct { 61 net.Conn 62 Bastion *ssh.Client 63 } 64 65 func (c *bastionConn) Close() error { 66 c.Conn.Close() 67 return c.Bastion.Close() 68 }