// sendSshKeepAlive is a helper which sends a [email protected] request
// on the specified SSH connections and returns true of the request succeeds
// within a specified timeout.
func sendSshKeepAlive(
	sshClient *ssh.Client, conn net.Conn, timeout time.Duration) error {

	errChannel := make(chan error, 2)
	if timeout > 0 {
		time.AfterFunc(timeout, func() {
			errChannel <- TimeoutError{}
		})
	}

	go func() {
		// Random padding to frustrate fingerprinting
		_, _, err := sshClient.SendRequest(
			"*****@*****.**", true,
			MakeSecureRandomPadding(0, TUNNEL_SSH_KEEP_ALIVE_PAYLOAD_MAX_BYTES))
		errChannel <- err
	}()

	err := <-errChannel
	if err != nil {
		sshClient.Close()
		conn.Close()
	}

	return ContextError(err)
}
Example #2
0
func CopyFile(conn *ssh.Client, FileName, DirectoryPath string) bool {
	defer conn.Close()
	if !strings.HasSuffix(DirectoryPath, "/") {
		DirectoryPath = DirectoryPath + "/"
	}
	con, err := sftp.NewClient(conn, sftp.MaxPacket(5e9))
	if err != nil {
		color.Red("%s传输文件新建会话错误: %s\n", conn.RemoteAddr(), err)
		return false
	}
	sFile, _ := os.Open(FileName)
	defer sFile.Close()
	dFile := DirectoryPath + FileName
	fmt.Printf("%s 目标路径:%s\n", conn.RemoteAddr(), dFile)
	File, err := con.OpenFile(dFile, os.O_CREATE|os.O_TRUNC|os.O_RDWR)
	if err != nil {
		color.Red("%s 创建文件%s错误: %s \n", conn.RemoteAddr(), dFile, err)
		return false
	}
	defer File.Close()
	for {
		buf := make([]byte, 1024)
		n, err := sFile.Read(buf)
		if err != nil {
			if err.Error() == "EOF" {
				break
			}
			return false
		}
		File.Write(buf[:n])
	}
	Result <- fmt.Sprintf("上传%s到%s成功.\n", FileName, conn.RemoteAddr())
	return true
}
Example #3
0
func (n *SSHNode) getClientAndSession() (*ssh.Client, *ssh.Session, error) {
	var client *ssh.Client
	var s *ssh.Session
	var err error

	// Retry few times if ssh connection fails
	for i := 0; i < MaxSSHRetries; i++ {
		client, err = n.dial()
		if err != nil {
			time.Sleep(SSHRetryDelay)
			continue
		}

		s, err = client.NewSession()
		if err != nil {
			client.Close()
			time.Sleep(SSHRetryDelay)
			continue
		}
		modes := ssh.TerminalModes{
			ssh.ECHO:          0,
			ssh.TTY_OP_ISPEED: 14400,
			ssh.TTY_OP_OSPEED: 14400,
		}
		// Request pseudo terminal
		if err := s.RequestPty("xterm", 40, 80, modes); err != nil {
			return nil, nil, fmt.Errorf("failed to get pseudo-terminal: %v", err)
		}

		return client, s, nil
	}

	return nil, nil, err
}
Example #4
0
func handleLocalSshConn(lnConn net.Conn) {
	defer func() {
		if Config.Ssh_Reverse_Proxy.Exit_On_Panic {
			return
		}
		if r := recover(); r != nil {
			Log.Error("Recovered from panic in connection from "+
				lnConn.RemoteAddr().String()+":", r)
		}
	}()

	Log.Info("Received connection from", lnConn.RemoteAddr())

	var sClient *ssh.Client
	psConfig := getProxyServerSshConfig(&sClient)
	psConn, psChans, psReqs, err := ssh.NewServerConn(lnConn, psConfig)
	if err != nil {
		Log.Info("Could not establish connection with " + lnConn.RemoteAddr().String() + ": " + err.Error())
		return
	}
	defer psConn.Close()
	defer sClient.Close()

	go ssh.DiscardRequests(psReqs)

	for newChannel := range psChans {
		handleChannel(newChannel, sClient)
	}

	Log.Info("Lost connection with", lnConn.RemoteAddr())
}
Example #5
0
func (n *SSHNode) getClientAndSession() (*ssh.Client, *ssh.Session, error) {
	var client *ssh.Client
	var s *ssh.Session
	var err error

	// Retry few times if ssh connection fails
	for i := 0; i < MaxSSHRetries; i++ {
		client, err = n.dial()
		if err != nil {
			time.Sleep(SSHRetryDelay)
			continue
		}

		s, err = client.NewSession()
		if err != nil {
			client.Close()
			time.Sleep(SSHRetryDelay)
			continue
		}

		return client, s, nil
	}

	return nil, nil, err
}
Example #6
0
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result execResult) {
	result.Servername = c.ServerName
	result.Host = c.Host
	result.Port = c.Port

	var client *ssh.Client
	var err error
	if client, err = sshConnect(c); err != nil {
		result.Error = err
		result.ExitStatus = 999
		return
	}
	defer client.Close()

	var session *ssh.Session
	if session, err = client.NewSession(); err != nil {
		result.Error = fmt.Errorf(
			"Failed to create a new session. servername: %s, err: %s",
			c.ServerName, err)
		result.ExitStatus = 999
		return
	}
	defer session.Close()

	// http://blog.ralch.com/tutorial/golang-ssh-connection/
	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
	}
	if err = session.RequestPty("xterm", 400, 256, modes); err != nil {
		result.Error = fmt.Errorf(
			"Failed to request for pseudo terminal. servername: %s, err: %s",
			c.ServerName, err)
		result.ExitStatus = 999
		return
	}

	var stdoutBuf, stderrBuf bytes.Buffer
	session.Stdout = &stdoutBuf
	session.Stderr = &stderrBuf

	cmd = decolateCmd(c, cmd, sudo)
	if err := session.Run(cmd); err != nil {
		if exitErr, ok := err.(*ssh.ExitError); ok {
			result.ExitStatus = exitErr.ExitStatus()
		} else {
			result.ExitStatus = 999
		}
	} else {
		result.ExitStatus = 0
	}

	result.Stdout = stdoutBuf.String()
	result.Stderr = stderrBuf.String()
	result.Cmd = strings.Replace(cmd, "\n", "", -1)
	return
}
Example #7
0
func Run(Con *ssh.Client, cmd string) {
	defer Con.Close()
	s, err := Con.NewSession()
	if err != nil {
		color.Red("%s:新建会话失败.命令未执行.", Con.RemoteAddr())
		return
	}
	fmt.Printf("成功连接:%s\n", Con.RemoteAddr())
	buf, err := s.Output(cmd)
	if err != nil {
		color.Red("%s:命令执行失败.", Con.RemoteAddr())
		return
	}
	str := fmt.Sprintf("%s 的执行结果:\n%s\n", Con.RemoteAddr().String(), string(buf))
	fmt.Println(str)
	Result <- str
}
Example #8
0
func client(info cmd_info, result chan string, num chan int32, returnnum *int32) {
	defer func() {
		time.Sleep(1e9)
		num <- atomic.AddInt32(returnnum, -1)
	}()

	config := &ssh.ClientConfig{
		User: info.user,
		Auth: []ssh.AuthMethod{
			ssh.Password(info.passwd),
		},
	}
	var client *ssh.Client
	var err error
	for i := 0; i < 5; i++ {
		client, err = ssh.Dial("tcp", info.ip, config)
		if err == nil {
			break
		}
	}
	if err != nil {
		fmt.Printf("%s 建立连接: %s\n", info.ip, err)
		return
	}
	defer client.Close()
	for _, v := range info.cmds {
		session, err := client.NewSession()
		if err != nil {
			fmt.Println("%s 创建Session出错: %s\n", info.ip, err)
			return
		}
		defer session.Close()
		buf, err := session.Output(v)
		if err != nil {
			fmt.Printf("%s 执行命令:%s出错:%s\n", info.ip, v, err)
			continue
		}
		result <- fmt.Sprintf("remote_PC:%s CMD:%s\n%s", info.ip, v, buf)
	}
}
Example #9
0
func TtyClient(Con *ssh.Client) error {
	defer Con.Close()
	session, err := Con.NewSession()
	if err != nil {
		return err
	}
	session.Stdout = os.Stdout
	session.Stderr = os.Stderr
	session.Stdin = os.Stdin

	modes := ssh.TerminalModes{
		ssh.ECHO:          0,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}
	err = session.RequestPty("xterm", 25, 100, modes)
	if err != nil {
		return err
	}
	session.Shell()
	return session.Wait()
}
Example #10
0
func scp(Client *ssh.Client, File io.Reader, size int64, path string) {
	filename := filepath.Base(path)
	dirname := strings.Replace(filepath.Dir(path), "\\", "/", -1)
	defer Client.Close()

	session, err := Client.NewSession()
	if err != nil {
		fmt.Println("创建Session失败:", err)
		return
	}
	go func() {
		w, _ := session.StdinPipe()
		fmt.Fprintln(w, "C0644", size, filename)
		io.CopyN(w, File, size)
		fmt.Fprint(w, "\x00")
		w.Close()
	}()

	if err := session.Run(fmt.Sprintf("/usr/bin/scp -qrt %s", dirname)); err != nil {
		fmt.Println("执行scp命令失败:", err)
		session.Close()
		return
	} else {
		fmt.Printf("%s 发送成功.\n", Client.RemoteAddr())
		session.Close()
	}

	if session, err = Client.NewSession(); err == nil {
		defer session.Close()
		buf, err := session.Output(fmt.Sprintf("/usr/bin/md5sum %s", path))
		if err != nil {
			fmt.Println("检查md5失败:", err)
			return
		}
		fmt.Printf("%s 的MD5:\n%s\n", Client.RemoteAddr(), string(buf))
	}
}
Example #11
0
func CopyFile(conn *ssh.Client, FileName, DirectoryPath string) bool {
	defer conn.Close()
	if !strings.HasSuffix(DirectoryPath, "/") {
		DirectoryPath = DirectoryPath + "/"
	}
	con, err := sftp.NewClient(conn, sftp.MaxPacket(5e9))
	if err != nil {
		if debug {
			fmt.Println(err)
		}
		return false
	}
	sFile, _ := os.Open(FileName)
	defer sFile.Close()
	dFile := DirectoryPath + FileName
	File, err := con.OpenFile(dFile, os.O_CREATE|os.O_TRUNC|os.O_RDWR)
	if err != nil {
		if debug {
			fmt.Println(err)
		}
		return false
	}
	defer File.Close()
	for {
		buf := make([]byte, 1024)
		n, err := sFile.Read(buf)
		if err != nil {
			if err.Error() == "EOF" {
				break
			}
			return false
		}
		File.Write(buf[:n])
	}
	return true
}
Example #12
0
// NewSession will open an ssh session using the provided connection
func NewSession(client *ssh.Client) (*Session, error) {
	session, err := client.NewSession()
	if err != nil {
		return nil, err
	}

	s := &Session{ssh: session, client: client}

	// Set up terminal modes
	modes := ssh.TerminalModes{
		ssh.ECHO:          0,      // disable echoing
		ssh.TTY_OP_ISPEED: 115200, // input speed  = 115.2kbps
		ssh.TTY_OP_OSPEED: 115200, // output speed = 115.2kbps
	}
	// Request pseudo terminal
	if err := session.RequestPty(termType, 80, 40, modes); err != nil {
		client.Close()
		return nil, err
	}

	session.Stdout = &s.out
	session.Stderr = &s.err
	return s, nil
}
		serverNetConn, clientNetConn := test_helpers.Pipe()

		sshd = daemon.New(logger, serverSSHConfig, nil, newChannelHandlers)
		connectionFinished = make(chan struct{})
		go func() {
			sshd.HandleConnection(serverNetConn)
			close(connectionFinished)
		}()

		client = test_helpers.NewClient(clientNetConn, nil)
	})

	AfterEach(func() {
		if client != nil {
			err := client.Close()
			Expect(err).NotTo(HaveOccurred())
		}
		Eventually(connectionFinished).Should(BeClosed())
	})

	Context("when a session is opened", func() {
		var session *ssh.Session

		BeforeEach(func() {
			var sessionErr error
			session, sessionErr = client.NewSession()

			Expect(sessionErr).NotTo(HaveOccurred())
		})
Example #14
0
func forward(localConn net.Conn, config *ssh.ClientConfig, serverAddrString, remoteAddrString string) {

	defer localConn.Close()
	currentRetriesServer := 0
	currentRetriesRemote := 0
	var sshClientConnection *ssh.Client = nil

	// Loop for retries:
	for {

		// Try to connect to the SSH server:
		if sshClientConn, err := ssh.Dial(`tcp`, serverAddrString, config); err != nil {

			// Failed:
			currentRetriesServer++
			log.Printf("Was not able to connect with the SSH server %s: %s\n", serverAddrString, err.Error())

			// Is a retry alowed?
			if currentRetriesServer < maxRetriesServer {
				log.Println(`Retry...`)
				time.Sleep(1 * time.Second)
			} else {

				// After the return, this thread is closed down. The client can try it again...
				log.Println(`No more retries for connecting the SSH server.`)
				return
			}

		} else {

			// Success:
			log.Println(`Connected to the SSH server ` + serverAddrString)
			sshClientConnection = sshClientConn
			defer sshClientConnection.Close()
			break
		}
	}

	// Loop for retries:
	for {

		// Try to create the remote end-point:
		if sshConn, err := sshClientConnection.Dial(`tcp`, remoteAddrString); err != nil {

			// Failed:
			currentRetriesRemote++
			log.Printf("Was not able to create the remote end-point %s: %s\n", remoteAddrString, err.Error())

			// Is another retry allowed?
			if currentRetriesRemote < maxRetriesRemote {
				log.Println(`Retry...`)
				time.Sleep(1 * time.Second)
			} else {

				// After the return, this thread is closed down. The client can try it again...
				log.Println(`No more retries for connecting the remote end-point.`)
				return
			}
		} else {

			// Fine, the connections are up and ready :-)
			log.Printf("The remote end-point %s is connected.\n", remoteAddrString)
			defer sshConn.Close()

			// To be able to close down both transfer threads, we create a channel:
			quit := make(chan bool)

			// Create the transfers to/from both sides (two new threads are created for this):
			go transfer(localConn, sshConn, `Local => Remote`, quit)
			go transfer(sshConn, localConn, `Remote => Local`, quit)

			// Wait and look if any of the two transfer theads are down:
			isRunning := true
			for isRunning {
				select {
				case <-quit:
					log.Println(`At least one transfer was stopped.`)
					isRunning = false
					break
				}
			}

			// Now, close all the channels and therefore, force the other / second thread to go down:
			log.Println(`Close now all connections.`)
			return
		}
	}
}
		handler.HandleNewChannelStub = testHandler.HandleNewChannel

		newChannelHandlers := map[string]handlers.NewChannelHandler{
			"direct-tcpip": handler,
		}

		serverNetConn, clientNetConn := test_helpers.Pipe()

		sshd = daemon.New(logger, serverSSHConfig, nil, newChannelHandlers)
		go sshd.HandleConnection(serverNetConn)

		client = test_helpers.NewClient(clientNetConn, nil)
	})

	AfterEach(func() {
		client.Close()
		echoServer.Shutdown()
	})

	Context("when a session is opened", func() {
		var conn net.Conn

		JustBeforeEach(func() {
			var dialErr error
			conn, dialErr = client.Dial("tcp", echoAddress)
			Expect(dialErr).NotTo(HaveOccurred())
		})

		AfterEach(func() {
			conn.Close()
		})
Example #16
0
	AfterEach(func() {
		if sshClient != nil {
			// restart addon_update with the default options
			switch framework.TestContext.OSDistro {
			case "debian":
				sshExec(sshClient, "sudo /etc/init.d/kube-addons restart")
			case "trusty":
				sshExec(sshClient, "sudo initctl restart kube-addons")
			case "coreos":
				sshExec(sshClient, "sudo systemctl unset-environment TEST_ADDON_CHECK_INTERVAL_SEC")
				sshExec(sshClient, "sudo systemctl restart kubernetes-addons")
			default:
				framework.Failf("Unsupported OS distro type %s", framework.TestContext.OSDistro)
			}
			sshClient.Close()
		}
	})

	// WARNING: the test is not parallel-friendly!
	It("should propagate add-on file changes", func() {
		// This test requires:
		// - SSH
		// - master access
		// ... so the provider check should be identical to the intersection of
		// providers that provide those capabilities.
		framework.SkipUnlessProviderIs("gce")

		//these tests are long, so I squeezed several cases in one scenario
		Expect(sshClient).NotTo(BeNil())
		dir = f.Namespace.Name // we use it only to give a unique string for each test execution
Example #17
0
func (s *BotClientT) Start(botId string, botInstance int, cmdline string, cfg *ConfigT, debugLevel int) error {
	var err error
	var sshclient *ssh.Client
	var session *ssh.Session
	//   var wg         sync.WaitGroup
	var cmd string

	if s.Host[botInstance].Status == BotStatPaused {
		return nil
	}

	if s.Host[botInstance].Status == BotStatRunning {
		err = s.PingAt(botId, botInstance, cfg)
		if err == nil {
			Goose.Ping.Logf(2, "bot %s@%s is alive", botId, s.Host[botInstance].Name)
			return nil
		}
	}

	Goose.StartStop.Logf(2, "Starting bot %s@%s", botId, s.Host[botInstance].Name)

	s.Host[botInstance].Status = BotStatUnreachable
	if s.Host[botInstance].OnStatUpdate != nil {
		s.Host[botInstance].OnStatUpdate(BotStatUnreachable)
	}

	cfg.SshClientConfig.User = s.SysUser

	sshclient, err = ssh.Dial("tcp", s.Host[botInstance].Name+":22", cfg.SshClientConfig)
	if err != nil {
		Goose.StartStop.Logf(1, "%s (%s)", ErrDialingToBot, err)
		return ErrDialingToBot
	}
	defer sshclient.Close()

	Goose.StartStop.Logf(3, "Dialed to bot %s@%s", botId, s.Host[botInstance].Name)

	session, err = sshclient.NewSession()
	if err != nil {
		Goose.StartStop.Logf(1, "%s (%s)", ErrCreatingSession, err)
		return ErrCreatingSession
	}
	defer session.Close()

	Goose.StartStop.Logf(3, "Session started at bot %s@%s", botId, s.Host[botInstance].Name)

	/*
	   wg.Add(1)

	   go func() {
	      defer wg.Done()
	      w, _ := session.StdinPipe()
	      defer w.Close()
	      Goose.StartStop.Logf(2,"Closing stdin for bot %s",botId)
	      //fmt.Fprintf(w, "%s\n", config)
	   }()
	*/

	/*
	   // 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 {
	      Goose.StartStop.Fatalf(1,"request for pseudo terminal failed: %s", err)
	   }


	   session.Stdout = &bytes.Buffer{}
	   session.Stderr = &bytes.Buffer{}
	*/

	cmd = fmt.Sprintf("%s%c%s -v %d %s", s.BinDir, os.PathSeparator, s.BinName, debugLevel, cmdline)
	Goose.StartStop.Logf(3, "Will run %s@%s using %s", botId, s.Host[botInstance].Name, cmd)

	err = session.Start(cmd)
	//   err = session.Run(cmd)
	Goose.StartStop.Logf(2, "Running bot %s", botId)
	//   wg.Wait()

	if err != nil {
		session.Signal(ssh.SIGKILL)
		Goose.StartStop.Logf(1, "%s (%s)", ErrFailedStartingBot, err)
		return ErrFailedStartingBot
	}

	Goose.StartStop.Logf(2, "Started bot %s with cmd:[%s]", botId, cmd)

	s.Host[botInstance].Status = BotStatRunning
	if s.Host[botInstance].OnStatUpdate != nil {
		s.Host[botInstance].OnStatUpdate(BotStatRunning)
	}

	return nil
}
Example #18
-1
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (result sshResult) {
	logger := getSSHLogger(log...)

	cmd = decolateCmd(c, cmd, sudo)
	logger.Debugf("Command: %s",
		strings.Replace(maskPassword(cmd, c.Password), "\n", "", -1))

	var client *ssh.Client
	var err error
	client, err = sshConnect(c)
	defer client.Close()

	var session *ssh.Session
	if session, err = client.NewSession(); err != nil {
		logger.Errorf("Failed to new session. err: %s, c: %s",
			err,
			pp.Sprintf("%v", c))
		result.ExitStatus = 999
		return
	}
	defer session.Close()

	// http://blog.ralch.com/tutorial/golang-ssh-connection/
	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
	}
	if err = session.RequestPty("xterm", 400, 256, modes); err != nil {
		logger.Errorf("Failed to request for pseudo terminal. err: %s, c: %s",
			err,
			pp.Sprintf("%v", c))

		result.ExitStatus = 999
		return
	}

	var stdoutBuf, stderrBuf bytes.Buffer
	session.Stdout = &stdoutBuf
	session.Stderr = &stderrBuf

	if err := session.Run(cmd); err != nil {
		if exitErr, ok := err.(*ssh.ExitError); ok {
			result.ExitStatus = exitErr.ExitStatus()
		} else {
			result.ExitStatus = 999
		}
	} else {
		result.ExitStatus = 0
	}

	result.Stdout = stdoutBuf.String()
	result.Stderr = stderrBuf.String()
	result.Host = c.Host
	result.Port = c.Port

	logger.Debugf(
		"SSH executed. cmd: %s, err: %#v, status: %d\nstdout: \n%s\nstderr: \n%s",
		maskPassword(cmd, c.Password), err, result.ExitStatus, result.Stdout, result.Stderr)

	return
}