2016-06-24 106 views
2

我正在嘗試編寫一個可以幫助解決防火牆/ NAT問題的服務器/客戶端。與GO的SSH反向隧道

我注意到SSH已經建成支持這樣做了。 (http://rustyrazorblade.com/2010/03/ssh-reverse-tunnel-to-access-box-behind-firewall/

我嘗試了幾個不同的SSH例子,似乎都沒有工作。我發現一個項目說它實現了遠程端口轉發 - >https://godoc.org/dev.justinjudd.org/justin/easyssh

服務器說它正在偵聽連接,但我無法從服務器計算機到客戶端計算機進行SSH連接。 (遠程機器上的ssh本地主機8080應該轉發給客戶端機器

客戶 - >

package main 

import (
    "log" 

    "dev.justinjudd.org/justin/easyssh" 
    "golang.org/x/crypto/ssh" 
) 

func main() { 
    config := &ssh.ClientConfig{ 
    User: "test", 
    Auth: []ssh.AuthMethod{ 
     ssh.Password("test"), 
    }, 
    } 


    conn, err := easyssh.Dial("tcp", "*SSH-SERVER*:22", config) 
    if err != nil { 
    log.Fatalf("unable to connect: %s", err) 
    } 
    defer conn.Close() 

    err = conn.RemoteForward("0.0.0.0:8080", "127.0.0.1:22") 
    if err != nil { 
    log.Fatalf("unable to forward local port: %s", err) 
    } 

} 

服務器 - >

package main 

import (
    "fmt" 
    "io/ioutil" 
    "log" 

    "dev.justinjudd.org/justin/easyssh" 

    "golang.org/x/crypto/ssh" 
) 

func main() { 

    privateBytes, err := ioutil.ReadFile("id_rsa") 
    if err != nil { 
    log.Fatal("Failed to load private key (./id_rsa)") 
    } 

    private, err := ssh.ParsePrivateKey(privateBytes) 
    if err != nil { 
    log.Fatal("Failed to parse private key") 
    } 

    config := &ssh.ServerConfig{ 
    PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { 
     if c.User() == "test" && string(pass) == "test" { 
     log.Printf("User logged in: %s", c.User()) 
     return nil, nil 
     } 
     return nil, fmt.Errorf("password rejected for %s", c.User()) 
    }, 
    } 
    config.AddHostKey(private) 


    easyssh.HandleChannel(easyssh.SessionRequest, easyssh.SessionHandler()) 
    easyssh.HandleChannel(easyssh.DirectForwardRequest, easyssh.DirectPortForwardHandler()) 
    easyssh.HandleRequestFunc(easyssh.RemoteForwardRequest, easyssh.TCPIPForwardRequest) 

    easyssh.ListenAndServe(":22", config, nil) 
} 
+0

我得到的代碼基本上工作。我試圖基本克隆http://ngrok.com –

+0

試圖讓代碼工作,但是當我使用ssh連接到轉發的本地端口時,沒有任何反應。你是如何得到它的工作?謝謝! – Anton

+0

https://gist.github.com/kevinpostal/0228941c2b594504ed1f39914a3bf1ca –

回答

0

我不知道您瞭解如何SSH隧道工程在您的代碼上查找

您需要SSH連接到第遠程(服務器)。 然後您設置SSH隧道,以便使用SSH連接將本地TCP:8080端口轉發到遠程服務器TCP:8080端口。實際的8080端口可以通過防火牆關閉。

您可以使用SSH從您的客戶端連接到您的服務器嗎?

您需要檢查localhost:8080端口,並且您需要確保您的服務器8080端口也被某些應用程序監聽。

請看一看here的一些例子和理論。

2

我發現easyssh有關遠程端口轉發了一個錯誤:

https://dev.justinjudd.org/justin/easyssh/src/master/tcpip.go#L107

ssh.DiscardRequests(reqs)應在分離goroutine運行,否則下一個數據傳輸將不會被執行。

+1

不知道爲什麼https://dev.justinjudd.org關閉了......當人們不使用github並嘗試託管他們自己的代碼時,他們很吝嗇......只有因爲它會永遠丟失 - –