go实现ssh远程机器并传输文件

22 篇文章 0 订阅

 项目目录结构:

 sshtool.go:

package ssh_tool

import (
	"flag"
	"fmt"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
	"io"
	"log"
	"net"
	"os"
	"path"
	"time"
)

// SshClient ssh客户端对象 /*
type SshClient struct {
	username string
	password string
	host string
	Client * ssh.Client
}

func (sshClient * SshClient) NewSshClient() *ssh.Client{
	flag.StringVar(&sshClient.username,"username","root","通过ssh2登录linux的用户名")
	flag.StringVar(&sshClient.password,"password","root","通过ssh2登录linux的密码")
	flag.StringVar(&sshClient.host,"host","192.168.56.25","通过ssh2登录linux的ip地址")
	flag.Parse()

	log.Println(sshClient.password)

	auth := make([]ssh.AuthMethod, 0)
	auth = append(auth, ssh.Password(sshClient.password))

	clientConfig := &ssh.ClientConfig{
		User:    sshClient.username,
		Auth:    auth,
		Timeout: 30 * time.Second,
		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
			return nil
		},
	}

	addr := sshClient.host + ":22"
	client, err := ssh.Dial("tcp", addr, clientConfig) //连接ssh
	if err != nil {
		log.Fatal("连接ssh失败", err)
	}

	sshClient.Client = client
	return client
}

func (sshClient * SshClient) RunCmd(cmd string) string {
	session, err := sshClient.Client.NewSession()
	if err != nil{
		panic(err)
	}
	defer session.Close()

	runResult,err := session.CombinedOutput(cmd)
	if err != nil{
		panic(err)
	}
	return string(runResult)
}


func (sshClient * SshClient) UploadFile(localPath string, remoteDir string, remoteFileName string){
	ftpClient, err := sftp.NewClient(sshClient.Client)
	if err != nil {
		fmt.Println("创建ftp客户端失败", err)
		panic(err)
	}

	defer ftpClient.Close()

	fmt.Println(localPath, remoteFileName)
	srcFile, err := os.Open(localPath)
	if err != nil {
		fmt.Println("打开文件失败", err)
		panic(err)
	}
	defer srcFile.Close()

	dstFile, e := ftpClient.Create(path.Join(remoteDir, remoteFileName))
	if e != nil {
		fmt.Println("创建文件失败", e)
		panic(e)
	}
	defer dstFile.Close()

	buffer := make([]byte, 1024000)
	for {
		n, err := srcFile.Read(buffer)
		dstFile.Write(buffer[:n])
		//注意,由于文件大小不定,不可直接使用buffer,否则会在文件末尾重复写入,以填充1024的整数倍
		if err != nil {
			if err == io.EOF {
				fmt.Println("已读取到文件末尾")
				break
			} else {
				fmt.Println("读取文件出错", err)
				panic(err)
			}
		}
	}
}

func (sshClient * SshClient) DownloadFile(remotePath string, localDir string , localFilename string)  {
	ftpClient, err := sftp.NewClient(sshClient.Client)
	if err != nil {
		fmt.Println("创建ftp客户端失败", err)
		panic(err)
	}

	defer ftpClient.Close()

	srcFile, err := ftpClient.Open(remotePath)
	if err != nil {
		fmt.Println("文件读取失败", err)
		panic(err)
	}
	defer srcFile.Close()

	dstFile, e := os.Create(path.Join(localDir, localFilename))
	if e != nil {
		fmt.Println("文件创建失败", e)
		panic(e)
	}
	defer dstFile.Close()
	if _, err1 := srcFile.WriteTo(dstFile); err1 != nil {
		fmt.Println("文件写入失败", err1)
		panic(err1)
	}
	fmt.Println("文件下载成功")
}

const_values.go: 

package constkv

const (
	MSG_CODE_KEY = "code"
	MSG_CONTENT_KEY = "msg"
)

SSHRemote.go: 

package main

import (
	"SSH/constkv"
	"SSH/ssh_tool"
	"bufio"
	"encoding/json"
	"io"
	"log"
	"net/http"
)

var (
	sshClient = new(ssh_tool.SshClient)
	buffer = make([]byte,10240)
)

func handlerCmd(writer http.ResponseWriter, request *http.Request) {
	var resultMap = make(map[string]interface{})
	//处理错误的panic
	defer func() {
		err := recover()
		if err != nil{
			resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
			resultMap[constkv.MSG_CONTENT_KEY] = err.(error).Error()
			bytes, _ := json.Marshal(&resultMap)
			writer.Write(bytes)
		}
	}()

	var bufferSlice = make([]byte,0)

	reader := request.Body
	bufferReader := bufio.NewReader(reader)

	for {
		length, err := bufferReader.Read(buffer)
		bufferSlice = append(bufferSlice,buffer[:length]...)
		if err == io.EOF{
			break
		}
	}

	log.Println(string(bufferSlice))
	var paramMap = make(map[string]interface{})
	_ = json.Unmarshal(bufferSlice, &paramMap)

	log.Println(paramMap["cmd"])
	cmd := paramMap["cmd"]
	log.Println(cmd.(string) + "--------------------")

	if sshClient.Client != nil{
		runCmd := sshClient.RunCmd(cmd.(string))
		resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
		resultMap[constkv.MSG_CONTENT_KEY] = runCmd
	}

	bytes, _ := json.Marshal(&resultMap)
	_ , _ = writer.Write(bytes)
}

