我尝试使用Go编程语言的[ssh] [1]包使用密钥连接到amazon AWS linux服务器。但是包文档有点神秘/混乱。有没有人知道如何使用密钥通过ssh连接,或者至少是否可能?令我困扰的是,在[拨号] [3]示例中,它说
// An SSH client is represented with a ClientConn. Currently only
// the "password" authentication method is supported.
我基本上想模仿ssh -i x.pem root@server.com行为并在服务器内执行命令(例如whoami
)
答案 0 :(得分:20)
您需要使用ssh.PublicKeys
将ssh.Signers
列表转换为ssh.AuthMethod
。您可以使用ssh.ParsePrivateKey
从pem字节中获取Signer
,或者如果您需要使用rsa,dsa或ecdsa私钥,则可以将这些内容提供给ssh.NewSignerFromKey
。
这里的一个例子也充实了代理支持(因为在使用密钥文件之后使用代理通常是下一步)。
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!")
...
答案 1 :(得分:9)
以下是使用“普通私钥文件”远程运行 ls 的示例。
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)