Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SSH和带有golang的pem/密钥连接到服务器_Ssh_Go - Fatal编程技术网

使用SSH和带有golang的pem/密钥连接到服务器

使用SSH和带有golang的pem/密钥连接到服务器,ssh,go,Ssh,Go,我正在尝试使用Go编程语言的[ssh][1]包,通过密钥连接到AmazonAWSLinux服务器。然而,软件包文档有点神秘/混乱。有人知道如何使用密钥或至少在可能的情况下通过ssh进行连接吗?让我烦恼的是,在[Dial][3]的例子中,它说 // An SSH client is represented with a ClientConn. Currently only // the "password" authentication method is supported. 我基本上想模仿s

我正在尝试使用Go编程语言的[ssh][1]包,通过密钥连接到AmazonAWSLinux服务器。然而,软件包文档有点神秘/混乱。有人知道如何使用密钥或至少在可能的情况下通过ssh进行连接吗?让我烦恼的是,在[Dial][3]的例子中,它说

// An SSH client is represented with a ClientConn. Currently only
// the "password" authentication method is supported.

我基本上想模仿ssh-ix.pemroot@server.com行为并在服务器内部执行命令(例如,
whoami

您需要使用
ssh.PublicKeys
ssh.Signers
列表转换为
ssh.AuthMethod
。您可以使用
ssh.ParsePrivateKey
从pem字节中获取
签名者
,或者如果您需要使用rsa、dsa或ecdsa私钥,您可以将它们提供给
ssh.NewSignerFromKey

下面是一个示例,该示例在代理支持方面也有所充实(因为使用代理通常是在使用密钥文件之后的下一步)


下面是一个使用“普通私钥文件”远程运行ls的示例


我不确定我是否理解代码。如何传递密钥文件(例如mykey.pem)或密钥内容?签名者似乎是一个接口。我将密钥存储在dbI中,并添加了关于使用
ParsePrivateKey
从pem字节中获取签名者的说明。为什么我需要
代理
?它似乎是声明的,但没有像我使用签名者那样使用,err:=ssh.ParsePrivateKey(cl.Key)您不需要在程序中使用代理,但由于您通常应该使用代理(您的密钥都是安全加密的,对吗?),所以它通常是使用普通私钥文件后的下一个“如何”请求。@JimB您的示例不清楚,我猜您依赖于一些默认值,任何SSH都涉及两个密钥,私钥和公钥,您的示例只使用私钥,公钥是通过使用SSH.PublicKeys的一些黑魔法检索的,但问题是,我如何指定公钥的位置,而不是依赖SSH.PublicKey的默认行为?如果我没有错的话,它只会尝试在默认位置定位公钥。恐慌意味着您忽略了某个地方的错误(或在检查错误之前设置延迟)。我们需要一些代码来知道你在做什么。@JimB我添加了一些代码。我想我已经检查了所有的错误。延迟关闭会话是在错误检查后设置的。您的恐慌是因为您在会话为零的情况下调用了
defer session.close()
t.Error(err)
不会提前返回。
sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
if err != nil {
    log.Fatal(err)
}

agent := agent.NewClient(sock)

signers, err := agent.Signers()
if err != nil {
    log.Fatal(err)
}

// or get the signer from your private key file directly
// signer, err := ssh.ParsePrivateKey(pemBytes)
// if err != nil {
//     log.Fatal(err)
// }

auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)}

cfg := &ssh.ClientConfig{
    User: "username",
    Auth: auths,
}
cfg.SetDefaults()

client, err := ssh.Dial("tcp", "aws-hostname:22", cfg)
if err != nil {
    log.Fatal(err)
}

session, err = client.NewSession()
if err != nil {
    log.Fatal(err)
}

log.Println("we have a session!")

...
    pemBytes, err := ioutil.ReadFile("/location/to/YOUR.pem")
    if err != nil {
        log.Fatal(err)
    }
    signer, err := ssh.ParsePrivateKey(pemBytes)
    if err != nil {
        log.Fatalf("parse key failed:%v", err)
    }
    config := &ssh.ClientConfig{
        User: "ubuntu",
        Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
    }
    conn, err := ssh.Dial("tcp", "yourhost.com:22", config)
    if err != nil {
        log.Fatalf("dial failed:%v", err)
    }
    defer conn.Close()
    session, err := conn.NewSession()
    if err != nil {
        log.Fatalf("session failed:%v", err)
    }
    defer session.Close()
    var stdoutBuf bytes.Buffer
    session.Stdout = &stdoutBuf
    err = session.Run("ls -l")
    if err != nil {
        log.Fatalf("Run failed:%v", err)
    }
    log.Printf(">%s", stdoutBuf)