From 58e38d7f190b94439d724c3702076214ea327da7 Mon Sep 17 00:00:00 2001 From: Anders Pitman Date: Sun, 22 Nov 2020 13:49:48 -0700 Subject: [PATCH] Implement HTTPS requests from client to upstreams Can now put "https://" in front of Client Address to force it to use TLS. It doesn't do any verification of the upstream cert. This is intended to work similarly to the way ngrok does it: https://ngrok.com/docs#http-local-https --- client.go | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/client.go b/client.go index 5e67f00..2417bd5 100644 --- a/client.go +++ b/client.go @@ -2,6 +2,7 @@ package main import ( "context" + "crypto/tls" "encoding/json" "errors" "flag" @@ -13,6 +14,7 @@ import ( "net" "net/http" "os" + "strings" "sync" "time" ) @@ -240,15 +242,35 @@ func (c *BoringProxyClient) BoreTunnel(tunnel Tunnel) context.CancelFunc { return cancelFunc } -func (c *BoringProxyClient) handleConnection(conn net.Conn, addr string, port int) { +func (c *BoringProxyClient) handleConnection(conn net.Conn, upstreamAddr string, port int) { defer conn.Close() - upstreamConn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", addr, port)) + useTls := false + addr := upstreamAddr + + if strings.HasPrefix(upstreamAddr, "https://") { + addr = upstreamAddr[len("https://"):] + useTls = true + } + + var upstreamConn net.Conn + var err error + + if useTls { + tlsConfig := &tls.Config{ + InsecureSkipVerify: true, + } + upstreamConn, err = tls.Dial("tcp", fmt.Sprintf("%s:%d", addr, port), tlsConfig) + } else { + upstreamConn, err = net.Dial("tcp", fmt.Sprintf("%s:%d", addr, port)) + } + if err != nil { log.Print(err) return } + defer upstreamConn.Close() var wg sync.WaitGroup @@ -260,7 +282,13 @@ func (c *BoringProxyClient) handleConnection(conn net.Conn, addr string, port in if err != nil { log.Println(err.Error()) } - upstreamConn.(*net.TCPConn).CloseWrite() + + if c, ok := upstreamConn.(*net.TCPConn); ok { + c.CloseWrite() + } else if c, ok := upstreamConn.(*tls.Conn); ok { + c.CloseWrite() + } + wg.Done() }()