golang通过SSH实现远程执行和SCP文件下载的插件库easyssh-proxy的使用
Golang通过SSH实现远程执行和SCP文件下载的插件库easyssh-proxy的使用
easyssh-proxy提供了Go语言中SSH协议功能的简单实现。
功能特性
这个项目是从easyssh分叉而来,但添加了以下功能:
- 支持用户私钥的纯文本
- 支持用户私钥的路径
- 支持TCP连接建立的超时设置
- 支持SSH ProxyCommand
使用示例
MakeConfig
所有功能都通过MakeConfig结构体的方法访问:
ssh := &easyssh.MakeConfig{
User: "drone-scp",
Server: "localhost",
KeyPath: "./tests/.ssh/id_rsa",
Port: "22",
Timeout: 60 * time.Second,
}
stdout, stderr, done, err := ssh.Run("ls -al", 60*time.Second)
err = ssh.Scp("/root/source.csv", "/tmp/target.csv")
stdoutChan, stderrChan, doneChan, errChan, err = ssh.Stream("for i in {1..5}; do echo ${i}; sleep 1; done; exit 2;", 60*time.Second)
SSH远程执行命令
package main
import (
"fmt"
"time"
"github.com/appleboy/easyssh-proxy"
)
func main() {
// 创建MakeConfig实例,包含远程用户名、服务器地址和私钥路径
ssh := &easyssh.MakeConfig{
User: "appleboy",
Server: "example.com",
// 可选密钥或密码,如果两者都没有,我们会尝试联系您的代理SOCKET
// Password: "password",
// 粘贴您的私钥源内容
// Key: `-----BEGIN RSA PRIVATE KEY-----
// MIIEpAIBAAKCAQEA4e2D/qPN08pzTac+a8ZmlP1ziJOXk45CynMPtva0rtK/RB26
// 7XC9wlRna4b3Ln8ew3q1ZcBjXwD4ppbTlmwAfQIaZTGJUgQbdsO9YA==
// -----END RSA PRIVATE KEY-----
// `,
KeyPath: "/Users/username/.ssh/id_rsa",
Port: "22",
Timeout: 60 * time.Second,
// 使用密码短语解析私钥
Passphrase: "1234",
// 可选指纹SHA256验证
// 获取指纹: ssh.FingerprintSHA256(key)
// Fingerprint: "SHA256:mVPwvezndPv/ARoIadVY98vAC0g+P/5633yTC4d/wXE"
// 启用不安全密码和密钥交换方法的使用
// 这将启用以下不安全密码和密钥交换方法:
// - aes128-cbc
// - aes192-cbc
// - aes256-cbc
// - 3des-cbc
// - diffie-hellman-group-exchange-sha256
// - diffie-hellman-group-exchange-sha1
// 这些算法不安全,可能允许攻击者恢复明文数据
// UseInsecureCipher: true,
}
// 调用Run方法执行您想在远程服务器上运行的命令
stdout, stderr, done, err := ssh.Run("ls -al", 60*time.Second)
// 处理错误
if err != nil {
panic("Can't run remote command: " + err.Error())
} else {
fmt.Println("don is :", done, "stdout is :", stdout, "; stderr is :", stderr)
}
}
SCP文件传输
package main
import (
"fmt"
"github.com/appleboy/easyssh-proxy"
)
func main() {
// 创建MakeConfig实例,包含远程用户名、服务器地址和私钥路径
ssh := &easyssh.MakeConfig{
User: "appleboy",
Server: "example.com",
Password: "123qwe",
Port: "22",
}
// 调用Scp方法上传文件到远程服务器
// 请确保`tmp`文件夹存在
err := ssh.Scp("/root/source.csv", "/tmp/target.csv")
// 处理错误
if err != nil {
panic("Can't run remote command: " + err.Error())
} else {
fmt.Println("success")
}
}
SSH ProxyCommand
ssh := &easyssh.MakeConfig{
User: "drone-scp",
Server: "localhost",
Port: "22",
KeyPath: "./tests/.ssh/id_rsa",
Timeout: 60 * time.Second,
Proxy: easyssh.DefaultConfig{
User: "drone-scp",
Server: "localhost",
Port: "22",
KeyPath: "./tests/.ssh/id_rsa",
Timeout: 60 * time.Second,
},
}
注意:Proxy连接的属性不会从跳板机继承。您必须在DefaultConfig结构体中明确指定它们。
SSH Stream日志
func main() {
// 创建MakeConfig实例,包含远程用户名、服务器地址和私钥路径
ssh := &easyssh.MakeConfig{
Server: "localhost",
User: "drone-scp",
KeyPath: "./tests/.ssh/id_rsa",
Port: "22",
Timeout: 60 * time.Second,
}
// 调用Run方法执行您想在远程服务器上运行的命令
stdoutChan, stderrChan, doneChan, errChan, err := ssh.Stream("for i in {1..5}; do echo ${i}; sleep 1; done; exit 2;", 60*time.Second)
// 处理错误
if err != nil {
panic("Can't run remote command: " + err.Error())
} else {
// 从输出通道读取,直到收到完成信号
isTimeout := true
loop:
for {
select {
case isTimeout = <-doneChan:
break loop
case outline := <-stdoutChan:
fmt.Println("out:", outline)
case errline := <-stderrChan:
fmt.Println("err:", errline)
case err = <-errChan:
}
}
// 获取退出代码或命令错误
if err != nil {
fmt.Println("err: " + err.Error())
}
// 命令超时
if !isTimeout {
fmt.Println("Error: command timeout")
}
}
}
更多关于golang通过SSH实现远程执行和SCP文件下载的插件库easyssh-proxy的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang通过SSH实现远程执行和SCP文件下载的插件库easyssh-proxy的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用easyssh-proxy实现Golang远程SSH执行和SCP文件下载
easyssh-proxy是一个简单易用的Golang SSH库,它提供了远程命令执行和SCP文件传输功能。下面我将详细介绍如何使用这个库。
安装
首先安装easyssh-proxy库:
go get github.com/appleboy/easyssh-proxy
基本用法
1. 远程命令执行
package main
import (
"fmt"
"log"
"github.com/appleboy/easyssh-proxy"
)
func main() {
// 创建SSH配置
ssh := &easyssh.MakeConfig{
User: "username",
Server: "example.com",
Port: "22",
Password: "password",
// 或者使用私钥认证
// Key: "/.ssh/id_rsa",
// KeyPath: "/.ssh/id_rsa",
Timeout: 30, // 超时时间(秒)
}
// 执行远程命令
stdout, stderr, done, err := ssh.Run("ls -l /", 30)
if err != nil {
log.Fatalf("命令执行失败: %v", err)
}
fmt.Println("执行状态:", done)
fmt.Println("标准输出:", stdout)
fmt.Println("标准错误:", stderr)
}
2. SCP文件下载
package main
import (
"fmt"
"log"
"github.com/appleboy/easyssh-proxy"
)
func main() {
ssh := &easyssh.MakeConfig{
User: "username",
Server: "example.com",
Port: "22",
Password: "password",
Timeout: 30,
}
// 从远程服务器下载文件
err := ssh.Scp("/remote/path/file.txt", "/local/path/file.txt")
if err != nil {
log.Fatalf("文件下载失败: %v", err)
}
fmt.Println("文件下载成功")
}
3. SCP文件上传
package main
import (
"fmt"
"log"
"github.com/appleboy/easyssh-proxy"
)
func main() {
ssh := &easyssh.MakeConfig{
User: "username",
Server: "example.com",
Port: "22",
Password: "password",
Timeout: 30,
}
// 上传文件到远程服务器
err := ssh.Scp("/local/path/file.txt", "/remote/path/file.txt")
if err != nil {
log.Fatalf("文件上传失败: %v", err)
}
fmt.Println("文件上传成功")
}
高级功能
1. 使用代理
ssh := &easyssh.MakeConfig{
User: "username",
Server: "target.example.com",
Port: "22",
KeyPath: "/.ssh/id_rsa",
Proxy: easyssh.DefaultConfig{
User: "proxyuser",
Server: "proxy.example.com",
Port: "22",
KeyPath: "/.ssh/proxy_id_rsa",
},
}
2. 超时设置
ssh := &easyssh.MakeConfig{
User: "username",
Server: "example.com",
Password: "password",
Timeout: 60, // 60秒超时
}
3. 并行执行多个命令
package main
import (
"fmt"
"log"
"sync"
"github.com/appleboy/easyssh-proxy"
)
func main() {
ssh := &easyssh.MakeConfig{
User: "username",
Server: "example.com",
Password: "password",
}
var wg sync.WaitGroup
commands := []string{"uname -a", "df -h", "free -m"}
for _, cmd := range commands {
wg.Add(1)
go func(command string) {
defer wg.Done()
stdout, stderr, done, err := ssh.Run(command, 30)
if err != nil {
log.Printf("命令 %s 执行失败: %v", command, err)
return
}
fmt.Printf("命令: %s\n状态: %t\n输出: %s\n错误: %s\n\n",
command, done, stdout, stderr)
}(cmd)
}
wg.Wait()
}
错误处理
package main
import (
"fmt"
"log"
"github.com/appleboy/easyssh-proxy"
)
func main() {
ssh := &easyssh.MakeConfig{
User: "wronguser", // 错误的用户名
Server: "example.com",
Password: "wrongpass", // 错误的密码
Timeout: 10,
}
_, _, _, err := ssh.Run("ls", 10)
if err != nil {
switch e := err.(type) {
case *easyssh.SshError:
fmt.Printf("SSH错误: %s\n", e.Message)
fmt.Printf("退出状态: %d\n", e.ExitStatus)
default:
log.Fatalf("未知错误: %v", err)
}
return
}
}
总结
easyssh-proxy提供了简单易用的API来实现Golang中的SSH远程命令执行和SCP文件传输功能。它的主要特点包括:
- 支持密码和密钥认证
- 支持SSH代理
- 提供超时控制
- 简单的错误处理机制
- 支持并行执行
对于更复杂的SSH操作,可以考虑使用golang.org/x/crypto/ssh标准库,但对于大多数常见任务,easyssh-proxy提供了更简洁的接口。