From 40ddd1be3a2bd5906405044082ac54e1c42cf866 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Sun, 11 Oct 2020 01:15:28 +0800 Subject: [PATCH] trojan: add new scheme trojanc (trojan cleartext) --- README.md | 7 +++++-- config.go | 6 ++++-- config/glider.conf.example | 2 +- go.mod | 2 +- go.sum | 4 ++-- proxy/trojan/client.go | 25 ++++++++++++++++++++----- proxy/trojan/server.go | 33 ++++++++++++++++++++++++--------- proxy/trojan/trojan.go | 21 ++++++++++++++------- 8 files changed, 71 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index e84d40a..b10fd58 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ we can set up local listeners as proxy servers, and forward requests to internet |ssr | | |√| |client only |ssh | | |√| |client only |trojan |√|√|√|√|client & server +|trojanc |√|√|√|√|trojan cleartext(without tls) |vless |√|√|√|√|client & server |vmess | | |√| |client only |redir |√| | | |linux only @@ -141,8 +142,8 @@ glider -h verbose mode Available schemes: - listen: mixed ss socks5 http vless trojan redir redir6 tcptun udptun uottun tls unix kcp - forward: reject ss socks4 socks5 http ssr ssh vless vmess trojan tls ws unix kcp simple-obfs + listen: mixed ss socks5 http vless trojan trojanc redir redir6 tcptun udptun uottun tls unix kcp + forward: reject ss socks4 socks5 http ssr ssh vless vmess trojan trojanc tls ws unix kcp simple-obfs Socks5 scheme: socks://[user:pass@]host:port @@ -173,9 +174,11 @@ VLESS scheme: Trojan client scheme: trojan://pass@host:port[?serverName=SERVERNAME][&skipVerify=true] + trojanc://pass@host:port (cleartext, without TLS) Trojan server scheme: trojan://pass@host:port?cert=PATH&key=PATH + trojanc://pass@host:port (cleartext, without TLS) Available securities for vmess: none, aes-128-gcm, chacha20-poly1305 diff --git a/config.go b/config.go index 6d9f739..b78b143 100644 --- a/config.go +++ b/config.go @@ -130,8 +130,8 @@ func usage() { fmt.Fprintf(w, "\n") fmt.Fprintf(w, "Available schemes:\n") - fmt.Fprintf(w, " listen: mixed ss socks5 http vless trojan redir redir6 tcptun udptun uottun tls unix kcp\n") - fmt.Fprintf(w, " forward: reject ss socks4 socks5 http ssr ssh vless vmess trojan tls ws unix kcp simple-obfs\n") + fmt.Fprintf(w, " listen: mixed ss socks5 http vless trojan trojanc redir redir6 tcptun udptun uottun tls unix kcp\n") + fmt.Fprintf(w, " forward: reject ss socks4 socks5 http ssr ssh vless vmess trojan trojanc tls ws unix kcp simple-obfs\n") fmt.Fprintf(w, "\n") fmt.Fprintf(w, "Socks5 scheme:\n") @@ -170,10 +170,12 @@ func usage() { fmt.Fprintf(w, "Trojan client scheme:\n") fmt.Fprintf(w, " trojan://pass@host:port[?serverName=SERVERNAME][&skipVerify=true]\n") + fmt.Fprintf(w, " trojanc://pass@host:port (cleartext, without TLS)\n") fmt.Fprintf(w, "\n") fmt.Fprintf(w, "Trojan server scheme:\n") fmt.Fprintf(w, " trojan://pass@host:port?cert=PATH&key=PATH\n") + fmt.Fprintf(w, " trojanc://pass@host:port (cleartext, without TLS)\n") fmt.Fprintf(w, "\n") fmt.Fprintf(w, "Available securities for vmess:\n") diff --git a/config/glider.conf.example b/config/glider.conf.example index 8db3e70..1f6085e 100644 --- a/config/glider.conf.example +++ b/config/glider.conf.example @@ -79,7 +79,7 @@ listen=socks5://:1080 # listen=tls://:1234?cert=/path/to/cert&key=/path/to/key,vless://UUID@?fallback=127.0.0.1:80 # trojan server -#listen=trojan://PASSWORD:1234?cert=/path/to/cert&key=/path/to/key +# listen=trojan://PASSWORD:1234?cert=/path/to/cert&key=/path/to/key # FORWARDERS # ---------- diff --git a/go.mod b/go.mod index 2229d99..b486918 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 golang.org/x/net v0.0.0-20201009032441-dbdefad45b89 // indirect golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 // indirect - golang.org/x/tools v0.0.0-20201009162240-fcf82128ed91 // indirect + golang.org/x/tools v0.0.0-20201010145503-6e5c6d77ddcc // indirect gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect ) diff --git a/go.sum b/go.sum index ca8b5d3..4200d3b 100644 --- a/go.sum +++ b/go.sum @@ -177,8 +177,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU= golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201009162240-fcf82128ed91 h1:UNUk0ao5UA0V4v2wikQWc4U+yG5UGoWku8MHs27mMqs= -golang.org/x/tools v0.0.0-20201009162240-fcf82128ed91/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201010145503-6e5c6d77ddcc h1:NJuVOHii6+cOLWV2ofkVwU7frODgrUFHcjHCxyQ4DqI= +golang.org/x/tools v0.0.0-20201010145503-6e5c6d77ddcc/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/proxy/trojan/client.go b/proxy/trojan/client.go index 9715192..82841ed 100644 --- a/proxy/trojan/client.go +++ b/proxy/trojan/client.go @@ -10,6 +10,18 @@ import ( "github.com/nadoo/glider/proxy/socks" ) +// NewClearTextDialer returns a trojan cleartext proxy dialer. +func NewClearTextDialer(s string, d proxy.Dialer) (proxy.Dialer, error) { + t, err := NewTrojan(s, d, nil) + if err != nil { + log.F("[trojan] create instance error: %s", err) + return nil, err + } + + t.clearText = true + return t, err +} + // NewTrojanDialer returns a trojan proxy dialer. func NewTrojanDialer(s string, d proxy.Dialer) (proxy.Dialer, error) { t, err := NewTrojan(s, d, nil) @@ -49,9 +61,12 @@ func (s *Trojan) dial(network, addr string) (net.Conn, error) { return nil, err } - tlsConn := tls.Client(rc, s.tlsConfig) - if err := tlsConn.Handshake(); err != nil { - return nil, err + if !s.clearText { + tlsConn := tls.Client(rc, s.tlsConfig) + if err := tlsConn.Handshake(); err != nil { + return nil, err + } + rc = tlsConn } buf := pool.GetWriteBuffer() @@ -68,9 +83,9 @@ func (s *Trojan) dial(network, addr string) (net.Conn, error) { buf.Write(socks.ParseAddr(addr)) buf.WriteString("\r\n") - _, err = tlsConn.Write(buf.Bytes()) + _, err = rc.Write(buf.Bytes()) - return tlsConn, err + return rc, err } // DialUDP connects to the given address via the proxy. diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index b1ebf27..b80faf6 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -15,6 +15,18 @@ import ( "github.com/nadoo/glider/proxy/socks" ) +// NewClearTextServer returns a trojan cleartext proxy server. +func NewClearTextServer(s string, p proxy.Proxy) (proxy.Server, error) { + t, err := NewTrojan(s, nil, p) + if err != nil { + log.F("[trojan] create instance error: %s", err) + return nil, err + } + + t.clearText = true + return t, nil +} + // NewTrojanServer returns a trojan proxy server. func NewTrojanServer(s string, p proxy.Proxy) (proxy.Server, error) { t, err := NewTrojan(s, nil, p) @@ -60,18 +72,21 @@ func (s *Trojan) ListenAndServe() { } // Serve serves a connection. -func (s *Trojan) Serve(cc net.Conn) { - defer cc.Close() +func (s *Trojan) Serve(c net.Conn) { + defer c.Close() - if cc, ok := cc.(*net.TCPConn); ok { - cc.SetKeepAlive(true) + if c, ok := c.(*net.TCPConn); ok { + c.SetKeepAlive(true) } - c := tls.Server(cc, s.tlsConfig) - err := c.Handshake() - if err != nil { - log.F("[trojan] error in tls handshake: %s", err) - return + if !s.clearText { + tlsConn := tls.Server(c, s.tlsConfig) + err := tlsConn.Handshake() + if err != nil { + log.F("[trojan] error in tls handshake: %s", err) + return + } + c = tlsConn } cmd, target, err := s.readHeader(c) diff --git a/proxy/trojan/trojan.go b/proxy/trojan/trojan.go index 43b9336..9236a63 100644 --- a/proxy/trojan/trojan.go +++ b/proxy/trojan/trojan.go @@ -18,20 +18,27 @@ import ( // Trojan is a base trojan struct. type Trojan struct { - dialer proxy.Dialer - proxy proxy.Proxy - addr string - pass [56]byte + dialer proxy.Dialer + proxy proxy.Proxy + addr string + pass [56]byte + + clearText bool + + tlsConfig *tls.Config + serverName string skipVerify bool - tlsConfig *tls.Config - certFile string - keyFile string + + certFile string + keyFile string } func init() { proxy.RegisterDialer("trojan", NewTrojanDialer) proxy.RegisterServer("trojan", NewTrojanServer) + proxy.RegisterDialer("trojanc", NewClearTextDialer) // cleartext + proxy.RegisterServer("trojanc", NewClearTextServer) // cleartext } // NewTrojan returns a trojan proxy.