title: SSH Reverse Tunnel with GO
body: <p>I am trying to write a server / client that can help get around Firewalls / Nat Issues.</p>
  
  <p>I noticed SSH has built into support for doing this already.
  (<a href="http://rustyrazorblade.com/2010/03/ssh-reverse-tunnel-to-access-box-behind-firewall/" rel="nofollow">http://rustyrazorblade.com/2010/03/ssh-reverse-tunnel-to-access-box-behind-firewall/</a>)</p>
  
  <p>I tried a few different SSH examples and none seem to be working. I found one project that says it implemented the Remote Port Fowarding -> <a href="https://godoc.org/dev.justinjudd.org/justin/easyssh" rel="nofollow">https://godoc.org/dev.justinjudd.org/justin/easyssh</a></p>
  
  <p>The Server says it is Listening for connections but I am unable to SSH from Server Machine To Client Machine. (ssh localhost 8080 on remote machine should forward to client machine.</p>
  
  <p><strong>Client</strong> -></p>
  
  <pre><code>package main
  
  import (
    "log"
  
    "dev.justinjudd.org/justin/easyssh"
    "golang.org/x/crypto/ssh"
  )
  
  func main() {
    config := &amp;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)
    }
  
  }
  </code></pre>
  
  <p><strong>Server</strong> -></p>
  
  <pre><code>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 := &amp;ssh.ServerConfig{
      PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
        if c.User() == "test" &amp;&amp; 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)
  }
  </code></pre>