返回顶部
首页 > 资讯 > 后端开发 > GO >Golang实现SSH、SFTP等相关操作
  • 777
分享到

Golang实现SSH、SFTP等相关操作

sshgolang服务器 2023-09-05 07:09:00 777人浏览 独家记忆
摘要

1.1 前言 在日常的一些开发场景中,我们需要去和远程服务器进行一些通信,执行一些相关命令操作,这个时候我们就可以使用ssh协议实现目标。SSH协议是建立在应用层上的安全协议,全称为Secure

1.1 前言

在日常的一些开发场景中,我们需要去和远程服务器进行一些通信,执行一些相关命令操作,这个时候我们就可以使用ssh协议实现目标。SSH协议是建立在应用层上的安全协议,全称为Secure shell,采用的是面向连接的tcp协议进行传输,也就意味着它是安全可靠的。需要注意的是文件传输并不能在SSH协议上完成,需要在下面提到的SFTP协议完成。

1.2 Go实现

Go官方为我们提供了用于实现SSH连接的package,位于golang.org/x/crypto下,通过在程序中调用包中提供的相关方法,便可以实现与其他机器进行通信。使用前我们需要使用go get导入相关的依赖包。

go get golang.org/x/crypto/ssh

1.2.1 配置相关参数

在进行通信之前,我们还需要配置一些用于配置一些用于建立连接的相关参数。ssh包下的ClientConfig结构体中,定义了建立SSH连接需要用到的一些配置项,部分项提供了默认参数,我们使用时可以不进行声明。

下面的代码段中,我们首先是声明了用户名和密码,连接超时时间设置为10秒钟,addr变量定义了目标机器的IP地址以及端口。

HosTKEyCallback项,我们设置了忽略,这是因为SSH协议为客户端提供了两种安全验证方式,一种是基于口令的安全验证,也就是我们常常使用的账号密码形式,另外一种则是基于密钥的安全验证,相较于第一种,这种形式的校验方法极大的提升了安全等级,缺点则是时间损耗相对较长。

如果需要使用这种方式进行校验,首先我们需要在服务器上为自己创建一对密钥,作为客户端进行访问时,首先会向服务端发送安全验证请求,服务端收到请求后,首先会将机器上保存的公钥与客户端发送的公钥进行比较,如果一致,服务端则会向客户端响应加密质询,客户端接受到质询之后,使用私钥进行解密,然后再将解密结果发送给服务端,服务端进行校验后再返回响应结果,到这里就算是完成了一段密钥校验。

        //添加配置        config := &ssh.ClientConfig{                User: "root",                Auth: []ssh.AuthMethod{ssh.PassWord("Password")},                HostKeyCallback: ssh.InsecureIgnoreHostKey(),                Timeout: 10 * time.Second,            }        }        addr := fmt.Sprintf("%v:%v", IP, Port)

1.2.2 建立连接

在完成了所有的参数初始化之后,我们便可以调用Dial方法建立SSH连接。Dial方法一共有三个参数和两个返回值,第一个参数network为网络类型,这里我们使用面向连接的TCP协议,第二个参数addr则为目标机器的IP地址和端口号,第三个参数config则为前面我们生命的配置项。Dial会返回一个SSH连接和错误类型。

func Dial(network, addr string, config *ClientConfig) (*Client, error)

        //建立SSH连接        sshClient, err := ssh.Dial("tcp", addr, config)        if err != nil {            log.Fatal("unable to create ssh conn")        }

1.2.3 创建会话

在建立了与目标机器的SSH连接之后,我们就可以通过创建SSH会话来与目标机器进行通信。通过NewSession()方法便可以实现这一操作。

        //建立SSH会话        sshSession, err := sshClient.NewSession()        if err != nil {           log.Fatal("unable to create ssh session")        }

1.2.4 执行操作

