Skip to content

Instantly share code, notes, and snippets.

@makkes
Created May 15, 2019 09:20
Show Gist options
  • Save makkes/2d7df19f2179673afd88fdec361b9c77 to your computer and use it in GitHub Desktop.
Save makkes/2d7df19f2179673afd88fdec361b9c77 to your computer and use it in GitHub Desktop.
SSH remote execution and SCP
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"path"
"sync"
"golang.org/x/crypto/ssh"
)
type Client struct {
sshClient *ssh.Client
}
func NewClient(privKey, privKeyPassphrase, user, host string) *Client {
key, err := ioutil.ReadFile(privKey)
if err != nil {
log.Fatalf("Could not get private key: %s", err)
}
signer, err := ssh.ParsePrivateKeyWithPassphrase(key, []byte(privKeyPassphrase))
if err != nil {
log.Fatalf("Could not parse private key: %s", err)
}
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
client, err := ssh.Dial("tcp", host, config)
if err != nil {
log.Fatalf("Unable to connect: %s", err)
}
return &Client{
sshClient: client,
}
}
func (c *Client) Close() error {
return c.sshClient.Close()
}
func (c *Client) TransferFile(name string) {
data, err := ioutil.ReadFile(name)
if err != nil {
log.Fatalf("Error reading file %s: %s", name, err)
}
sess, err := c.sshClient.NewSession()
if err != nil {
log.Fatalf("Could not create session: %s", err)
}
defer sess.Close()
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
w, err := sess.StdinPipe()
if err != nil {
log.Fatalf("Error getting stdin pipe: %s", err)
}
defer w.Close()
if n, err := fmt.Fprintln(w, "C0700", len(data), path.Base(name)); err != nil {
log.Fatalf("Error writing: %s. Wrote %d bytes", err, n)
}
if n, err := w.Write(data); err != nil {
log.Fatalf("Error writing: %s. Wrote %d bytes", err, n)
}
if _, err := fmt.Fprintf(w, "\x00"); err != nil {
log.Fatalf("Error sending termination: %s", err)
}
}()
go func() {
defer wg.Done()
err := sess.Run("/usr/bin/scp -qt .")
if err != nil {
log.Fatalf("Error running scp: %s", err)
}
}()
wg.Wait()
}
func main() {
privateKeyLocation := path.Join(os.Getenv("HOME"), "dcos-aws-demo", "dcos-ssh-shared-key")
privateKeyPassphrase := "CHANGEME"
sshUsername := "CHANGEME"
sshHost := "CHANGEME:22"
client := NewClient(privateKeyLocation, privateKeyPassphrase, sshUsername, sshHost)
defer client.Close()
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
client.TransferFile(os.Args[0])
}()
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment