2014-06-26 19 views
5

Tôi đang cố gắng kết nối với máy chủ Linux AWS amazon bằng khóa bằng gói [ssh] [1] của ngôn ngữ lập trình Go. Tuy nhiên các tài liệu gói là một chút khó hiểu/khó hiểu. Có ai biết làm thế nào để kết nối thông qua ssh bằng cách sử dụng một phím hoặc ít nhất là nếu nó có thể? Có gì làm tôi bực mình là trong [Quay số] [3] Ví dụ nó nóiKết nối với máy chủ bằng SSH và pem/key bằng golang

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

tôi về cơ bản muốn bắt chước các ssh -i x.pem [email protected] hành vi và thực thi một lệnh bên trong máy chủ (ví dụ như whoami)

+1

sự hoảng loạn ngụ ý bạn đang bỏ qua lỗi ở đâu đó (hoặc đặt trì hoãn trước khi kiểm tra lỗi). chúng tôi cần một số mã để biết bạn đang làm gì. – JimB

+0

@JimB Tôi đã thêm một số mã. Tôi nghĩ rằng tôi đã kiểm tra tất cả các lỗi. Sự trì hoãn để đóng phiên được thiết lập sau khi kiểm tra lỗi – hey

+1

sự hoảng sợ của bạn là vì bạn đang gọi 'trì hoãn session.Close()' trên đó phiên là nil. 't.Error (err)' không trả về sớm. – JimB

Trả lời

10

Bạn cần sử dụng ssh.PublicKeys để chuyển danh sách ssh.Signers thành ssh.AuthMethod. Bạn có thể sử dụng ssh.ParsePrivateKey để nhận được Signer từ byte byte hoặc nếu bạn cần sử dụng khóa riêng tư, rsa, dsa hoặc ecdsa, bạn có thể cung cấp cho số ssh.NewSignerFromKey.

Dưới đây là một ví dụ được tô điểm một chút với hỗ trợ tác nhân quá (vì sử dụng tác nhân thường là bước tiếp theo sau khi chỉ sử dụng tệp khóa).

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!") 

... 
+0

Tôi không chắc mình hiểu mã. Làm cách nào để chuyển tệp khóa (ví dụ: mykey.pem) hoặc nội dung chính? Người ký dường như là một giao diện. Tôi có các khóa được lưu trữ trong một db – hey

+1

Tôi đã thêm một lưu ý về việc sử dụng 'ParsePrivateKey' để có được một người ký từ các byte pem. – JimB

+0

tại sao tôi cần '' agent''? có vẻ như được khai báo nhưng không được sử dụng khi tôi sử dụng '' signers, err: = ssh.ParsePrivateKey (cl.Key) '' – hey

6

Dưới đây là một ví dụ để chạy ls từ xa sử dụng "đồng bằng tập tin khóa bí mật" của bạn.

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) 
Các vấn đề liên quan