与目标机器建立会话后,我们就可以通过执行命令等来操作远程服务器。Go目前为我们提供了五个用于操作远程机器的方法,分别是Run(), Start(), Output(), CombineOutpt(), Shell()

🦫其中 Output(), **CombineOutpt()**这两个方法是对Run()方法进行不同程度上的封装,校验了输出流,错误流等相关内容。

        // Output runs cmd on the remote host and returns its standard output.        func (s *Session) Output(cmd string) ([]byte, error) {           if s.Stdout != nil {              return nil, errors.New("ssh: Stdout already set")           }           var b bytes.Buffer           s.Stdout = &b           err := s.Run(cmd)           return b.Bytes(), err        }                        // CombinedOutput runs cmd on the remote host and returns its combined        // standard output and standard error.        func (s *Session) CombinedOutput(cmd string) ([]byte, error) {           if s.Stdout != nil {              return nil, errors.New("ssh: Stdout already set")           }           if s.Stderr != nil {              return nil, errors.New("ssh: Stderr already set")           }           var b singleWriter           s.Stdout = &b           s.Stderr = &b           err := s.Run(cmd)           return b.b.Bytes(), err        }

Run()方法则是对Start()方法进行了封装,添加了Wait方法,用于校验远程服务器的退出指令。Wait()方法中有一个管道类型的变量exitStatus,它是用来保存每次执行命令后,机器返回的退出状态的。有兴趣的朋友可以去看看这块的代码,这里就不贴代码了。

这里面有一个坑,如果我们在远程机器上去运行一个永远不会停止的程序,这个时候我们的程序一直等待不到远程机器发送的退出指令,就会造成程序一直阻塞而无法正常返回。解决的办法是用一个协程去单独执行这一块的任务,或者是使用定时器来定时结束session会话,来正常返回。

Start()方法与Shell方法一致,都是返回一个error类型,在底层都是调用了start()方法和SendRequest方法,关于这两个方法的内容这里就不做详细介绍了,有兴趣的朋友可以自行去阅读。唯一的区别是Start()方法有一个string类型的参数,用于接收用户输入的参数,而Shell()方法是无参数的。

使用Shell()方法配合RequestPty()等方法可以在本地建立一个伪终端,可以直接通过输入命令的形式操作目标机器。下面都会做一个示例。

        //Run        func (s *Session) Run(cmd string) error {           err := s.Start(cmd)           if err != nil {              fmt.Println(err)              return err           }           return s.Wait()                }            // Start runs cmd on the remote host. Typically, the remote        // server passes cmd to the shell for interpretation.        // A Session only accepts one call to Run, Start or Shell.        func (s *Session) Start(cmd string) error {           if s.started {              return errors.New("ssh: session already started")           }           req := execMsg{              Command: cmd,           }                   ok, err := s.ch.SendRequest("exec", true, Marshal(&req))           if err == nil && !ok {              err = fmt.Errorf("ssh: command %v failed", cmd)           }           if err != nil {              return err           }           return s.start()        }

1.2.5 示例代码(执行命令)

这里我们使用Run()方法来演示一下如果去执行命令,其他方法类型就不做演示了。这里我们使用一个标准输出流、错误流来保存执行结果。

这里演示了一个简单的执行过程,使用了cd命令到/home/min目录下,在给helloworld程序添加可执行权限,最后运行程序。

        var stdoutBuf, stderrBuf bytes.Buffer        session.Stdout = &stdoutBuf        session.Stderr = &stderrBuf            // cd /home/min        // chmod +x helloworld        // ./helloworld        cmd := fmt.Sprintf("cd %v ; chmod +x %v ; %v &", "/home/min", "helloworld", ./helloworld)        err := session.Run(cmd)        if err != nil {            log.Fatal("[ERROR]: ", session.Stderr, err)        }

