From 06070e0559cf4b8e0fa8f19ceb520015a81b03e6 Mon Sep 17 00:00:00 2001 From: lovedboy Date: Fri, 31 Mar 2017 15:09:43 +0800 Subject: [PATCH] add http proxy support (#6) --- README.md | 12 +++--- local/main.go | 32 +++++++++++++--- src/http_connect/http.go | 82 ++++++++++++++++++++++++++++++++++++++++ src/socks/socks5.go | 2 +- 4 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 src/http_connect/http.go diff --git a/README.md b/README.md index b1361f3..c0abf8b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # cracker -socks5 proxy over http +proxy over http[s], support http,socks5 proxy. ``` +------------+ +--------------+ -| local app | <=======> |socks5 client | <####### +| local app | <=======> |local proxy | <####### +------------+ +--------------+ # # # @@ -11,7 +11,7 @@ socks5 proxy over http # # +-------------+ +--------------+ # -| target host | <=======> | proxy server | <##### +| target host | <=======> |http[s] server| <##### +-------------+ +--------------+ ``` @@ -39,7 +39,7 @@ list ## Local side (Run on your local pc) ``` -./local -laddr 127.0.0.1:1080 -raddr http://example.com:8080 -secret +./local -raddr http://example.com:8080 -secret ``` ## https @@ -59,7 +59,7 @@ copy the certificate and private key into the same folder with server bin ``` ``` -./local -laddr 127.0.0.1:1080 -raddr https://example.com:8080 -secret +./local -raddr https://example.com:8080 -secret ``` Of Course, you can create a self-signed ssl certificate by openssl. @@ -75,7 +75,7 @@ copy the certificate into the same folder with local bin and bind the ip and hos ``` echo " " >> /etc/hosts -./local -laddr 127.0.0.1:1080 -raddr https://:8080 -secret +./local -raddr https://:8080 -secret ``` ## Next diff --git a/local/main.go b/local/main.go index 75277e1..417cdb0 100644 --- a/local/main.go +++ b/local/main.go @@ -3,10 +3,12 @@ package main import ( "flag" "fmt" + "http_connect" "logger" "os" "proxy" "socks" + "sync" ) var ( @@ -17,7 +19,8 @@ var ( var g = logger.GetLogger() func main() { - laddr := flag.String("laddr", "", "listen addr") + socks5Addr := flag.String("socks5", "127.0.0.1:1080", "socks5 listen addr") + httpAddr := flag.String("http", "127.0.0.1:8080", "http listen addr") raddr := flag.String("raddr", "", "remote http url(e.g, https://example.com)") secret := flag.String("secret", "", "secret key") debug := flag.Bool("debug", false, "debug mode") @@ -31,9 +34,28 @@ func main() { } logger.InitLogger(*debug) proxy.Init() - s, err := socks.NewSocks5(*laddr, *raddr, *secret) - if err != nil { - g.Fatal(err) + wg := &sync.WaitGroup{} + if *socks5Addr != "" { + s, err := socks.NewSocks5(*socks5Addr, *raddr, *secret) + if err != nil { + g.Fatal(err) + } + wg.Add(1) + go func() { + s.Wait() + wg.Done() + }() } - s.Wait() + if *httpAddr != "" { + h, err := http_connect.NewHttpConnect(*httpAddr, *raddr, *secret) + if err != nil { + g.Fatal(err) + } + wg.Add(1) + go func() { + h.Wait() + wg.Done() + }() + } + wg.Wait() } diff --git a/src/http_connect/http.go b/src/http_connect/http.go new file mode 100644 index 0000000..0158030 --- /dev/null +++ b/src/http_connect/http.go @@ -0,0 +1,82 @@ +package http_connect + +import ( + "bytes" + "fmt" + "io" + "logger" + "net" + "proxy" +) + +var g = logger.GetLogger() + +type httpConnect struct { + raddr string + secret string + wait chan bool +} + +func (h *httpConnect) handleConn(conn net.Conn) { + + defer conn.Close() + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil { + g.Errorf("read err:%s", err) + return + } + var method, addr string + fmt.Sscanf(string(buf[:bytes.IndexByte(buf[:n], '\n')]), "%s%s", &method, &addr) + g.Debugf("will connect %s ... ", addr) + lp, err := proxy.Connect(h.raddr, addr, h.secret) + if err != nil { + g.Errorf("proxy connect err:%s", err) + return + } + if method == "CONNECT" { + conn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n")) //响应客户端连接成功 + }else{ + conn.Write(buf[:n]) + } + //进行转发 + go func() { + _, err := io.Copy(conn, lp) + if err != nil { + g.Debugf("read err: %s", err) + } + lp.CloseRead() + }() + io.Copy(lp, conn) + lp.Close() + g.Debugf("close connection with %s", conn.RemoteAddr().String()) + +} + +func (h *httpConnect) Wait() { + <-h.wait +} + +func NewHttpConnect(addr, raddr, secret string) (h *httpConnect, err error) { + l, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + g.Infof("http proxy listen at:[%s]", addr) + h = &httpConnect{ + raddr: raddr, + secret: secret, + wait: make(chan bool), + } + go func() { + for { + conn, err := l.Accept() + if err != nil { + g.Errorf("accept err:%s", err) + } + go h.handleConn(conn) + + } + }() + return h, nil +} diff --git a/src/socks/socks5.go b/src/socks/socks5.go index e3d1dae..955043b 100644 --- a/src/socks/socks5.go +++ b/src/socks/socks5.go @@ -62,7 +62,7 @@ func (s *socks5) handleConn(conn net.Conn) { go func() { _, err := io.Copy(conn, lp) if err != nil { - g.Debugf("read err:", err) + g.Debugf("read err: %s", err) } lp.CloseRead() }()