func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) { config := state.Get("config").(*Config) var privateKey string var auth []gossh.AuthMethod if config.Comm.SSHPassword != "" { auth = []gossh.AuthMethod{ gossh.Password(config.Comm.SSHPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), } } if config.Comm.SSHPrivateKey != "" { if priv, ok := state.GetOk("privateKey"); ok { privateKey = priv.(string) } signer, err := gossh.ParsePrivateKey([]byte(privateKey)) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.Comm.SSHUsername, Auth: auth, }, nil }
// SSHConfig returns a function that can be used for the SSH communicator // config for connecting to the instance created over SSH using the private key // or password. func SSHConfig(username, password string) func(multistep.StateBag) (*ssh.ClientConfig, error) { return func(state multistep.StateBag) (*ssh.ClientConfig, error) { privateKey, hasKey := state.GetOk("privateKey") if hasKey { signer, err := ssh.ParsePrivateKey([]byte(privateKey.(string))) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } return &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, }, nil } else { return &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.Password(password), ssh.KeyboardInteractive( packerssh.PasswordKeyboardInteractive(password)), }}, nil } } }
func (d *ESX5Driver) connect() error { address := fmt.Sprintf("%s:%d", d.Host, d.Port) auth := []gossh.AuthMethod{ gossh.Password(d.Password), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(d.Password)), } if d.PrivateKey != "" { signer, err := commonssh.FileSigner(d.PrivateKey) if err != nil { return err } auth = append(auth, gossh.PublicKeys(signer)) } sshConfig := &ssh.Config{ Connection: ssh.ConnectFunc("tcp", address), SSHConfig: &gossh.ClientConfig{ User: d.Username, Auth: auth, }, } comm, err := ssh.New(address, sshConfig) if err != nil { return err } d.comm = comm return nil }
func (d *ESX5Driver) connect() error { address := fmt.Sprintf("%s:%d", d.Host, d.Port) auth := []gossh.AuthMethod{ gossh.Password(d.Password), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(d.Password)), } // TODO(dougm) KeyPath support sshConfig := &ssh.Config{ Connection: ssh.ConnectFunc("tcp", address), SSHConfig: &gossh.ClientConfig{ User: d.Username, Auth: auth, }, NoPty: true, } comm, err := ssh.New(address, sshConfig) if err != nil { return err } d.comm = comm return nil }
func (p *PostProcessor) connect() error { address := fmt.Sprintf("%s:%d", p.config.Host, p.config.SshPort) auth := []gossh.AuthMethod{ gossh.Password(p.config.Password), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(p.config.Password)), } // TODO(dougm) KeyPath support sshConfig := &ssh.Config{ Connection: ssh.ConnectFunc("tcp", address), SSHConfig: &gossh.ClientConfig{ User: p.config.Username, Auth: auth, }, } comm, err := ssh.New(address, sshConfig) if err != nil { return err } p.comm = comm return nil }
func sshConfig(comm *communicator.Config) func(state multistep.StateBag) (*gossh.ClientConfig, error) { return func(state multistep.StateBag) (*gossh.ClientConfig, error) { if comm.SSHPrivateKey != "" { // key based auth bytes, err := ioutil.ReadFile(comm.SSHPrivateKey) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } privateKey := string(bytes) signer, err := gossh.ParsePrivateKey([]byte(privateKey)) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } return &gossh.ClientConfig{ User: comm.SSHUsername, Auth: []gossh.AuthMethod{ gossh.PublicKeys(signer), }, }, nil } else { // password based auth return &gossh.ClientConfig{ User: comm.SSHUsername, Auth: []gossh.AuthMethod{ gossh.Password(comm.SSHPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(comm.SSHPassword)), }, }, nil } } }
func sshConfig(state map[string]interface{}) (*gossh.ClientConfig, error) { config := state["config"].(*config) return &gossh.ClientConfig{ User: config.SSHUser, Auth: []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), }, }, nil }
// SSHConfig returns a function that can be used for the SSH communicator // config for connecting to the instance created over SSH using the private key // or password. func SSHConfig(useAgent bool, username, password string) func(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") if hasKey { signer, err := ssh.ParsePrivateKey([]byte(privateKey.(string))) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } return &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, }, nil } else { return &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.Password(password), ssh.KeyboardInteractive( packerssh.PasswordKeyboardInteractive(password)), }}, nil } } }
func SSHConfig(state multistep.StateBag) (*gossh.ClientConfig, error) { config := state.Get("commonconfig").(CommonConfig) auth := []gossh.AuthMethod{ gossh.Password(config.SSHPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), } if config.SSHKeyPath != "" { signer, err := commonssh.FileSigner(config.SSHKeyPath) if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.SSHUser, Auth: auth, }, nil }
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) { return func(state multistep.StateBag) (*gossh.ClientConfig, error) { auth := []gossh.AuthMethod{ gossh.Password(config.Comm.SSHPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), } if config.SSHKeyPath != "" { signer, err := commonssh.FileSigner(config.Comm.SSHPrivateKey) if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.Comm.SSHUsername, Auth: auth, }, nil } }
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*ssh.ClientConfig, error) { return func(state multistep.StateBag) (*ssh.ClientConfig, error) { auth := []ssh.AuthMethod{ ssh.Password(config.SSHPassword), ssh.KeyboardInteractive( packerssh.PasswordKeyboardInteractive(config.SSHPassword)), } if config.SSHKeyPath != "" { signer, err := sshKeyToSigner(config.SSHKeyPath) if err != nil { return nil, err } auth = append(auth, ssh.PublicKeys(signer)) } return &ssh.ClientConfig{ User: config.SSHUser, Auth: auth, }, nil } }
func sshConfig(state map[string]interface{}) (*gossh.ClientConfig, error) { config := state["config"].(*config) auth := []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), } if config.SSHKeyPath != "" { keyring, err := sshKeyToKeyring(config.SSHKeyPath) if err != nil { return nil, err } auth = append(auth, gossh.ClientAuthKeyring(keyring)) } return &gossh.ClientConfig{ User: config.SSHUser, Auth: auth, }, nil }
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) { return func(state multistep.StateBag) (*gossh.ClientConfig, error) { auth := []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), } if config.SSHKeyPath != "" { keyring, err := sshKeyToKeyring(config.SSHKeyPath) if err != nil { return nil, err } auth = append(auth, gossh.ClientAuthKeyring(keyring)) } return &gossh.ClientConfig{ User: config.SSHUser, Auth: auth, }, nil } }
func sshBastionConfig(config *Config) (*gossh.ClientConfig, error) { auth := make([]gossh.AuthMethod, 0, 2) if config.SSHBastionPassword != "" { auth = append(auth, gossh.Password(config.SSHBastionPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHBastionPassword))) } if config.SSHBastionPrivateKey != "" { signer, err := commonssh.FileSigner(config.SSHBastionPrivateKey) if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.SSHBastionUsername, Auth: auth, }, nil }
// SSHConfig returns a function that can be used for the SSH communicator // config for connecting to the specified host via SSH // private_key_file has precedence over password! func SSHConfig(username string, password string, privateKeyFile string) func(multistep.StateBag) (*gossh.ClientConfig, error) { return func(state multistep.StateBag) (*gossh.ClientConfig, error) { if privateKeyFile != "" { // key based auth bytes, err := ioutil.ReadFile(privateKeyFile) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } privateKey := string(bytes) keyring := new(ssh.SimpleKeychain) if err := keyring.AddPEMKey(privateKey); err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } return &gossh.ClientConfig{ User: username, Auth: []gossh.ClientAuth{ gossh.ClientAuthKeyring(keyring), }, }, nil } else { // password based auth return &gossh.ClientConfig{ User: username, Auth: []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(password)), gossh.ClientAuthKeyboardInteractive(ssh.PasswordKeyboardInteractive(password)), }, }, nil } } }
func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) { config := state.Get("config").(config) privateKey := state.Get("ssh_private_key").(string) auth := []ssh.AuthMethod{ ssh.Password(config.SSHPassword), ssh.KeyboardInteractive( packerssh.PasswordKeyboardInteractive(config.SSHPassword)), } if privateKey != "" { signer, err := ssh.ParsePrivateKey([]byte(privateKey)) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } auth = append(auth, ssh.PublicKeys(signer)) } return &ssh.ClientConfig{ User: config.SSHUsername, Auth: auth, }, nil }
// This blocks until SSH becomes available, and sends the communicator // on the given channel. func (s *stepWaitForSSH) waitForSSH(state map[string]interface{}) (packer.Communicator, error) { config := state["config"].(*config) ui := state["ui"].(packer.Ui) vmxPath := state["vmx_path"].(string) handshakeAttempts := 0 ui.Say("Waiting for SSH to become available...") var comm packer.Communicator for { time.Sleep(5 * time.Second) if s.cancel { log.Println("SSH wait cancelled. Exiting loop.") return nil, errors.New("SSH wait cancelled") } // First we wait for the IP to become available... log.Println("Lookup up IP information...") ipLookup, err := s.dhcpLeaseLookup(vmxPath) if err != nil { log.Printf("Can't lookup via DHCP lease: %s", err) } ip, err := ipLookup.GuestIP() if err != nil { log.Printf("IP lookup failed: %s", err) continue } log.Printf("Detected IP: %s", ip) // Attempt to connect to SSH port connFunc := ssh.ConnectFunc( "tcp", fmt.Sprintf("%s:%d", ip, config.SSHPort), 5*time.Minute) nc, err := connFunc() if err != nil { log.Printf("TCP connection to SSH ip/port failed: %s", err) continue } nc.Close() // Then we attempt to connect via SSH config := &ssh.Config{ Connection: connFunc, SSHConfig: &gossh.ClientConfig{ User: config.SSHUser, Auth: []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), }, }, } comm, err = ssh.New(config) if err != nil { log.Printf("SSH handshake err: %s", err) handshakeAttempts += 1 if handshakeAttempts < 10 { // Try to connect via SSH a handful of times continue } return nil, err } ui.Say("Connected via SSH!") break } return comm, nil }
// This blocks until SSH becomes available, and sends the communicator // on the given channel. func (s *stepWaitForSSH) waitForSSH(state map[string]interface{}) (packer.Communicator, error) { config := state["config"].(*config) ui := state["ui"].(packer.Ui) sshHostPort := state["sshHostPort"].(uint) ui.Say("Waiting for SSH to become available...") var comm packer.Communicator var nc net.Conn for { if nc != nil { nc.Close() } time.Sleep(5 * time.Second) if s.cancel { log.Println("SSH wait cancelled. Exiting loop.") return nil, errors.New("SSH wait cancelled") } // Attempt to connect to SSH port nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort)) if err != nil { log.Printf("TCP connection to SSH ip/port failed: %s", err) continue } // Then we attempt to connect via SSH sshConfig := &gossh.ClientConfig{ User: config.SSHUser, Auth: []gossh.ClientAuth{ gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)), gossh.ClientAuthKeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), }, } sshConnectSuccess := make(chan bool, 1) go func() { comm, err = ssh.New(nc, sshConfig) if err != nil { log.Printf("SSH connection fail: %s", err) sshConnectSuccess <- false return } sshConnectSuccess <- true }() select { case success := <-sshConnectSuccess: if !success { continue } case <-time.After(5 * time.Second): log.Printf("SSH handshake timeout. Trying again.") continue } ui.Say("Connected via SSH!") break } // Store the connection so we can close it later s.conn = nc return comm, nil }