Go連接到Linux服務器進行操作-執行shell命令&&上傳文件


Go連接到Linux服務器進行操作

使用密碼連接Linux服務器

package main

import (
	"fmt"
	"golang.org/x/crypto/ssh"
	"log"
	"time"
)

func pwdConnect(sshHost, sshUser, sshPassword string, sshPort int) (*ssh.Client, error) {
	// 創建ssh登錄配置
	config := &ssh.ClientConfig{
		Timeout:         5 * time.Second,                             // 超時時間
		User:            sshUser,                                     // 登錄賬號
		Auth:            []ssh.AuthMethod{ssh.Password(sshPassword)}, // 密碼
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),                 // 這個不夠安全,生產環境不建議使用
		//HostKeyCallback: ssh.FixedHostKey(), // 建議使用這種,目前還沒研究出怎么使用[todo]
	}

	// dial連接服務器
	addr := fmt.Sprintf("%s:%d", sshHost, sshPort)
	Client, err := ssh.Dial("tcp", addr, config)
	if err != nil {
		log.Fatal("連接到服務器失敗", err)
		return nil, err
	}

	//defer sshClient.Close()
	return Client, nil
}

func main() {
  // 連接到服務器
	conn, err := pwdConnect("192.168.3.121", "root", "123456", 22)
	if err != nil {
		return
	}
	defer conn.Close()

	// 創建 ssh session 會話
	session, err := conn.NewSession()
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// 執行遠程命令
	cmd := "cd /tmp/;ls -l; tar -czf test.tar.gz hello.txt test.txt;ls -l"
	cmdInfo, err := session.CombinedOutput(cmd)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(cmdInfo))
}

使用秘鑰連接到Linux服務器

package main

import (
	"fmt"
	"golang.org/x/crypto/ssh"
	"io/ioutil"
	"time"
)

// 使用秘鑰連接Linux服務器

// 連接到linux服務器
func keyConnect(sshUser, sshHost, sshKey string, sshPort int) (*ssh.Client, error) {
	// 讀取秘鑰
	key, err := ioutil.ReadFile(sshKey)
	if err != nil {
		panic("秘鑰讀取失敗")
	}

	// 創建秘鑰簽名
	// 會拿着秘鑰去登錄服務器
	signer, err := ssh.ParsePrivateKey(key)
	if err != nil {
		panic("秘鑰簽名失敗")
	}

	// ssh配置
	config := &ssh.ClientConfig{
		Timeout: 5 * time.Second, // 超時時間
		User:    sshUser,
		Auth: []ssh.AuthMethod{
			// 使用秘鑰登錄遠程服務器
			ssh.PublicKeys(signer),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(), //這個不夠安全,生產環境不建議使用
		//var hostKey ssh.PublicKey
		//HostKeyCallback: ssh.FixedHostKey(hostKey),
	}

	// 連接遠程服務器
	addr := fmt.Sprintf("%s:%d", sshHost, sshPort)
	client, err := ssh.Dial("tcp", addr, config)
	if err != nil {
		fmt.Println("連接遠程服務器失敗", err)
		return nil, err
	}

	//defer client.Close()
	return client, nil
}

func main() {
	// 連接服務器
	conn, err := keyConnect("root", "192.168.3.121", "id_rsa", 22)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	// 創建 ssh session 會話
	session, err := conn.NewSession()
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// 執行遠程命令
	cmd := "cd /tmp/; ls -l"
	cmdInfo, err := session.CombinedOutput(cmd)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(cmdInfo))
}

使用秘鑰或者密碼連接到服務器

package main

import (
	"errors"
	"fmt"
	"golang.org/x/crypto/ssh"
	"io/ioutil"
	"log"
	"time"
)

func keyOrPwdConnect(sshHost, sshUser, sshPassword, sshKey string, sshPort int) (*ssh.Client, error) {
	// 創建ssh登錄配置
	config := &ssh.ClientConfig{
		Timeout:         5 * time.Second,             // 超時時間
		User:            sshUser,                     // 登錄賬號
		HostKeyCallback: ssh.InsecureIgnoreHostKey(), //這個不夠安全,生產環境不建議使用
		//HostKeyCallback: ssh.FixedHostKey(), //建議使用這種
	}

	if sshKey != "" {
    // 秘鑰登錄
		key, err := ioutil.ReadFile(sshKey) // 讀取秘鑰
		if err != nil {
			panic("秘鑰讀取失敗")
		}
		// 創建秘鑰簽名
		signer, err := ssh.ParsePrivateKey(key)
		if err != nil {
			panic("秘鑰簽名失敗")
		}
		// 配置秘鑰登錄
		config.Auth = []ssh.AuthMethod{
			ssh.PublicKeys(signer),
		}
	} else if sshPassword != "" {
		// 密碼登錄
		config.Auth = []ssh.AuthMethod{ssh.Password(sshPassword)}
	} else {
		err := errors.New("秘鑰或者密碼登錄")
		return nil, err
	}

	// dial連接服務器
	addr := fmt.Sprintf("%s:%d", sshHost, sshPort)
	Client, err := ssh.Dial("tcp", addr, config)
	if err != nil {
		log.Fatal("連接到服務器失敗", err)
		return nil, err
	}

	return Client, nil
}

