使用Golang使用SSH和pem/key连接到服务器。

huangapple go评论108阅读模式
英文:

Connect to a server using SSH and a pem / key with golang

问题

我正在尝试使用Go编程语言的ssh包连接到一个使用密钥的Amazon AWS Linux服务器。然而,该包的文档有点晦涩和令人困惑。有人知道如何使用密钥连接到ssh,或者至少知道是否可能吗?让我困扰的是,在Dial的示例中,它说:

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

我基本上想模仿ssh -i x.pem root@server.com的行为,并在服务器内执行一个命令(例如whoami)。

英文:

I'm trying to connect to an amazon AWS linux server with a key using the ssh package of Go programming language. However the package documentation is a bit cryptic/confusing. Does anyone know how to connect through ssh using a key or at least if it's possible ? What bothers me is that in the Dial example it says

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

I basically want to mimic the ssh -i x.pem root@server.com behavior and execute a command inside the server ( e.g. whoami )

答案1

得分: 24

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

下面是一个示例,稍微添加了一些代理支持(因为在仅使用密钥文件之后,通常会使用代理)。

  1. sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
  2. if err != nil {
  3. log.Fatal(err)
  4. }
  5. agent := agent.NewClient(sock)
  6. signers, err := agent.Signers()
  7. if err != nil {
  8. log.Fatal(err)
  9. }
  10. // 或者直接从私钥文件获取签名者
  11. // signer, err := ssh.ParsePrivateKey(pemBytes)
  12. // if err != nil {
  13. // log.Fatal(err)
  14. // }
  15. auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)}
  16. cfg := &ssh.ClientConfig{
  17. User: "username",
  18. Auth: auths,
  19. }
  20. cfg.SetDefaults()
  21. client, err := ssh.Dial("tcp", "aws-hostname:22", cfg)
  22. if err != nil {
  23. log.Fatal(err)
  24. }
  25. session, err = client.NewSession()
  26. if err != nil {
  27. log.Fatal(err)
  28. }
  29. log.Println("we have a session!")
  30. ...

希望对你有帮助!

英文:

You need to use ssh.PublicKeys to turn a list of ssh.Signers into an ssh.AuthMethod. You can use ssh.ParsePrivateKey to get a Signer from the pem bytes, or if you need to use an rsa, dsa or ecdsa private key, you can give those to ssh.NewSignerFromKey.

Here's an example fleshed out a bit with Agent support too (since using an agent is usually the next step after simply using a key file).

  1. sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
  2. if err != nil {
  3. log.Fatal(err)
  4. }
  5. agent := agent.NewClient(sock)
  6. signers, err := agent.Signers()
  7. if err != nil {
  8. log.Fatal(err)
  9. }
  10. // or get the signer from your private key file directly
  11. // signer, err := ssh.ParsePrivateKey(pemBytes)
  12. // if err != nil {
  13. // log.Fatal(err)
  14. // }
  15. auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)}
  16. cfg := &ssh.ClientConfig{
  17. User: "username",
  18. Auth: auths,
  19. }
  20. cfg.SetDefaults()
  21. client, err := ssh.Dial("tcp", "aws-hostname:22", cfg)
  22. if err != nil {
  23. log.Fatal(err)
  24. }
  25. session, err = client.NewSession()
  26. if err != nil {
  27. log.Fatal(err)
  28. }
  29. log.Println("we have a session!")
  30. ...

答案2

得分: 15

这是一个使用你的“普通私钥文件”远程运行ls命令的示例。

  1. pemBytes, err := ioutil.ReadFile("/location/to/YOUR.pem")
  2. if err != nil {
  3. log.Fatal(err)
  4. }
  5. signer, err := ssh.ParsePrivateKey(pemBytes)
  6. if err != nil {
  7. log.Fatalf("解析密钥失败:%v", err)
  8. }
  9. config := &ssh.ClientConfig{
  10. User: "ubuntu",
  11. Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
  12. HostKeyCallback: ssh.InsecureIgnoreHostKey(),
  13. }
  14. conn, err := ssh.Dial("tcp", "yourhost.com:22", config)
  15. if err != nil {
  16. log.Fatalf("连接失败:%v", err)
  17. }
  18. defer conn.Close()
  19. session, err := conn.NewSession()
  20. if err != nil {
  21. log.Fatalf("创建会话失败:%v", err)
  22. }
  23. defer session.Close()
  24. var stdoutBuf bytes.Buffer
  25. session.Stdout = &stdoutBuf
  26. err = session.Run("ls -l")
  27. if err != nil {
  28. log.Fatalf("运行命令失败:%v", err)
  29. }
  30. log.Printf(">%s", stdoutBuf)

希望对你有帮助!

英文:

Here is an example to run ls remotely using your "plain private key file".

  1. pemBytes, err := ioutil.ReadFile("/location/to/YOUR.pem")
  2. if err != nil {
  3. log.Fatal(err)
  4. }
  5. signer, err := ssh.ParsePrivateKey(pemBytes)
  6. if err != nil {
  7. log.Fatalf("parse key failed:%v", err)
  8. }
  9. config := &ssh.ClientConfig{
  10. User: "ubuntu",
  11. Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
  12. HostKeyCallback: ssh.InsecureIgnoreHostKey(),
  13. }
  14. conn, err := ssh.Dial("tcp", "yourhost.com:22", config)
  15. if err != nil {
  16. log.Fatalf("dial failed:%v", err)
  17. }
  18. defer conn.Close()
  19. session, err := conn.NewSession()
  20. if err != nil {
  21. log.Fatalf("session failed:%v", err)
  22. }
  23. defer session.Close()
  24. var stdoutBuf bytes.Buffer
  25. session.Stdout = &stdoutBuf
  26. err = session.Run("ls -l")
  27. if err != nil {
  28. log.Fatalf("Run failed:%v", err)
  29. }
  30. log.Printf(">%s", stdoutBuf)

huangapple
  • 本文由 发表于 2014年6月27日 02:37:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/24437809.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定