From eefbd63e5a164d52a85c553e0a966cf0b44cff75 Mon Sep 17 00:00:00 2001 From: Ambrose Chua Date: Wed, 4 Sep 2019 15:16:02 +0800 Subject: [PATCH] Fix missing bypass and update README --- README.md | 10 ++++++-- server.go | 74 +++++++++++++++++++++++++++++++++---------------------- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index c71f942..bdcaa8b 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,17 @@ A simple TCP proxy. Currently used in [AppVenture](https://appventure.nushigh.ed $ ./forward -help Usage of ./forward: -connect string - forward to ip and port (default ":8080") + forward to address -listen string - listen on ip and port (default ":8081") + listen on address (default ":8000") + -ssh string + if set, will do basic introspection to forward SSH traffic to this address ``` +### Usage with SSH + +You can use `forward` to do multiplexing of SSH and HTTP in a quick and dirty way, using very simple protocol introspection. A more robust solution would be [sshttp](https://github.com/stealth/sshttp) + ## Usage on Windows `forward` is wrapped with [go-svc](https://github.com/judwhite/go-svc), enabling it to be run as a Windows service. To add with PowerShell: diff --git a/server.go b/server.go index 03c8e07..bc62bad 100644 --- a/server.go +++ b/server.go @@ -70,37 +70,53 @@ var magic = []byte{'S', 'S', 'H', '-'} var magicLen = len(magic) func handle(c net.Conn, count int) { - // read first four characters - readMagic := make([]byte, magicLen, magicLen) - n, err := c.Read(readMagic) - if n != magicLen { - log.Printf("warning! could not read header") - return - } - opError, ok := err.(*net.OpError) - if err != nil && (!ok || opError.Op != "readfrom") { - log.Printf("warning! %v", err) - return - } + if connSSH != nil { + + // read first four characters + readMagic := make([]byte, magicLen, magicLen) + n, err := c.Read(readMagic) + if n != magicLen { + log.Printf("warning! could not read header") + return + } + opError, ok := err.(*net.OpError) + if err != nil && (!ok || opError.Op != "readfrom") { + log.Printf("warning! %v", err) + return + } + + connTo := conn + // if the header looks like SSH, forward to SSH connection + if bytes.Equal(readMagic, magic) { + connTo = connSSH + } + + cn, err := net.DialTCP("tcp", nil, connTo) + if err != nil { + c.Close() + log.Print(err) + return + } + + // write the first four characters + cn.Write(readMagic) + + go pipe(c, cn, count) + go pipe(cn, c, count) + + } else { + + cn, err := net.DialTCP("tcp", nil, conn) + if err != nil { + c.Close() + log.Print(err) + return + } + + go pipe(c, cn, count) + go pipe(cn, c, count) - connTo := conn - // if the header looks like SSH, forward to SSH connection - if bytes.Equal(readMagic, magic) { - connTo = connSSH } - - cn, err := net.DialTCP("tcp", nil, connTo) - if err != nil { - c.Close() - log.Print(err) - return - } - - // write the first four characters - cn.Write(readMagic) - - go pipe(c, cn, count) - go pipe(cn, c, count) } func pipe(w io.WriteCloser, r io.ReadCloser, count int) {