使用golang crypto / ssh在Cisco上运行多个命令

时间:2016-02-19 19:11:33

标签: go ssh

我将以下代码拼凑在一起,这将让我发送读取和写入思科盒子的ssh控制台,但我目前不知道如何在同一会话中发送多个命令。

我将整个程序包括在内,以便将服务器作为未来尝试同样事情的其他人的起点,我找不到专门针对Golang< - > Cisco的工作示例。

String query = "select * from Peter1Score where DateSort=?";
PreparedStatement pst = connection.prepareStatement(query);
pst.setDate(1, convertSQLDate("09/20/15"));

正如你所看到的,我已经硬编码了" en" session.Run()中的命令。 如果我之后添加一个命令,只需执行以下操作:

package main

import (
    "fmt"
    "io"
    "io/ioutil"
    "net"
    "os"
    //"strings"

    "golang.org/x/crypto/ssh"
    "golang.org/x/crypto/ssh/agent"
)

type SSHCommand struct {
    Stdin  io.Reader
    Stdout io.Writer
    Stderr io.Writer
}

type SSHClient struct {
    Config *ssh.ClientConfig
    Host   string
    Port   int
}

func (client *SSHClient) RunCommand(cmd *SSHCommand) error {
    var (
        session *ssh.Session
        err     error
    )

    if session, err = client.newSession(); err != nil {
        return err
    }
    defer session.Close()

    if err = client.prepareCommand(session, cmd); err != nil {
        return err
    }

    err = session.Run("en\r")


    return err
}

func (client *SSHClient) prepareCommand(session *ssh.Session, cmd *SSHCommand) error {

    if cmd.Stdin != nil {
        stdin, err := session.StdinPipe()
        if err != nil {
            return fmt.Errorf("Unable to setup stdin for session: %v", err)
        }
        go io.Copy(stdin, cmd.Stdin)
    }

    if cmd.Stdout != nil {
        stdout, err := session.StdoutPipe()
        if err != nil {
            return fmt.Errorf("Unable to setup stdout for session: %v", err)
        }
        go io.Copy(cmd.Stdout, stdout)
    }

    if cmd.Stderr != nil {
        stderr, err := session.StderrPipe()
        if err != nil {
            return fmt.Errorf("Unable to setup stderr for session: %v", err)
        }
        go io.Copy(cmd.Stderr, stderr)
    }

    return nil
}

func (client *SSHClient) newSession() (*ssh.Session, error) {
    connection, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", client.Host, client.Port), client.Config)
    if err != nil {
        return nil, fmt.Errorf("Failed to dial: %s", err)
    }

    session, err := connection.NewSession()
    if err != nil {
        return nil, fmt.Errorf("Failed to create session: %s", err)
    }

    modes := ssh.TerminalModes{
        // ssh.ECHO:          0,     // disable echoing
        ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }

    if err := session.RequestPty("xterm", 0, 200, modes); err != nil {
        session.Close()
        return nil, fmt.Errorf("request for pseudo terminal failed: %s", err)
    }

    return session, nil
}

func SSHAgent() ssh.AuthMethod {
    if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
        return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)
    }
    return nil
}

func main() {

    sshConfig := &ssh.ClientConfig{
        User: "admin",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
    }
    sshConfig.Ciphers = []string{"aes128-cbc"}

    client := &SSHClient{
        Config: sshConfig,
        Host:   "10.10.10.10",
        Port:   22,
    }

    cmd := &SSHCommand{
        Stdin:  os.Stdin,
        Stdout: os.Stdout,
        Stderr: os.Stderr,
    }

    fmt.Printf("Running commands\n")
    if err := client.RunCommand(cmd); err != nil {
        fmt.Fprintf(os.Stderr, "command run error: %s\n", err)
        os.Exit(1)
    }

}

它被忽略了。阅读https://godoc.org/golang.org/x/crypto/ssh#Session.Shell告诉我这是设计的。所以我的问题是:如何设置一些东西让我输入命令,读取输出,解析它,并根据输出输入更多命令?

一旦我绕过这个,我计划解析路由表并发出响应命令。 IE,如果缺少路径X,请添加它。

1 个答案:

答案 0 :(得分:1)

这可能不是惯用的,我还在学习。我刚才写了这篇文章来从交换机上获取备份,但我认为它可以解决你的问题:

https://github.com/plod/goSwitchBackup/blob/master/main.go

func writeBuff(command string, sshIn io.WriteCloser) (int, error) {
    returnCode, err := sshIn.Write([]byte(command + "\r"))
    return returnCode, err
}