func handleUploadFile(writer http.ResponseWriter, request *http.Request)  {
	var resultMap = make(map[string]interface{})
	//处理错误的panic
	defer func() {
		err := recover()
		if err != nil{
			resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
			resultMap[constkv.MSG_CONTENT_KEY] = err.(error).Error()
			bytes, _ := json.Marshal(&resultMap)
			writer.Write(bytes)
		}

	}()
	var bufferSlice = make([]byte,0)
	reader := request.Body
	bufferReader := bufio.NewReader(reader)

	for {
		length, err := bufferReader.Read(buffer)
		bufferSlice = append(bufferSlice,buffer[:length]...)
		if err == io.EOF{
			break
		}
	}

	log.Println(string(bufferSlice))
	var paramMap = make(map[string]interface{})
	_ = json.Unmarshal(bufferSlice, &paramMap)

	localPath := paramMap["localPath"]
	remoteDir := paramMap["remoteDir"]
	remoteFileName := paramMap["remoteFileName"]

	log.Println(localPath)
	log.Println(remoteDir)

	sshClient.UploadFile(localPath.(string),remoteDir.(string),remoteFileName.(string))
}

func handleDownloadFile(writer http.ResponseWriter, request *http.Request)  {
	var resultMap = make(map[string]interface{})
	//处理错误的panic
	defer func() {
		err := recover()
		if err != nil{
			resultMap[constkv.MSG_CODE_KEY] = http.StatusOK
			resultMap[constkv.MSG_CONTENT_KEY] = err.(error).Error()
			bytes, _ := json.Marshal(&resultMap)
			writer.Write(bytes)
		}

	}()
	var bufferSlice = make([]byte,0)
	reader := request.Body
	bufferReader := bufio.NewReader(reader)

	for {
		length, err := bufferReader.Read(buffer)
		bufferSlice = append(bufferSlice,buffer[:length]...)
		if err == io.EOF{
			break
		}
	}

	log.Println(string(bufferSlice))
	var paramMap = make(map[string]interface{})
	_ = json.Unmarshal(bufferSlice, &paramMap)

	remotePath := paramMap["remotePath"]
	localDir := paramMap["localDir"]
	localFileName := paramMap["localFileName"]

	log.Println(remotePath)
	log.Println(localDir)
	log.Println(localFileName)

	sshClient.DownloadFile(remotePath.(string),localDir.(string),localFileName.(string))
}

func main(){
	//初始化ssh客户端
	sshClient.NewSshClient()
	//1.注册一个给定模式的处理器函数到DefaultServeMux
	http.HandleFunc("/", handlerCmd)
	http.HandleFunc("/uploadFile", handleUploadFile)
	http.HandleFunc("/downloadFile", handleDownloadFile)

	//2.设置监听的TCP地址并启动服务
	//参数1:TCP地址(IP+Port)
	//参数2:当设置为nil时表示使用DefaultServeMux
	err := http.ListenAndServe(":8080", nil)
	log.Fatal(err)
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用Python实现SSH远程登录,首先需要安装paramiko库。然后可以使用paramiko模块的SSHClient类来创建一个SSH客户端对象。接下来,可以使用SSH客户端对象的connect()方法来连接到目标主机。在connect()方法中,需要提供目标主机的IP地址、端口号、用户名和密码作为参数。一旦连接成功,就可以使用SSH客户端对象的exec_command()方法执行远程命令。 下面是一个示例代码,展示了如何使用Python实现SSH远程登录: ``` import paramiko def ssh_login(ip, port, username, password): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip, port, username, password) return ssh def ssh_execute_command(ssh, command): stdin, stdout, stderr = ssh.exec_command(command) output = stdout.read().decode('utf-8') return output def main(): ip = '192.168.xx.xx' port = 22 username = 'root' password = 'pwd' ssh = ssh_login(ip, port, username, password) output = ssh_execute_command(ssh, 'pwd') print(output) output = ssh_execute_command(ssh, 'ifconfig') print(output) ssh.close() if __name__ == '__main__': main() ``` 在这个示例代码中,首先定义了一个ssh_login()函数,它接受目标主机的IP地址、端口号、用户名和密码作为参数,并使用paramiko库创建一个SSH客户端对象,并通过connect()方法连接到目标主机。然后定义了一个ssh_execute_command()函数,它接受一个SSH客户端对象和要执行的命令作为参数,并使用exec_command()方法执行远程命令,并返回命令的输出。最后,在main()函数中,调用了ssh_login()函数来建立SSH连接,然后使用ssh_execute_command()函数执行了两个远程命令,并打印输出结果。最后,调用ssh.close()关闭SSH连接。 这样,就实现了使用Python进行SSH远程登录。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [python实现远程ssh登录](https://blog.csdn.net/u010835747/article/details/126562612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双天至尊20176

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值