func main() {
	// 連接服務器
	//conn, err := keyOrPwdConnect("192.168.3.121", "root", "", "id_rsa", 22) // 秘鑰登錄
	conn, err := keyOrPwdConnect("192.168.3.121", "root", "123456", "", 22) // 密碼登錄
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	// 創建 ssh session 會話
	session, err := conn.NewSession()
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// 執行遠程命令
	cmd := "echo 'hello world!'"
	cmdInfo, err := session.CombinedOutput(cmd)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(cmdInfo))
}

上傳文件到Linux服務器

package main

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

// 通過SSH連接Linux服務器
func keyOrPwdConnectLinuxServer(sshHost, sshUser, sshPassword, sshKey string, sshPort int) (*ssh.Client, error) {
	// 創建ssh登錄配置
	config := &ssh.ClientConfig{
		Timeout:         5 * time.Second,             // 超時時間
		User:            sshUser,                     // 登錄賬號
		HostKeyCallback: ssh.InsecureIgnoreHostKey(), //這個不夠安全,生產環境不建議使用
		//HostKeyCallback: ssh.FixedHostKey(), //建議使用這種
	}

	
	if sshKey != "" {
		// 秘鑰登錄
		key, err := ioutil.ReadFile(sshKey) 
		if err != nil {
			panic("秘鑰讀取失敗")
		}
		// 創建秘鑰簽名
		// 會拿着秘鑰去登錄服務器
		signer, err := ssh.ParsePrivateKey(key)
		if err != nil {
			panic("秘鑰簽名失敗")
		}
		// 配置秘鑰登錄
		config.Auth = []ssh.AuthMethod{
			ssh.PublicKeys(signer),
		}
	} else if sshPassword != "" {
		// 密碼登錄
		config.Auth = []ssh.AuthMethod{ssh.Password(sshPassword)}
	} else {
		err := errors.New("秘鑰或者密碼登錄")
		return nil, err
	}

	// dial連接服務器
	addr := fmt.Sprintf("%s:%d", sshHost, sshPort)
	Client, err := ssh.Dial("tcp", addr, config)
	if err != nil {
		log.Fatal("連接到服務器失敗", err)
		return nil, err
	}

	return Client, nil
}

// 創建sftp會話
func CreateSftp(sshHost, sshUser, sshPassword, sshKey string, sshPort int) (*sftp.Client, error) {
	// 連接Linux服務器
	conn, err := keyOrPwdConnectLinuxServer(sshHost, sshUser, sshPassword, sshKey, sshPort)
	if err != nil {
		fmt.Println("連接Linux服務器失敗")
		panic(err)
	}
	//defer conn.Close()

	// 創建sftp會話
	client, err := sftp.NewClient(conn)
	if err != nil {
		return nil, err
	}
	//defer client.Close()
	return client, nil
}

func main() {
	// 連接sftp
	client, err := CreateSftp("192.168.3.121", "root", "123456", "", 22)
	if err != nil {
		return
	}
	defer client.Close()

	// 瀏覽服務器/home/devel目錄
	//w := client.Walk("/home/devel")
	//for w.Step() {
	//	if w.Err() != nil {
	//		continue
	//	}
	//	fmt.Println(w.Path())
	//}

	// 在服務器創建文件
	//f, err := client.Create("/tmp/hello.txt")
	//if err != nil {
	//	panic(err)
	//}
	//_, err = f.Write([]byte("hello world!\n")) // 寫入內容
	//if err != nil {
	//	panic(err)
	//}
	//f.Close()

	// 查看服務器的文件
	//fi, err := client.Lstat("/tmp/hello.txt")
	//if err != nil {
	//	panic(err)
	//}
	//fmt.Printf("%#v\n", fi)

	// 上傳文件
	var localFilePath = "./test.txt" // 本地文件全路徑
	var remoteDir = "/tmp"           // 服務器目錄
	// 打開需要上傳的本地文件
	srcFile, err := os.Open(localFilePath)
	if err != nil {
		panic(err)
	}
	defer srcFile.Close()
	// 獲取需要上傳的文件的名稱
	var remoteFileName = path.Base(localFilePath)
	// 在服務器創建文件並打開文件獲得句柄
	dstFile, err := client.Create(path.Join(remoteDir, remoteFileName))
	if err != nil {
		panic(err)
	}
	defer dstFile.Close()
	// 寫入內容
	buf := make([]byte, 1024)
	for {
		n, _ := srcFile.Read(buf) // 把文件中的內容讀取到buf中,每次讀取本地需要上傳的文件1024字節內容
		// 當n=0時,證明本地需要上傳的文件已經讀取完畢了
		if n == 0 {
			break
		}
		dstFile.Write(buf) // 寫入到句柄
	}
	fmt.Println("文件上傳完畢")
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM