func ExampleClient_Listen() { config := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.Password("password"), }, } // Dial your ssh server. conn, err := ssh.Dial("tcp", "localhost:22", config) if err != nil { log.Fatalf("unable to connect: %s", err) } defer conn.Close() // Request the remote side to open port 8080 on all interfaces. l, err := conn.Listen("tcp", "0.0.0.0:8080") if err != nil { log.Fatalf("unable to register tcp forward: %v", err) } defer l.Close() // Serve HTTP with your SSH server acting as a reverse proxy. http.Serve(l, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { fmt.Fprintf(resp, "Hello world!\n") })) }
func ExampleSession_RequestPty() { // Create client config config := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.Password("password"), }, } // Connect to ssh server conn, err := ssh.Dial("tcp", "localhost:22", config) if err != nil { log.Fatalf("unable to connect: %s", err) } defer conn.Close() // Create a session session, err := conn.NewSession() if err != nil { log.Fatalf("unable to create session: %s", err) } defer session.Close() // Set up terminal modes modes := ssh.TerminalModes{ ssh.ECHO: 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } // Request pseudo terminal if err := session.RequestPty("xterm", 80, 40, modes); err != nil { log.Fatalf("request for pseudo terminal failed: %s", err) } // Start remote shell if err := session.Shell(); err != nil { log.Fatalf("failed to start shell: %s", err) } }
func ExampleDial() { // An SSH client is represented with a ClientConn. Currently only // the "password" authentication method is supported. // // To authenticate with the remote server you must pass at least one // implementation of AuthMethod via the Auth field in ClientConfig. config := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.Password("yourpassword"), }, } client, err := ssh.Dial("tcp", "yourserver.com:22", config) if err != nil { panic("Failed to dial: " + err.Error()) } // Each ClientConn can support multiple interactive sessions, // represented by a Session. session, err := client.NewSession() if err != nil { panic("Failed to create session: " + err.Error()) } defer session.Close() // Once a Session is created, you can execute a single command on // the remote side using the Run method. var b bytes.Buffer session.Stdout = &b if err := session.Run("/usr/bin/whoami"); err != nil { panic("Failed to run: " + err.Error()) } fmt.Println(b.String()) }
func (s *sshTunnel) Start(readyErrCh chan<- error, errCh chan<- error) { authMethods := []ssh.AuthMethod{} if s.options.PrivateKey != "" { s.logger.Debug(s.logTag, "Reading private key file '%s'", s.options.PrivateKey) keyContents, err := ioutil.ReadFile(s.options.PrivateKey) if err != nil { readyErrCh <- bosherr.WrapErrorf(err, "Reading private key file '%s'", s.options.PrivateKey) return } s.logger.Debug(s.logTag, "Parsing private key file '%s'", s.options.PrivateKey) signer, err := ssh.ParsePrivateKey(keyContents) if err != nil { readyErrCh <- bosherr.WrapErrorf(err, "Parsing private key file '%s'", s.options.PrivateKey) return } authMethods = append(authMethods, ssh.PublicKeys(signer)) } if s.options.Password != "" { s.logger.Debug(s.logTag, "Adding password auth method to ssh tunnel config") keyboardInteractiveChallenge := func( user, instruction string, questions []string, echos []bool, ) (answers []string, err error) { if len(questions) == 0 { return []string{}, nil } return []string{s.options.Password}, nil } authMethods = append(authMethods, ssh.KeyboardInteractive(keyboardInteractiveChallenge)) authMethods = append(authMethods, ssh.Password(s.options.Password)) } sshConfig := &ssh.ClientConfig{ User: s.options.User, Auth: authMethods, } s.logger.Debug(s.logTag, "Dialing remote server at %s:%d", s.options.Host, s.options.Port) remoteAddr := fmt.Sprintf("%s:%d", s.options.Host, s.options.Port) retryStrategy := &SSHRetryStrategy{ TimeService: s.timeService, ConnectionRefusedTimeout: s.connectionRefusedTimeout, AuthFailureTimeout: s.authFailureTimeout, } var conn *ssh.Client var err error for i := 0; ; i++ { s.logger.Debug(s.logTag, "Making attempt #%d", i) conn, err = ssh.Dial("tcp", remoteAddr, sshConfig) if err == nil { break } if !retryStrategy.IsRetryable(err) { readyErrCh <- bosherr.WrapError(err, "Failed to connect to remote server") return } s.logger.Debug(s.logTag, "Attempt failed #%d: Dialing remote server: %s", i, err.Error()) time.Sleep(s.startDialDelay) } remoteListenAddr := fmt.Sprintf("127.0.0.1:%d", s.options.RemoteForwardPort) s.logger.Debug(s.logTag, "Listening on remote server %s", remoteListenAddr) s.remoteListener, err = conn.Listen("tcp", remoteListenAddr) if err != nil { readyErrCh <- bosherr.WrapError(err, "Listening on remote server") return } readyErrCh <- nil for { remoteConn, err := s.remoteListener.Accept() s.logger.Debug(s.logTag, "Received connection") if err != nil { errCh <- bosherr.WrapError(err, "Accepting connection on remote server") } defer func() { if err = remoteConn.Close(); err != nil { s.logger.Warn(s.logTag, "Failed to close remote listener connection: %s", err.Error()) } }() s.logger.Debug(s.logTag, "Dialing local server") localDialAddr := fmt.Sprintf("127.0.0.1:%d", s.options.LocalForwardPort) localConn, err := net.Dial("tcp", localDialAddr) if err != nil { errCh <- bosherr.WrapError(err, "Dialing local server") return } go func() { bytesNum, err := io.Copy(remoteConn, localConn) defer func() { if err = localConn.Close(); err != nil { s.logger.Warn(s.logTag, "Failed to close local dial connection: %s", err.Error()) } }() s.logger.Debug(s.logTag, "Copying bytes from local to remote %d", bytesNum) if err != nil { errCh <- bosherr.WrapError(err, "Copying bytes from local to remote") } }() go func() { bytesNum, err := io.Copy(localConn, remoteConn) defer func() { if err = localConn.Close(); err != nil { s.logger.Warn(s.logTag, "Failed to close local dial connection: %s", err.Error()) } }() s.logger.Debug(s.logTag, "Copying bytes from remote to local %d", bytesNum) if err != nil { errCh <- bosherr.WrapError(err, "Copying bytes from remote to local") } }() } }