Динамический порт пересылает трафик TCP через обратный туннель SSH - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть SSH-туннель, который подключается к конечной точке сервера и запускает удаленного прослушивателя через порт 1080.Моя цель - динамически пересылать любой TCP-трафик с этого порта на клиентскую часть туннеля.Хотя я могу принять поток TCP, я не могу найти способ Dial на стороне клиента туннеля SSH.Похоже, dialer, который я передаю, является serverConn серверным SSH-концом туннеля.И когда я пытаюсь remote, err := dialer.DialTCP("tcp4", local.RemoteAddr().(*net.TCPAddr), addr), я получаю набор трафика на удаленном конце.Я хочу найти способ дозвониться на стороне клиента через обратный туннель.

Я не собираюсь переадресовывать определенные порты в определенное место назначения на локальном компьютере, но хочу сделать более динамичную переадресацию портов, подобную опции ssh -D.Я сам управляю назначением TCP-трафика, это не проблема.

Я попытался создать ssh.NewClient из переданного serverConn, но для этого нужно выполнить SSH-рукопожатие, и Iam только получает необработанный TCP через порт 1080, поэтому он не является действительным 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
}
...