Go小记:使用Go实现ssh客户端
一、前言
SSH(Secure Shell)是一种用于在不安全网络上安全访问远程计算机的网络协议。它通过加密的方式提供远程登录会话和其他网络服务,保证通信的安全性和数据的完整性。
本文使用golang.org/x/crypto/ssh
包来实现SSH客户端
可以通过go get -u golang.org/x/crypto/ssh
来引包。其中参数-u
指定从远程仓库下载最新版本
二、开发
(1) 创建ssh客户端配置
使用ssh.ClientConfig
来创建一个结构体. 指定用户名User
和认证方法 Auth
。忽略主机密钥验证,允许连接到任意服务器。
config := &ssh.ClientConfig{
User: "Yliken", //用户名
Auth: []ssh.AuthMethod{
ssh.Password("Yliken"), //密码、
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(), //忽略主机密钥验证
}
(2)发起ssh连接
使用ssh.Dial
来向服务器发送ssh连接请求。ssh.Dial
需要指定三个参数:网络类型(通常是tcp)、服务器地址(需要加上端口)、和一个指向ssh.ClientConfig
的指针
dial, err := ssh.Dial("tcp", "192.168.22.100:22", config)
if err != nil {
fmt.Println("连接服务器失败", err)
}
defer dial.Close()
(3)创建ssh会话
使用dial.NewSession
来与服务端建立一个会话。用于执行远程命令或交互操作。dial
是一个通过 ssh.Dial
方法获得的 *ssh.Client
对象。
session, err := dial.NewSession()
if err != nil {
fmt.Println("创建会话失败", err)
}
defer session.Close()
(4)创建伪终端
使用ssh.TerminalModes
创建伪终端模式
modes := ssh.TerminalModes{
ssh.ECHO: 0, // 禁用回显
ssh.TTY_OP_ISPEED: 14400, // 输入速度(比特/秒)
ssh.TTY_OP_OSPEED: 14400, // 输出速度(比特/秒)
}
然后再用session.RequestPty
再服务器上面请求一个伪终端。
session.RequestPty
包含4个参数:伪终端的类型、伪终端的高度和宽度、伪终端的模式配置(就是上面的modes)
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
fmt.Println(err)
}
(5)绑定标准输入、标准输出、标准错误
session.Stdout = os.Stdout //将远程会话的标准输出绑定到本地终端的标准输出。
session.Stderr = os.Stderr //将远程会话的标准错误输出绑定到本地终端的标准错误输出。
session.Stdin = os.Stdin //将本地终端的标准输入绑定到远程会话的标准输入。
(6)启动交互式shell
使用session.shell()
启动一个交互式shell。允许用户通过本地终端与远程服务器进行实时交互操作。
if err := session.Shell(); err != nil {
fmt.Println(err)
}
(7)等待会话结束
在交互式shell模式下session.Wait()
会阻塞程序。直到远程会话结束
三、完整程序源码
package main
import (
"fmt"
"golang.org/x/crypto/ssh"
"os"
)
func main() {
config := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
ssh.Password("312909"),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
dial, err := ssh.Dial("tcp", "192.168.22.100:22", config)
if err != nil {
fmt.Println("连接服务器失败", err)
}
defer dial.Close()
session, err := dial.NewSession()
if err != nil {
fmt.Println("创建会话失败", err)
}
defer session.Close()
modes := ssh.TerminalModes{
ssh.ECHO: 0,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
}
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
fmt.Println(err)
}
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin
if err := session.Shell(); err != nil {
fmt.Println(err)
}
session.Wait()
}