Go SSH Client
Go proof of concept
ssh client, using ssh keys, ignoring host key verification.
Note, code is here for host key verification, if you want it.
package main
// Ref: https://github.com/golang/crypto/blob/master/ssh/example_test.go
// go get -u golang.org/x/crypto/ssh
import (
"bufio"
"bytes"
"errors"
"fmt"
"golang.org/x/crypto/ssh"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
func getHostKey(host string) (ssh.PublicKey, error) {
file, err := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts"))
if err != nil {
return nil, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
var hostKey ssh.PublicKey
for scanner.Scan() {
fields := strings.Split(scanner.Text(), " ")
if len(fields) != 3 {
continue
}
if strings.Contains(fields[0], host) {
var err error
hostKey, _, _, _, err = ssh.ParseAuthorizedKey(scanner.Bytes())
if err != nil {
return nil, errors.New(fmt.Sprintf("error parsing %q: %v", fields[2], err))
}
break
}
}
if hostKey == nil {
return nil, errors.New(fmt.Sprintf("no hostkey for %s", host))
}
return hostKey, nil
}
func main() {
user := "sparky"
server := "45.25.125.83:22"
command := "uptime"
// If you want to valid keys ...
// hostKey, err := getHostKey("smtp.aipiggybot.io")
//if err != nil {
// log.Fatal(err)
//}
var hostKey ssh.PublicKey
key, err := ioutil.ReadFile(filepath.Join(os.Getenv("HOME"), ".ssh", "id_rsa"))
if err != nil {
log.Fatalf("Unable to read private key: %v", err)
}
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
log.Fatalf("Unable to parse private key: %v", err)
}
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
// ssh.Password("yourpassword"),
},
HostKeyCallback: ssh.FixedHostKey(hostKey),
}
// Ignore key validation
config.HostKeyCallback = ssh.InsecureIgnoreHostKey()
client, err := ssh.Dial("tcp", server, config)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
// Each ClientConn can support multiple interactive sessions,
// represented by a Session.
session, err := client.NewSession()
if err != nil {
log.Fatal("Failed to create session: ", err)
}
defer session.Close()
// Once a Session is created, you can execute a single command on
// the remote side using the Run method.
var b bytes.Buffer
session.Stdout = &b
if err := session.Run(command); err != nil {
log.Fatal("Failed to run: " + err.Error())
}
fmt.Println(b.String())
}