如何在 Go 语言中通过 SSH 协议连接远程服务器,执行 Shell 命令,以及基于 SFTP 协议实现文件的上传和下载
这个在自动化运维、批量服务器管理、CI/CD自动化部署、配置分发、远程命令执行、容器操作中用途十分广泛
go ssh操作
依赖库
# SSH 核心库
go get golang.org/x/crypto/ssh
# SFTP 客户端库
go get github.com/pkg/sftp
package main
import (
"errors"
"fmt"
"golang.org/x/crypto/ssh"
"io"
"strings"
)
func main() {
user := "root"
password := ""
host := "192.168.80.166"
port := 22
cmder := "ls"
sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, port), &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
})
if err != nil {
if strings.Contains(err.Error(), "none password") {
err = errors.New("密码错误")
return
}
if strings.Contains(err.Error(), "No connection") {
err = errors.New("服务器地址访问超时")
return
}
err = errors.New("ssh连接失败 " + err.Error())
return
}
defer sshClient.Close()
session, err := sshClient.NewSession()
if err != nil {
err = errors.New("创建会话失败 " + err.Error())
return
}
stdout, _ := session.StdoutPipe()
fmt.Printf("ssh命令执行 %s\n", cmder)
err = session.Run(cmder)
if err != nil {
fmt.Printf("ssh命令执行失败 %s\n", err)
return
}
byteData, _ := io.ReadAll(stdout)
fmt.Printf("ssh命令执行成功 %s\n", byteData)
return
}
go sftp操作
sftp是基于ssh的ftp文件操作
package main
import (
"errors"
"fmt"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
"io"
"os"
"strings"
)
func main() {
user := "root"
password := ""
host := "192.168.80.166"
port := 22
sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, port), &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
})
if err != nil {
if strings.Contains(err.Error(), "none password") {
err = errors.New("密码错误")
return
}
if strings.Contains(err.Error(), "No connection") {
err = errors.New("服务器地址访问超时")
return
}
err = errors.New("ssh连接失败 " + err.Error())
return
}
defer sshClient.Close()
client, err := sftp.NewClient(sshClient)
if err != nil {
fmt.Println("sftp客户端初始化失败", err)
return
}
// 上传文件
file, err := os.Open("sftp.go")
if err != nil {
fmt.Println("读取文件失败", err)
return
}
remoteFile, _ := client.Create("sftp1.go")
io.Copy(remoteFile, file)
// 下载文件
rFile, err := client.Open("/root/initial-setup-ks.cfg")
if err != nil {
fmt.Println("远程文件打开失败", err)
return
}
localFile, _ := os.Create("initial-setup-ks.cfg")
io.Copy(localFile, rFile)
}