什么是ssh?
SSH是一种网络协议,用于计算机之间的加密登录.
如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露.
互联网通信早期都是明文通信,一旦被截获,内容就暴露无疑. 1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广, 目前已经成为Linux系统的标准配置.
Go实现ssh执行远端命令
package mainimport ("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 clientaddr := 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-sessionsession, 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 mainimport ("fmt""golang.org/x/crypto/ssh""golang.org/x/crypto/ssh/terminal""io""log""net""os""time")type Cli struct {IP stringUsername stringPassword stringPort intclient *ssh.ClientLastResult string}func New(ip string, username string, password string, port ...int) *Cli {cli := new(Cli)cli.IP = ipcli.Username = usernamecli.Password = passwordswitch {case len(port) <= 0:cli.Port = 22case 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 = sshClientreturn 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 = stdoutsession.Stderr = stderrsession.Stdin = os.StdintermWidth, 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