From 90e17c84e9e671cbd849e4ac790b7d08f6115db1 Mon Sep 17 00:00:00 2001 From: "rui.zheng" Date: Thu, 6 Aug 2015 17:24:16 +0800 Subject: [PATCH] add tls tunnel --- README.md | 2 +- client.go | 8 +++++- log.go | 80 ------------------------------------------------------ main.go | 19 +++++++------ socks5.go | 6 ++-- tls.go | 51 ++++++++++++++++++++++++++++++++++ version.go | 2 +- ws.go | 2 +- 8 files changed, 76 insertions(+), 94 deletions(-) delete mode 100644 log.go create mode 100644 tls.go diff --git a/README.md b/README.md index a9312a7..e8bd58b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ gost - GO Simple Tunnel 5. 多种加密方式(tls,aes-256-cfb,des-cfb,rc4-md5等)。 6. 客户端兼容shadowsocks协议,可作为shadowsocks服务器。 -二进制文件下载:https://bintray.com/ginuerzh/gost/gost/view +二进制文件下载:https://github.com/ginuerzh/gost/releases Google讨论组: https://groups.google.com/d/forum/go-gost diff --git a/client.go b/client.go index 37c6cc8..29ac045 100644 --- a/client.go +++ b/client.go @@ -6,6 +6,7 @@ import ( "crypto/tls" "encoding/base64" "encoding/binary" + //"encoding/hex" "errors" "fmt" "github.com/ginuerzh/gosocks5" @@ -103,7 +104,11 @@ func makeTunnel() (c net.Conn, err error) { if err != nil { return } - if UseWebsocket { + + if UseTLS { + config := &tls.Config{InsecureSkipVerify: true} + c = tls.Client(c, config) + } else if UseWebsocket { ws, resp, err := websocket.NewClient(c, &url.URL{Host: Saddr}, nil, 8192, 8192) if err != nil { c.Close() @@ -166,6 +171,7 @@ func cliHandle(conn net.Conn) { req, err := http.ReadRequest(bufio.NewReader(newReqReader(b[:n], conn))) if err != nil { + //log.Println(hex.Dump(b[:n])) log.Println(err) return } diff --git a/log.go b/log.go deleted file mode 100644 index a16944b..0000000 --- a/log.go +++ /dev/null @@ -1,80 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "io" - "os" -) - -var ( - Debug bool -) - -type BufferedLog struct { - buffer *bytes.Buffer - w io.WriteCloser -} - -func NewLog(buffered bool) *BufferedLog { - log := &BufferedLog{ - w: os.Stdout, - } - if buffered { - log.buffer = &bytes.Buffer{} - } - - return log -} - -func NewFileLog(file *os.File) *BufferedLog { - return &BufferedLog{ - buffer: &bytes.Buffer{}, - w: file, - } -} - -func (log *BufferedLog) Log(a ...interface{}) (int, error) { - if !Debug { - return 0, nil - } - if log.buffer != nil { - return fmt.Fprint(log.buffer, a...) - } - return fmt.Fprint(log.w, a...) -} - -func (log *BufferedLog) Logln(a ...interface{}) (int, error) { - if !Debug { - return 0, nil - } - if log.buffer != nil { - return fmt.Fprintln(log.buffer, a...) - } - return fmt.Fprintln(log.w, a...) -} - -func (log *BufferedLog) Logf(format string, a ...interface{}) (int, error) { - if !Debug { - return 0, nil - } - if log.buffer != nil { - return fmt.Fprintf(log.buffer, format, a...) - } - return fmt.Fprintf(log.w, format, a...) -} - -func (log *BufferedLog) Flush() error { - defer func() { - if log.w != os.Stdout { - log.w.Close() - } - }() - - if !Debug || log.buffer == nil { - return nil - } - - _, err := log.buffer.WriteTo(log.w) - return err -} diff --git a/main.go b/main.go index 7dc27be..78c84aa 100644 --- a/main.go +++ b/main.go @@ -9,13 +9,13 @@ import ( ) var ( - Laddr, Saddr, Proxy string - UseWebsocket, UseHttp bool - Shadows bool - SMethod, SPassword string - Method, Password string - CertFile, KeyFile string - PrintVersion bool + Laddr, Saddr, Proxy string + UseWebsocket, UseHttp, UseTLS bool + Shadows bool + SMethod, SPassword string + Method, Password string + CertFile, KeyFile string + PrintVersion bool proxyURL *url.URL listenUrl *url.URL @@ -30,6 +30,7 @@ func init() { flag.StringVar(&CertFile, "cert", "", "tls cert file") flag.StringVar(&KeyFile, "key", "", "tls key file") flag.BoolVar(&Shadows, "ss", false, "run as shadowsocks server") + flag.BoolVar(&UseTLS, "tls", false, "use ssl/tls tunnel") flag.BoolVar(&UseWebsocket, "ws", false, "use websocket tunnel") flag.BoolVar(&UseHttp, "http", false, "use http tunnel") flag.StringVar(&SMethod, "sm", "rc4-md5", "shadowsocks cipher method") @@ -59,7 +60,9 @@ func main() { if len(Saddr) == 0 { var server Server - if UseWebsocket { + if UseTLS { + server = &TlsServer{Addr: laddr, CertFile: CertFile, KeyFile: KeyFile} + } else if UseWebsocket { server = &WSServer{Addr: laddr} } else if UseHttp { server = &HttpServer{Addr: laddr} diff --git a/socks5.go b/socks5.go index 4a30b29..37d1094 100644 --- a/socks5.go +++ b/socks5.go @@ -180,7 +180,7 @@ func serveSocks5(conn net.Conn) { //log.Println("connect", req.Addr.String()) tconn, err := connect(req.Addr.String()) if err != nil { - log.Println(err) + log.Println("connect", req.Addr.String(), err) gosocks5.NewReply(gosocks5.HostUnreachable, nil).Write(conn) return } @@ -198,6 +198,7 @@ func serveSocks5(conn net.Conn) { l, err := net.ListenTCP("tcp", nil) if err != nil { gosocks5.NewReply(gosocks5.Failure, nil).Write(conn) + log.Println("bind listen", err) return } @@ -207,6 +208,7 @@ func serveSocks5(conn net.Conn) { rep := gosocks5.NewReply(gosocks5.Succeeded, addr) if err := rep.Write(conn); err != nil { log.Println(err) + l.Close() return } @@ -233,7 +235,7 @@ func serveSocks5(conn net.Conn) { case gosocks5.CmdUdp: uconn, err := net.ListenUDP("udp", nil) if err != nil { - log.Println(err) + log.Println("udp listen", err) gosocks5.NewReply(gosocks5.Failure, nil).Write(conn) return } diff --git a/tls.go b/tls.go new file mode 100644 index 0000000..6864633 --- /dev/null +++ b/tls.go @@ -0,0 +1,51 @@ +package main + +import ( + "crypto/tls" + "github.com/ginuerzh/gosocks5" + "net" +) + +type TlsServer struct { + Addr string + CertFile, KeyFile string +} + +func (s *TlsServer) ListenAndServe() error { + return s.listenAndServeTLS() +} + +func (s *TlsServer) listenAndServeTLS() error { + var cert tls.Certificate + var err error + + if len(s.CertFile) == 0 || len(s.KeyFile) == 0 { + cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey)) + } else { + cert, err = tls.LoadX509KeyPair(s.CertFile, s.KeyFile) + } + if err != nil { + return err + } + + config := &tls.Config{Certificates: []tls.Certificate{cert}} + l, err := tls.Listen("tcp", s.Addr, config) + if err != nil { + return err + } + defer l.Close() + + for { + conn, err := l.Accept() + if err != nil { + return err + } + + go func(c net.Conn) { + c = gosocks5.ServerConn(c, serverConfig) + serveSocks5(c) + }(conn) + } + + return nil +} diff --git a/version.go b/version.go index 1a89efd..bb98490 100644 --- a/version.go +++ b/version.go @@ -5,7 +5,7 @@ import ( ) const ( - Version = "1.7" + Version = "1.8" ) func printVersion() { diff --git a/ws.go b/ws.go index e8e6d2d..c2db6ec 100644 --- a/ws.go +++ b/ws.go @@ -64,7 +64,7 @@ func (s *WSServer) handle(w http.ResponseWriter, r *http.Request) { log.Println(err) return } - defer conn.Close() + //defer conn.Close() c := gosocks5.ServerConn(NewWSConn(conn), serverConfig) /*