1.2.6(创建伪终端)

        // 设置Terminal Modemodes := ssh.TerminalModes{ssh.ECHO:          0,     // 关闭回显ssh.TTY_OP_ISPEED: 14400, // 设置传输速率ssh.TTY_OP_OSPEED: 14400,}            // 请求伪终端err = session.RequestPty("linux", 32, 160, modes)if err != nil {log.Println(err)return}            // 设置输入输出session.Stdout = os.Stdoutsession.Stdin = os.Stdinsession.Stderr = os.Stderr session.Shell() // 启动shellsession.Wait()  // 等待退出

1.2.7 完整代码

//机器平台信息type Machine struct {   IP       string   Port     string   Username string   Password string}//建立SSH连接func CreateSSHConn(m *model.Machine) error {   //初始化连接信息   config := &ssh.ClientConfig{      User:            m.Username,      Auth:            []ssh.AuthMethod{ssh.Password(m.Password)},      HostKeyCallback: ssh.InsecureIgnoreHostKey(),      Timeout:         10 * time.Second,   }   addr := fmt.Sprintf("%v:%v", m.IP, m.Port)   //建立ssh连接   sshClient, err := ssh.Dial("tcp", addr, config)   if err != nil {      fmt.Println("unable create ssh conn", err)      return err   }   defer sshClient.Close()      //建立ssh会话   session, err := sshClient.NewSession()   if err != nil {      fmt.Println("unable create ssh conn", err)      return err   }   defer session.Close()         //执行命令   var stdoutBuf, stderrBuf bytes.Buffer   session.Stdout = &stdoutBuf   session.Stderr = &stderrBuf      cmd := fmt.Sprintf("cd %v ; chmod +x %v ; %v &", "/home/min", "helloworld", ./helloworld)   if err := session.Run(cmd); err != nil {       log.Fatal("[ERROR]: ", session.Stderr, err)   }     //创建伪终端   // 设置Terminal Mode   modes := ssh.TerminalModes{           ssh.ECHO:          0,     // 关闭回显           ssh.TTY_OP_ISPEED: 14400, // 设置传输速率           ssh.TTY_OP_OSPEED: 14400,   }         // 请求伪终端   err = session.RequestPty("linux", 32, 160, modes)   if err != nil {           log.Fatal(err)   }         // 设置输入输出   session.Stdout = os.Stdout   session.Stdin = os.Stdin   session.Stderr = os.Stderr      session.Shell() // 启动shell   session.Wait()  // 等待退出      return err}

来源地址:https://blog.csdn.net/qq_44445809/article/details/129797933

您可能感兴趣的文档:

--结束END--

本文标题: Golang实现SSH、SFTP等相关操作

