zoukankan      html  css  js  c++  java
  • Go实现ssh执行远端命令及远程终端

    什么是ssh?

    SSH是一种网络协议,用于计算机之间的加密登录.

    如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露.

    互联网通信早期都是明文通信,一旦被截获,内容就暴露无疑. 1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广, 目前已经成为Linux系统的标准配置.

    Go实现ssh执行远端命令

    package main
    
    import (
    	"fmt"
    	"golang.org/x/crypto/ssh"
    	"log"
    	"time"
    )
    
    func main(){
    	sshHost := ""
    	sshUser := "root"
    	sshPassword := ""
    	sshType := "password"
    	sshPort := 22
    
    
    	//创建sshp登陆配置
    	config := &ssh.ClientConfig{
    		Timeout:         time.Second,//ssh 连接time out 时间一秒钟, 如果ssh验证错误 会在一秒内返回
    		User:            sshUser,
    		HostKeyCallback: ssh.InsecureIgnoreHostKey(), //这个可以, 但是不够安全
    		//HostKeyCallback: hostKeyCallBackFunc(h.Host),
    	}
    	if sshType == "password" {
    		config.Auth = []ssh.AuthMethod{ssh.Password(sshPassword)}
    	}
    
    
    
    	//dial 获取ssh client
    	addr := fmt.Sprintf("%s:%d", sshHost, sshPort)
    	sshClient, err := ssh.Dial("tcp", addr, config)
    	if err != nil {
    		log.Fatal("创建ssh client 失败",err)
    	}
    	defer sshClient.Close()
    
    
    	//创建ssh-session
    	session, err := sshClient.NewSession()
    	if err != nil {
    		log.Fatal("创建ssh session 失败",err)
    	}
    	defer session.Close()
    	//执行远程命令
    	combo,err := session.CombinedOutput("whoami; cd /; ls -al;echo https://github.com/libragen/felix")
    	if err != nil {
    		log.Fatal("远程执行cmd 失败",err)
    	}
    	log.Println("命令输出:",string(combo))
    
    }
    
    

    Go实现一个远程终端

    package main
    
    import (
    	"fmt"
    	"golang.org/x/crypto/ssh"
    	"golang.org/x/crypto/ssh/terminal"
    	"io"
    	"log"
    	"net"
    	"os"
    	"time"
    )
    
    type Cli struct {
    	IP string
    	Username string
    	Password string
    	Port int
    	client *ssh.Client
    	LastResult string
    }
    
    func New(ip string, username string, password string, port ...int) *Cli  {
    	cli := new(Cli)
    	cli.IP = ip
    	cli.Username = username
    	cli.Password = password
    	switch  {
    	case len(port) <= 0:
    		cli.Port = 22
    	case len(port) > 0:
    		cli.Port = port[0]
    	}
    	return cli
    }
    
    func (c *Cli) connect() error  {
    	config := ssh.ClientConfig{
    		User: c.Username,
    		Auth: []ssh.AuthMethod{ssh.Password(c.Password)},
    		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
    			return nil
    		},
    		Timeout: 10 * time.Second,
    	}
    	addr := fmt.Sprintf("%s:%d", c.IP,c.Port)
    	sshClient, err := ssh.Dial("tcp",addr,&config)
    	if err != nil {
    		return err
    	}
    	c.client = sshClient
    	return nil
    }
    
    func (c *Cli) RunTerminal(stdout, stderr io.Writer) error  {
    	if c.client == nil {
    		if err := c.connect(); err != nil {
    			return err
    		}
    	}
    	session, err := c.client.NewSession()
    	if err != nil {
    		return err
    	}
    	defer session.Close()
    
    	fd := int(os.Stdin.Fd())
    	oldState,err := terminal.MakeRaw(fd)
    	if err != nil {
    		panic(err)
    	}
    	defer terminal.Restore(fd,oldState)
    
    	session.Stdout = stdout
    	session.Stderr = stderr
    	session.Stdin = os.Stdin
    
    	termWidth, termHeight, err := terminal.GetSize(fd)
    	if err != nil {
    		panic(err)
    	}
    
    	modes := ssh.TerminalModes{
    		ssh.ECHO: 1,
    		ssh.TTY_OP_ISPEED: 14400,
    		ssh.TTY_OP_OSPEED: 14400,
    	}
    	if err := session.RequestPty("xterm-256color", termHeight,termWidth,modes); err != nil {
    		return err
    	}
    	session.Shell()
    	session.Wait()
    	return nil
    }
    
    func main()  {
    	cli := New("IP","用户名","密码",22)
    	err := cli.RunTerminal( os.Stdout, os.Stdin)
    	if err != nil {
    		log.Fatal(err)
    	}
    }
    

    1

  • 相关阅读:
    自动化:Appium运行成功,取得一个小的胜利
    调优案例1
    HTTP请求方式中8种请求方法(简单介绍)
    Java中基本类型和引用类型(简单介绍)
    @WebListener 注解方式实现监听(eclipse和idea)
    Git免密码提交
    在idea配置jetty和创建(包、文件)javaWeb以及Servlet简单实现
    emmet工具使用和技巧
    Markdown基本语法总结
    viewport原理和使用和设置移动端自适应的方法(移动适应电脑)
  • 原文地址:https://www.cnblogs.com/you-men/p/14163364.html
Copyright © 2011-2022 走看看