动态端口通过反向SSH隧道转发TCP流量

时间:2018-11-14 18:32:37

标签: go reverse-proxy socks ssh-tunnel

我有一个SSH隧道,该隧道拨入服务器端点并在端口1080上启动远程侦听器。我的目标是将所有TCP通信从该端口动态转发到隧道的客户端。虽然我可以接受TCP流,但无法在SSH隧道的客户端上找到一种方法Dial。看来我传递的dialer是隧道的serverConn服务器SSH端。当我尝试remote, err := dialer.DialTCP("tcp4", local.RemoteAddr().(*net.TCPAddr), addr)时,我在远端获得了流量拨号。我想找到一种在反向隧道上拨出客户端的方法。

我不是希望将特定端口转发到本地的特定目的地,而是希望进行更多类似于ssh -D选项的动态端口转发。我自己在管理TCP流量的目的地,这不是问题。

我尝试从传递的ssh.NewClient创建serverConn,但是它需要执行SSH握手,并且Iam仅在端口1080上接收原始TCP,因此它不是有效的SSH客户。谢谢。

func main(){

    type Dialer interface {
       DialTCP(net string, laddr, raddr *net.TCPAddr) (net.Conn, error)
    }

    // SSH server connection
    sshConfig := &ssh.ClientConfig{
         User: "tester",
         Auth: []ssh.AuthMethod{
         ssh.PublicKeys(signer),
         },
         HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    // Connect to SSH remote server using serverEndpoint (port 22)
    serverConn, err := ssh.Dial("tcp", serverEndpoint.String(), sshConfig)

    if err != nil {
        log.Fatalln(fmt.Printf("Dial INTO remote server error: %s", err))
    }

    // Listen on remote server port (port 1080)
    listener, err := serverConn.Listen("tcp", 
                     remoteEndpoint.String())
    if err != nil {
        log.Fatalln(fmt.Printf("Listen open port ON remote server error: %s", err))
    }
    defer listener.Close()

    acceptSLoop(listener, serverConn)
}

func acceptSLoop(listener net.Listener, sshClient *ssh.Client) {

    fmt.Printf("Listener: %s\n", listener.Addr().String())
    defer listener.Close()
    for {
        clientConn, err := listener.Accept()
        fmt.Printf("local addr %s\n", clientConn.LocalAddr())
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("New connection found on %s\n", listener.Addr().String())
        listenSConnection(clientConn, sshClient, config)
     }
 }

func listenSConnection(SClientConn net.Conn, sshClient 
  *ssh.Client) {
     // In a regular SSH I need to do
     // sshConn, chans, reqs, err := 
     ssh.NewServerConn(SClientConn, // config will be 
         passed in ..)
     //
     // But since it's TCP handoff I am passing socket data 
        directly
     handleSConn(SClientConn, sshClient)
 }

func handleSConn(local net.Conn, dialer Dialer) {
       defer local.Close()

       // Both of those establish socket from "remote" ssh side (Server) not "local" ssh side (client)
       remote, err := dialer.DialTCP("tcp4", local.RemoteAddr().(*net.TCPAddr), addr)
       //remote, err := net.Dial("tcp4", addr.String())

       // transfer bytes from local SOCKS to remote desired endpoint over SSH
       transfer(local, remote)
}

// in - local SOCKS conn, out - remote desired endpoint
func transfer(in, out net.Conn) {
     //.... working
}

0 个答案:

没有答案