Golang SSH to Cisco Wireless Controller and Run Commands

橙三吉。 提交于 2019-12-06 13:14:07

Finally got it working. Here is my new code inspired by this post:

package main

import (
    "golang.org/x/crypto/ssh"
    "log"
    "io/ioutil"
    "os"
    "strings"
    "path/filepath"
    "bufio"
    "fmt"
    "errors"
    "time"
)

func main() {
    client, err := authenticate("10.4.112.11", "mwalto7", "lion$Tiger$Bear$")
    if err != nil {
        log.Fatalf("unable to connect: %v", err)
    }
    defer client.Close()

    // Create a session
    session, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer session.Close()

    stdin, err := session.StdinPipe()
    if err != nil {
        log.Fatal(err)
    }
    session.Stdout = os.Stdout
    session.Stderr = os.Stderr

    if err := session.Shell(); err != nil {
        log.Fatal(err)
    }

    for _, cmd := range os.Args[1:] {
        stdin.Write([]byte(cmd + "\n"))
    }

    stdin.Write([]byte("logout\n"))
    stdin.Write([]byte("N\n"))

    session.Wait()
}

func authenticate(host, username, password string) (ssh.Client, error) {
    hostKey, err := checkHostKey(host)
    if err != nil {
        log.Fatal(err)
    }

    key, err := ioutil.ReadFile(filepath.Join(os.Getenv("HOME"), ".ssh", "id_rsa"))
    if err != nil {
        log.Fatalf("unable to read private key: %v", err)
    }

    // Create the Signer for this private key.
    signer, err := ssh.ParsePrivateKey(key)
    if err != nil {
        log.Fatalf("unable to parse private key: %v", err)
    }

    // Create client config
    config := &ssh.ClientConfig{
        User: username,
        Auth: []ssh.AuthMethod{
            ssh.Password(password),
            // Use the PublicKeys method for remote authentication.
            ssh.PublicKeys(signer),
        },
        HostKeyCallback: ssh.FixedHostKey(hostKey),
        Timeout: time.Second * 5,
    }

    // Connect to the remote server and perform the SSH handshake.
    client, err := ssh.Dial("tcp", host+":22", config)

    return *client, err
}

func checkHostKey(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) {
            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
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!