如何在 golang CLI 中在远程机器上执行命令?

如何在 golang CLI 中在远程机器上执行命令?我需要编写一个 golang CLI,它可以通过密钥 SSH 到远程机器并执行 shell 命令。此外,我需要能够做到这一点。例如,通过 SSH 连接到一台机器(如云堡垒),然后通过 SSH 连接到另一台内部机器并执行 shell 命令。

我(还)没有找到任何例子。


梦里花落0921
浏览 164回答 3
3回答

开满天机

"golang.org/x/crypto/ssh"您可以使用该软件包通过 SSH 在远程计算机上运行命令。这是一个示例函数,演示了在远程机器上运行单个命令并返回输出的简单用法://e.g. output, err := remoteRun("root", "MY_IP", "PRIVATE_KEY", "ls")func remoteRun(user string, addr string, privateKey string, cmd string) (string, error) {    // privateKey could be read from a file, or retrieved from another storage    // source, such as the Secret Service / GNOME Keyring    key, err := ssh.ParsePrivateKey([]byte(privateKey))    if err != nil {        return "", err    }    // Authentication    config := &ssh.ClientConfig{        User: user,        // https://github.com/golang/go/issues/19767         // as clientConfig is non-permissive by default         // you can set ssh.InsercureIgnoreHostKey to allow any host         HostKeyCallback: ssh.InsecureIgnoreHostKey(),        Auth: []ssh.AuthMethod{            ssh.PublicKeys(key),        },        //alternatively, you could use a password        /*            Auth: []ssh.AuthMethod{                ssh.Password("PASSWORD"),            },        */    }    // Connect    client, err := ssh.Dial("tcp", net.JoinHostPort(addr, "22"), config)    if err != nil {        return "", err    }    // Create a session. It is one session per command.    session, err := client.NewSession()    if err != nil {        return "", err    }    defer session.Close()    var b bytes.Buffer  // import "bytes"    session.Stdout = &b // get output    // you can also pass what gets input to the stdin, allowing you to pipe    // content from client to server    //      session.Stdin = bytes.NewBufferString("My input")    // Finally, run the command    err = session.Run(cmd)    return b.String(), err}

青春有我

尝试使用 os/exec https://golang.org/pkg/os/exec/来执行 sshpackage mainimport (    "bytes"    "log"    "os/exec")func main() {    cmd := exec.Command("ssh", "remote-machine", "bash-command")    var out bytes.Buffer    cmd.Stdout = &out    err := cmd.Run()    if err != nil {        log.Fatal(err)    }}要跳过机器,请使用 ssh 配置文件中的 ProxyCommand 指令。Host remote_machine_name  ProxyCommand ssh -q bastion nc remote_machine_ip 22

UYOU

这里的其他解决方案也可以,但我会抛出另一个你可以尝试的选项:simplessh。我认为它更容易使用。对于这个问题,我将使用下面的选项 3,您可以在其中使用您的密钥进行 ssh。选项 1:使用密码 SSH 到机器,然后运行命令import (    "log"    "github.com/sfreiberg/simplessh")func main() error {    var client *simplessh.Client    var err error    if client, err = simplessh.ConnectWithPassword("hostname_to_ssh_to", "username", "password"); err != nil {        return err    }    defer client.Close()    // Now run the commands on the remote machine:    if _, err := client.Exec("cat /tmp/somefile"); err != nil {        log.Println(err)    }    return nil}选项 2:使用一组可能的密码通过 SSH 连接到机器,然后运行命令import (    "log"    "github.com/sfreiberg/simplessh")type access struct {    login    string    password string}var loginAccess []accessfunc init() {    // Initialize all password to try    loginAccess = append(loginAccess, access{"root", "rootpassword1"})    loginAccess = append(loginAccess, access{"someuser", "newpassword"})}func main() error {    var client *simplessh.Client    var err error    // Try to connect with first password, then tried second else fails gracefully    for _, credentials := range loginAccess {        if client, err = simplessh.ConnectWithPassword("hostname_to_ssh_to", credentials.login, credentials.password); err == nil {            break        }    }    if err != nil {        return err    }    defer client.Close()    // Now run the commands on the remote machine:    if _, err := client.Exec("cat /tmp/somefile"); err != nil {        log.Println(err)    }    return nil}选项 3:使用您的密钥通过 SSH 连接到机器import (    "log"    "github.com/sfreiberg/simplessh")func SshAndRunCommand() error {    var client *simplessh.Client    var err error    // Option A: Using a specific private key path:    //if client, err = simplessh.ConnectWithKeyFile("hostname_to_ssh_to", "username", "/home/user/.ssh/id_rsa"); err != nil {    // Option B: Using your default private key at $HOME/.ssh/id_rsa:    //if client, err = simplessh.ConnectWithKeyFile("hostname_to_ssh_to", "username"); err != nil {    // Option C: Use the current user to ssh and the default private key file:    if client, err = simplessh.ConnectWithKeyFile("hostname_to_ssh_to"); err != nil {        return err    }    defer client.Close()    // Now run the commands on the remote machine:    if _, err := client.Exec("cat /tmp/somefile"); err != nil {        log.Println(err)    }    return nil}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go