本文链接: https://lsjlt.com/news/394810.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Golang实现SSH、SFTP等相关操作
    1.1 前言 在日常的一些开发场景中,我们需要去和远程服务器进行一些通信,执行一些相关命令操作,这个时候我们就可以使用SSH协议实现目标。SSH协议是建立在应用层上的安全协议,全称为Secure ...
    99+
    2023-09-05
    ssh golang 服务器
  • GoLang channel关闭状态相关操作详解
    关于 channel 的使用,有几点不方便的地方: 1.在不改变 channel 自身状态的情况下,无法获知一个 channel 是否关闭。 2.关闭一个 closed channe...
    99+
    2024-04-02
  • Linux中怎么实现Tomcat和Mysql相关操作
    本篇文章为大家展示了Linux中怎么实现Tomcat和Mysql相关操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。/home/mysql/3306/sql-ma...
    99+
    2024-04-02
  • Android 控制wifi 相关操作实例
    Android 控制WIFI相关操作 WIFI的全称是Wireless Fidelity,又称802.11b标准,是一种高速的无线通信协议,传输速度可以达到11Mb/s。 实际...
    99+
    2022-06-06
    Android
  • Java实现二分查找树及其相关操作
    二分查找树(Binary Search Tree)的基本操作有搜索、求最大值、求最小值、求前驱、求后继、插入及删除。 对二分查找树的进行基本操作所花费的时间与树的高度成比例。例如有n...
    99+
    2024-04-02
  • 大数据之Kafka————java来实现kafka相关操作
    一、在java中配置pom junit junit 4.11 test org.apache.kafka kafka-clients 2.8....
    99+
    2023-09-23
    大数据 kafka java
  • 有效使用ADO操作相关实现是怎样的
    本篇文章给大家分享的是有关有效使用ADO操作相关实现是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。其中路径名可以根据自己系统安装的ADO支持文件的路径来自行设定。当编译...
    99+
    2023-06-17
  • golang怎么实现mysql操作
    这篇文章主要介绍“golang怎么实现mysql操作”,在日常操作中,相信很多人在golang怎么实现mysql操作问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”golang怎么实现mysql操作”的疑惑有所...
    99+
    2023-07-06
  • python对json的相关操作实例详解
    本文实例分析了python对json的相关操作。分享给大家供大家参考,具体如下: 什么是json: JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和...
    99+
    2022-06-04
    详解 实例 操作
  • Python中怎么实现字符和字符串相关操作
    这篇文章给大家介绍Python中怎么实现字符和字符串相关操作,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Python字符(数位,字母和符号,比如$\@,%和*)是python程序的基本构件。每个程序都由字符构成。这些...
    99+
    2023-06-17
  • VB.NET实现接口的相关操作方法是怎样的
    VB.NET实现接口的相关操作方法是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。开发人员在应用VB.NET进行实际开发的时候,发现其中有不少跟其他语言不一样的地方,...
    99+
    2023-06-17
  • Golang 实现获取当前函数名称和文件行号等操作
    大家还是直接看代码吧~ // 获取正在运行的函数名 func runFuncName()string{ pc := make([]uintptr,1) runti...
    99+
    2024-04-02
  • Golang操作Kafka的实现示例
    目录一.使用库说明二.Kafka Producer发送消息三.Kafka Consumer消费消息一.使用库说明 Golang中连接kafka可以使用第三方库:github.com/...
    99+
    2023-02-19
    Golang操作Kafka Golang Kafka
  • Mybatis-Plus自动填充更新操作相关字段的实现
    目录场景介绍 自动填充处理器 Mybatis-Plus配置类 配置实体类中相关字段的自动填充策略 在阿里开发手册的建表规约中有说明,数据库表中应该都要有create_time、upd...
    99+
    2024-04-02
  • python通过SSH登陆linux并操作的实现
    用的昨天刚接触到的库,在windows下通过paramiko来登录linux系统并执行了几个命令,基本算是初试成功,后面会接着学习的。 代码: >>> import paramiko >&g...
    99+
    2022-06-04
    python SSH登陆linux python SSH linux
  • VB.NET LISTVIEW的相关操作方法和实现的功能有哪些
    VB.NET LISTVIEW的相关操作方法和实现的功能有哪些,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在VB.NET开发框架内,同样具有很多控件供开发人员使用,方便的实现...
    99+
    2023-06-17
  • JSch教程使用sftp协议实现服务器文件载操作
    目录Jsch是什么?怎么使用?添加jar依赖Jsch是什么? JSch 是SSH2的一个纯Java实现。它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等。你...
    99+
    2024-04-02
  • Pytorch实现List Tensor转Tensor,reshape拼接等操作
    目录一、List Tensor转Tensor (torch.cat)高维tensor二、List Tensor转Tensor (torch.stack)持续更新一些常用的Tensor...
    99+
    2024-04-02
  • 基于python win32setpixel api怎么实现计算机图形学相关操作
    本篇内容介绍了“基于python win32setpixel api怎么实现计算机图形学相关操作”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔...
    99+
    2023-06-21
  • 怎么解析正则表达式实现字符串的相关操作
    怎么解析正则表达式实现字符串的相关操作,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。正则表达式实现字符串的相关操作主要是实现对于字符串的开始和结束的锚定,那么具体的操作过程...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作