go: ssh connect and scp copy

package main

import (
	"bytes"
	"context"
	"fmt"
	"os"
	"strings"

	scp "github.com/bramvdbogaerde/go-scp"
	"github.com/rs/zerolog/log"
	"golang.org/x/crypto/ssh"
)

const (
	pemFile = "/Users/pepa/pepa.pem"
	user    = "root"
	host    = "server.example.com:22"
)

func main() {
	pemBytes, err := os.ReadFile(pemFile)
	if err != nil {
		log.Fatal().Err(err).Caller().Send()
	}

	singer, err := ssh.ParsePrivateKey(pemBytes)
	if err != nil {
		log.Fatal().Err(err).Caller().Send()
	}

	cfg := &ssh.ClientConfig{
		User:            user,
		Auth:            []ssh.AuthMethod{ssh.PublicKeys(singer)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	conn, err := ssh.Dial("tcp", host, cfg)
	if err != nil {
		log.Fatal().Err(err).Caller().Send()
	}
	defer conn.Close()

	scpClient, err := scp.NewClientBySSH(conn)
	if err != nil {
		log.Fatal().Err(err).Caller().Msg("scpClient")
	}
	defer scpClient.Close()

	text := "Hello, World!"

	r := strings.NewReader(text)
	if err := scpClient.Copy(
		context.Background(),
		r,
		"/home/admin/main.go",
		"0644",
		int64(len(text)),
	); err != nil {
		log.Fatal().Err(err).Caller().Msg("CopyFromFile")
	}

	var stdoutBuf bytes.Buffer
	var stderrBuf bytes.Buffer

	cmd := []string{
		"who",
		"date",
		"ls -al ./",
		"cat ~/main.go",
	}

	for _, command := range cmd {
		session, err := conn.NewSession()
		if err != nil {
			log.Fatal().Err(err).Caller().Send()
		}
		defer session.Close()
		session.Stdout = &stdoutBuf
		session.Stderr = &stderrBuf
		session.Run(command)
	}

	fmt.Println(stdoutBuf.String())

	if stderrBuf.Len() > 0 {
		fmt.Println("err:", stderrBuf.String())
	}
}
Publikováno v GoTagged