Skip to content

Instantly share code, notes, and snippets.

@iamralch
Last active August 21, 2024 05:15
Show Gist options
  • Select an option

  • Save iamralch/5d695dcc4cc6ad5dd275 to your computer and use it in GitHub Desktop.

Select an option

Save iamralch/5d695dcc4cc6ad5dd275 to your computer and use it in GitHub Desktop.
SSH tunnelling in Golang
package main
import (
"log"
"bufio"
"time"
"os"
"fmt"
"io"
"net"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
type Endpoint struct {
Host string
Port int
}
func (endpoint *Endpoint) String() string {
return fmt.Sprintf("%s:%d", endpoint.Host, endpoint.Port)
}
type SSHtunnel struct {
Local *Endpoint
Server *Endpoint
Remote *Endpoint
Config *ssh.ClientConfig
}
func (tunnel *SSHtunnel) Start() error {
listener, err := net.Listen("tcp", tunnel.Local.String())
if err != nil {
return err
}
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
return err
}
go tunnel.forward(conn)
}
}
func (tunnel *SSHtunnel) forward(localConn net.Conn) {
serverConn, err := ssh.Dial("tcp", tunnel.Server.String(), tunnel.Config)
if err != nil {
fmt.Printf("Server dial error: %s\n", err)
return
}
remoteConn, err := serverConn.Dial("tcp", tunnel.Remote.String())
if err != nil {
fmt.Printf("Remote dial error: %s\n", err)
return
}
copyConn:=func(writer, reader net.Conn) {
defer writer.Close()
defer reader.Close()
_, err:= io.Copy(writer, reader)
if err != nil {
fmt.Printf("io.Copy error: %s", err)
}
}
go copyConn(localConn, remoteConn)
go copyConn(remoteConn, localConn)
}
func SSHAgent() ssh.AuthMethod {
if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)
}
return nil
}
func main() {
localEndpoint := &Endpoint{
Host: "localhost",
Port: 9000,
}
serverEndpoint := &Endpoint{
Host: "example.com",
Port: 22,
}
remoteEndpoint := &Endpoint{
Host: "localhost",
Port: 8080,
}
sshConfig := &ssh.ClientConfig{
User: "vcap",
Auth: []ssh.AuthMethod{
SSHAgent(),
},
}
tunnel := &SSHtunnel{
Config: sshConfig,
Local: localEndpoint,
Server: serverEndpoint,
Remote: remoteEndpoint,
}
tunnel.Start()
}
@daihu
Copy link
Copy Markdown

daihu commented Jul 8, 2020

work for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment