From 4e1cb6ebf650083c2a51897134c6b128bfc5d8e4 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Wed, 8 Apr 2020 01:09:51 +0800 Subject: [PATCH] trojan: added trojan support --- README.md | 240 ++--------------------------------------- conf.go | 4 + go.mod | 9 +- go.sum | 28 ++--- main.go | 1 + proxy/kcp/kcp.go | 2 +- proxy/trojan/trojan.go | 141 ++++++++++++++++++++++++ 7 files changed, 176 insertions(+), 249 deletions(-) create mode 100644 proxy/trojan/trojan.go diff --git a/README.md b/README.md index bb00581..9680871 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Forward (local proxy client/upstream proxy server): - SS proxy(tcp&udp&uot) - SSR proxy(tcp) - VMess proxy(tcp) +- Trojan proxy(tcp) - TLS, use it together with above proxy protocols(tcp) - Websocket, use it together with above proxy protocols(tcp) - Unix domain socket, use it together with above proxy protocols(tcp) @@ -81,7 +82,7 @@ Binary: - [https://github.com/nadoo/glider/releases](https://github.com/nadoo/glider/releases) -Go Get (requires **Go 1.13+** ): +Go Get (requires **Go 1.14+** ): ```bash go get -u github.com/nadoo/glider @@ -95,244 +96,23 @@ sudo pacman -S glider ## Run -command line: - +help: ```bash -glider -listen :8443 -verbose +glider -h ``` -config file: - +run: +```bash +glider -verbose -listen :8443 -forward SCHEME://HOST:PORT +``` ```bash glider -config CONFIGPATH ``` - -command line with config file: - ```bash glider -config CONFIGPATH -listen :8080 -verbose ``` -## Usage - -```bash -glider 0.10.0 usage: - -checkinterval int - proxy check interval(seconds) (default 30) - -checktimeout int - proxy check timeout(seconds) (default 10) - -checkwebsite string - proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80 (default "www.apple.com") - -config string - config file path - -dns string - local dns server listen address - -dnsalwaystcp - always use tcp to query upstream dns servers no matter there is a forwarder or not - -dnsmaxttl int - maximum TTL value for entries in the CACHE(seconds) (default 1800) - -dnsminttl int - minimum TTL value for entries in the CACHE(seconds) - -dnsrecord value - custom dns record, format: domain/ip - -dnsserver value - remote dns server address - -dnstimeout int - timeout value used in multiple dnsservers switch(seconds) (default 3) - -forward value - forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS] - -include value - include file - -interface string - source ip or source interface - -listen value - listen url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS - -maxfailures int - max failures to change forwarder status to disabled (default 3) - -rulefile value - rule file path - -rules-dir string - rule file folder - -strategy string - forward strategy, default: rr (default "rr") - -verbose - verbose mode - -Available Schemes: - mixed: serve as a http/socks5 proxy on the same port. (default) - ss: ss proxy - socks5: socks5 proxy - http: http proxy - ssr: ssr proxy - vmess: vmess proxy - tls: tls transport - ws: websocket transport - redir: redirect proxy. (used on linux as a transparent proxy with iptables redirect rules) - redir6: redirect proxy(ipv6) - tcptun: tcp tunnel - udptun: udp tunnel - uottun: udp over tcp tunnel - unix: unix domain socket - kcp: kcp protocol - simple-obfs: simple-obfs protocol - reject: a virtual proxy which just reject connections - -Available schemes for different modes: - listen: mixed ss socks5 http redir redir6 tcptun udptun uottun tls unix kcp - forward: reject ss socks5 http ssr vmess tls ws unix kcp simple-obfs - -SS scheme: - ss://method:pass@host:port - -Available methods for ss: - AEAD Ciphers: - AEAD_AES_128_GCM AEAD_AES_192_GCM AEAD_AES_256_GCM AEAD_CHACHA20_POLY1305 AEAD_XCHACHA20_POLY1305 - Stream Ciphers: - AES-128-CFB AES-128-CTR AES-192-CFB AES-192-CTR AES-256-CFB AES-256-CTR CHACHA20-IETF XCHACHA20 CHACHA20 RC4-MD5 - Alias: - chacha20-ietf-poly1305 = AEAD_CHACHA20_POLY1305, xchacha20-ietf-poly1305 = AEAD_XCHACHA20_POLY1305 - Plain: DUMMY - -SSR scheme: - ssr://method:pass@host:port?protocol=xxx&protocol_param=yyy&obfs=zzz&obfs_param=xyz - -VMess scheme: - vmess://[security:]uuid@host:port?alterID=num - -Available securities for vmess: - none, aes-128-gcm, chacha20-poly1305 - -TLS client scheme: - tls://host:port[?skipVerify=true] - -Proxy over tls client: - tls://host:port[?skipVerify=true],scheme:// - tls://host:port[?skipVerify=true],http://[user:pass@] - tls://host:port[?skipVerify=true],socks5://[user:pass@] - tls://host:port[?skipVerify=true],vmess://[security:]uuid@?alterID=num - -TLS server scheme: - tls://host:port?cert=PATH&key=PATH - -Proxy over tls server: - tls://host:port?cert=PATH&key=PATH,scheme:// - tls://host:port?cert=PATH&key=PATH,http:// - tls://host:port?cert=PATH&key=PATH,socks5:// - tls://host:port?cert=PATH&key=PATH,ss://method:pass@ - -Websocket scheme: - ws://host:port[/path][?host=HOST] - -Websocket with a specified proxy protocol: - ws://host:port[/path][?host=HOST],scheme:// - ws://host:port[/path][?host=HOST],http://[user:pass@] - ws://host:port[/path][?host=HOST],socks5://[user:pass@] - ws://host:port[/path][?host=HOST],vmess://[security:]uuid@?alterID=num - -TLS and Websocket with a specified proxy protocol: - tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],scheme:// - tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],http://[user:pass@] - tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],socks5://[user:pass@] - tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],vmess://[security:]uuid@?alterID=num - -Unix domain socket scheme: - unix://path - -KCP scheme: - kcp://CRYPT:KEY@host:port[?dataShards=NUM&parityShards=NUM] - -Available crypt types for KCP: - none, sm4, tea, xor, aes, aes-128, aes-192, blowfish, twofish, cast5, 3des, xtea, salsa20 - -Simple-Obfs scheme: - simple-obfs://host:port[?type=TYPE&host=HOST&uri=URI&ua=UA] - -Available types for simple-obfs: - http, tls - -DNS forwarding server: - dns=:53 - dnsserver=8.8.8.8:53 - dnsserver=1.1.1.1:53 - dnsrecord=www.example.com/1.2.3.4 - dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946 - -Available forward strategies: - rr: Round Robin mode - ha: High Availability mode - lha: Latency based High Availability mode - dh: Destination Hashing mode - -Forwarder option scheme: FORWARD_URL#OPTIONS - priority: set the priority of that forwarder, default:0 - interface: set local interface or ip address used to connect remote server - - - Examples: - socks5://1.1.1.1:1080#priority=100 - vmess://[security:]uuid@host:port?alterID=num#priority=200 - vmess://[security:]uuid@host:port?alterID=num#priority=200&interface=192.168.1.99 - vmess://[security:]uuid@host:port?alterID=num#priority=200&interface=eth0 - -Config file format(see `glider.conf.example` as an example): - # COMMENT LINE - KEY=VALUE - KEY=VALUE - # KEY equals to command line flag name: listen forward strategy... - -Examples: - glider -config glider.conf - -run glider with specified config file. - - glider -listen :8443 -verbose - -listen on :8443, serve as http/socks5 proxy on the same port, in verbose mode. - - glider -listen ss://AEAD_CHACHA20_POLY1305:pass@:8443 -verbose - -listen on 0.0.0.0:8443 as a ss server. - - glider -listen socks5://user1:pass1@:1080 -verbose - -listen on :1080 as a socks5 proxy server, enable authentication. - - glider -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose - -listen on :443 as a https(http over tls) proxy server. - - glider -listen http://:8080 -forward socks5://127.0.0.1:1080 - -listen on :8080 as a http proxy server, forward all requests via socks5 server. - - glider -listen redir://:1081 -forward ss://method:pass@1.1.1.1:8443 - -listen on :1081 as a transparent redirect server, forward all requests via remote ss server. - - glider -listen redir://:1081 -forward "ssr://method:pass@1.1.1.1:8444?protocol=a&protocol_param=b&obfs=c&obfs_param=d" - -listen on :1081 as a transparent redirect server, forward all requests via remote ssr server. - - glider -listen redir://:1081 -forward "tls://1.1.1.1:443,vmess://security:uuid@?alterID=10" - -listen on :1081 as a transparent redirect server, forward all requests via remote tls+vmess server. - - glider -listen redir://:1081 -forward "ws://1.1.1.1:80,vmess://security:uuid@?alterID=10" - -listen on :1081 as a transparent redirect server, forward all requests via remote ws+vmess server. - - glider -listen tcptun://:80=2.2.2.2:80 -forward ss://method:pass@1.1.1.1:8443 - -listen on :80 and forward all requests to 2.2.2.2:80 via remote ss server. - - glider -listen udptun://:53=8.8.8.8:53 -forward ss://method:pass@1.1.1.1:8443 - -listen on :53 and forward all udp requests to 8.8.8.8:53 via remote ss server. - - glider -listen uottun://:53=8.8.8.8:53 -forward ss://method:pass@1.1.1.1:8443 - -listen on :53 and forward all udp requests via udp over tcp tunnel. - - glider -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:8443 - -listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server. - - glider -listen redir://:1081 -dns=:53 -dnsserver=8.8.8.8:53 -forward ss://method:pass@server1:port1,ss://method:pass@server2:port2 - -listen on :1081 as transparent redirect server, :53 as dns server, use forward chain: server1 -> server2. - - glider -listen socks5://:1080 -forward ss://method:pass@server1:port1 -forward ss://method:pass@server2:port2 -strategy rr - -listen on :1080 as socks5 server, forward requests via server1 and server2 in round robin mode. - - glider -verbose -dns=:53 -dnsserver=8.8.8.8:53 -dnsrecord=www.example.com/1.2.3.4 - -listen on :53 as dns server, forward dns requests to 8.8.8.8:53, return 1.2.3.4 when resolving www.example.com. -``` - -## Advanced Usage +## Config - [ConfigFile](config) - [glider.conf.example](config/glider.conf.example) @@ -341,7 +121,7 @@ Examples: - [transparent proxy with dnsmasq](config/examples/8.transparent_proxy_with_dnsmasq) - [transparent proxy without dnsmasq](config/examples/9.transparent_proxy_without_dnsmasq) -### Proxy & Protocol Chain +## Proxy & Protocol Chain In glider, you can easily chain several proxy servers or protocols together, e.g: - Chain proxy servers: diff --git a/conf.go b/conf.go index f94b701..685086c 100644 --- a/conf.go +++ b/conf.go @@ -158,6 +158,10 @@ func usage() { fmt.Fprintf(w, " vmess://[security:]uuid@host:port?alterID=num\n") fmt.Fprintf(w, "\n") + fmt.Fprintf(w, "Trojan scheme:\n") + fmt.Fprintf(w, " trojan://pass@host:port[?skipVerify=true]\n") + fmt.Fprintf(w, "\n") + fmt.Fprintf(w, "Available securities for vmess:\n") fmt.Fprintf(w, " none, aes-128-gcm, chacha20-poly1305\n") fmt.Fprintf(w, "\n") diff --git a/go.mod b/go.mod index 69d58f3..106d990 100644 --- a/go.mod +++ b/go.mod @@ -5,15 +5,14 @@ go 1.14 require ( github.com/klauspost/cpuid v1.2.3 // indirect github.com/mzz2017/shadowsocksR v0.0.0-20200126130347-721f53a7b15a - github.com/nadoo/conflag v0.2.2 + github.com/nadoo/conflag v0.2.3 github.com/nadoo/go-shadowsocks2 v0.1.2 github.com/pkg/errors v0.9.1 // indirect - github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect github.com/tjfoc/gmsm v1.3.0 // indirect - github.com/xtaci/kcp-go v5.4.20+incompatible - golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8 + github.com/xtaci/kcp-go/v5 v5.5.11 + golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect - golang.org/x/sys v0.0.0-20200406113430-c6e801f48ba2 // indirect + golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4 // indirect ) // Replace dependency modules with local developing copy diff --git a/go.sum b/go.sum index ba23a95..4f80fe9 100644 --- a/go.sum +++ b/go.sum @@ -2,7 +2,6 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/go-camellia v0.0.0-20140412174459-3be6b3054dd1 h1:/5UddQ9I3CXetvBVN2ipRc209YUB0AMR8bufErftAxI= github.com/dgryski/go-camellia v0.0.0-20140412174459-3be6b3054dd1/go.mod h1:QX5ZVULjAfZJux/W62Y91HvCh9hyW6enAwcrrv/sLj0= github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d h1:CPqTNIigGweVPT4CYb+OO2E6XyRKFOmvTHwWRLgCAlE= github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d/go.mod h1:QX5ZVULjAfZJux/W62Y91HvCh9hyW6enAwcrrv/sLj0= @@ -12,8 +11,8 @@ github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152 h1:ED31mPIxDJnrLt9W github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152/go.mod h1:I9fhc/EvSg88cDxmfQ47v35Ssz9rlFunL/KY0A1JAYI= github.com/ebfe/rc2 v0.0.0-20131011165748-24b9757f5521 h1:fBHFH+Y/GPGFGo7LIrErQc3p2MeAhoIQNgaxPWYsSxk= github.com/ebfe/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:ucvhdsUCE3TH0LoLRb6ShHiJl8e39dGlx6A4g/ujlow= -github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY= @@ -22,10 +21,11 @@ github.com/mzz2017/shadowsocksR v0.0.0-20200126130347-721f53a7b15a h1:lM2cQgk1E5 github.com/mzz2017/shadowsocksR v0.0.0-20200126130347-721f53a7b15a/go.mod h1:1SJEvxD2Y+N7SK2NpCC4wSatvfGGTUo2rhPdthUFsCU= github.com/nadoo/conflag v0.2.2 h1:xywuyaevdBnA3+4g9S11ng+Nby725WN1LXargWnAXpM= github.com/nadoo/conflag v0.2.2/go.mod h1:dzFfDUpXdr2uS2oV+udpy5N2vfNOu/bFzjhX1WI52co= +github.com/nadoo/conflag v0.2.3 h1:/+rTaN0bHTIiQbPl1WZK78JRoqjlNqJ9Zf05ep0o5jI= +github.com/nadoo/conflag v0.2.3/go.mod h1:dzFfDUpXdr2uS2oV+udpy5N2vfNOu/bFzjhX1WI52co= github.com/nadoo/glider v0.9.2/go.mod h1:S/94KRJFNtgoNlyEm4+33f/DrEsj/uxvismOW4FlIa0= github.com/nadoo/go-shadowsocks2 v0.1.2 h1:+tCSt65YAAMf24wj3tqv6a9oVBcqSGFYVsifBZwT9w8= github.com/nadoo/go-shadowsocks2 v0.1.2/go.mod h1:/E2kSkS0mqF/e79wcAA0PezoWXk4CY9HldJlzwWtbwU= -github.com/nadoo/shadowsocksR v0.1.0 h1:sYPxZi0l8F1nxDDcckzb0DHXxhe0LNW5iSeohqPw6Fg= github.com/nadoo/shadowsocksR v0.1.0/go.mod h1:nqcLRU7laARXdLLBrHP8odruT/6GIureicuRTs4R+RY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -35,46 +35,48 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU= +github.com/templexxx/cpu v0.0.1 h1:hY4WdLOgKdc8y13EYklu9OUTXik80BkxHoWvTO6MQQY= +github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= -github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b h1:mnG1fcsIB1d/3vbkBak2MM0u+vhGhlQwpeimUi7QncM= github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= -github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI= github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= +github.com/templexxx/xorsimd v0.4.1 h1:iUZcywbOYDRAZUasAs2eSCUW8eobuZDy0I9FJiORkVg= +github.com/templexxx/xorsimd v0.4.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2fqEr8qaNo= github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= github.com/tjfoc/gmsm v1.3.0 h1:i7c6Za/IlgBvnGxYpfD7L3TGuaS+v6oGcgq+J9/ecEA= github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= -github.com/xtaci/kcp-go v5.4.11+incompatible h1:tJbtarpmOoOD74cZ41uvvF5Hyt1nvctHQCOxZ6ot5xw= github.com/xtaci/kcp-go v5.4.11+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg= github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= +github.com/xtaci/kcp-go/v5 v5.5.11 h1:wYvoREAp6bG3sYwtxhY1QelbB/1fNggCtkt2DwqFj2M= +github.com/xtaci/kcp-go/v5 v5.5.11/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= gitlab.com/yawning/chacha20.git v0.0.0-20190903091407-6d1cb28dc72c h1:yrfrd1u7MWIwWIulet2TZPEkeNQhQ/GcPLdPXgiEEr0= gitlab.com/yawning/chacha20.git v0.0.0-20190903091407-6d1cb28dc72c/go.mod h1:3x6b94nWCP/a2XB/joOPMiGYUBvqbLfeY/BkHLeDs6s= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191010185427-af544f31c8ac h1:/b4NMZurYfBIQyRMqaPGMDeUrSW6gU7/7Hv6owY1Vjk= golang.org/x/crypto v0.0.0-20191010185427-af544f31c8ac/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8 h1:fpnn/HnJONpIu6hkXi1u/7rR0NzilgWr4T0JmWkEitk= -golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y= +golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191009170203-06d7bd2c5f4f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200406113430-c6e801f48ba2 h1:Z9pPywZscwuw0ijrLEbTzW9lppFgBY4HDgbvoDnreQs= -golang.org/x/sys v0.0.0-20200406113430-c6e801f48ba2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4 h1:c1Sgqkh8v6ZxafNGG64r8C8UisIW2TKMJN8P86tKjr0= +golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/main.go b/main.go index f5950a0..f920ca5 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ import ( _ "github.com/nadoo/glider/proxy/ssr" _ "github.com/nadoo/glider/proxy/tcptun" _ "github.com/nadoo/glider/proxy/tls" + _ "github.com/nadoo/glider/proxy/trojan" _ "github.com/nadoo/glider/proxy/udptun" _ "github.com/nadoo/glider/proxy/uottun" _ "github.com/nadoo/glider/proxy/vmess" diff --git a/proxy/kcp/kcp.go b/proxy/kcp/kcp.go index 1a70581..6e45a8b 100644 --- a/proxy/kcp/kcp.go +++ b/proxy/kcp/kcp.go @@ -9,7 +9,7 @@ import ( "strconv" "strings" - kcp "github.com/xtaci/kcp-go" + kcp "github.com/xtaci/kcp-go/v5" "golang.org/x/crypto/pbkdf2" "github.com/nadoo/glider/common/log" diff --git a/proxy/trojan/trojan.go b/proxy/trojan/trojan.go new file mode 100644 index 0000000..aba9a0a --- /dev/null +++ b/proxy/trojan/trojan.go @@ -0,0 +1,141 @@ +// protocol spec: +// https://trojan-gfw.github.io/trojan/protocol +// +-----------------------+---------+----------------+---------+----------+ +// | hex(SHA224(password)) | CRLF | Trojan Request | CRLF | Payload | +// +-----------------------+---------+----------------+---------+----------+ +// | 56 | X'0D0A' | Variable | X'0D0A' | Variable | +// +-----------------------+---------+----------------+---------+----------+ + +// where Trojan Request is a SOCKS5-like request: + +// +-----+------+----------+----------+ +// | CMD | ATYP | DST.ADDR | DST.PORT | +// +-----+------+----------+----------+ +// | 1 | 1 | Variable | 2 | +// +-----+------+----------+----------+ + +// where: +// o CMD +// o CONNECT X'01' +// o UDP ASSOCIATE X'03' +// o ATYP address type of following address +// o IP V4 address: X'01' +// o DOMAINNAME: X'03' +// o IP V6 address: X'04' +// o DST.ADDR desired destination address +// o DST.PORT desired destination port in network octet order + +package trojan + +import ( + "bytes" + "crypto/sha256" + "crypto/tls" + "encoding/hex" + "errors" + "net" + "net/url" + "strings" + + "github.com/nadoo/glider/common/log" + "github.com/nadoo/glider/common/socks" + "github.com/nadoo/glider/proxy" +) + +// Trojan is a base trojan struct. +type Trojan struct { + dialer proxy.Dialer + proxy proxy.Proxy + addr string + pass [56]byte + serverName string + skipVerify bool + tlsConfig *tls.Config +} + +func init() { + proxy.RegisterDialer("trojan", NewTrojanDialer) + // proxy.RegisterServer("trojan", NewTrojanServer) +} + +// NewTrojan returns a trojan proxy. +func NewTrojan(s string, d proxy.Dialer, p proxy.Proxy) (*Trojan, error) { + u, err := url.Parse(s) + if err != nil { + log.F("[trojan] parse err: %s", err) + return nil, err + } + + t := &Trojan{ + dialer: d, + proxy: p, + addr: u.Host, + } + + // pass + hash := sha256.New224() + hash.Write([]byte(u.User.Username())) + hex.Encode(t.pass[:], hash.Sum(nil)) + + // serverName + colonPos := strings.LastIndex(t.addr, ":") + if colonPos == -1 { + colonPos = len(t.addr) + } + t.serverName = t.addr[:colonPos] + + // skipVerify + if u.Query().Get("skipVerify") == "true" { + t.skipVerify = true + } + + t.tlsConfig = &tls.Config{ + ServerName: t.serverName, + InsecureSkipVerify: t.skipVerify, + NextProtos: []string{"http/1.1"}, + ClientSessionCache: tls.NewLRUClientSessionCache(64), + MinVersion: tls.VersionTLS10, + } + + return t, nil +} + +// NewTrojanDialer returns a trojan proxy dialer. +func NewTrojanDialer(s string, d proxy.Dialer) (proxy.Dialer, error) { + return NewTrojan(s, d, nil) +} + +// Addr returns forwarder's address. +func (s *Trojan) Addr() string { + if s.addr == "" { + return s.dialer.Addr() + } + return s.addr +} + +// Dial connects to the address addr on the network net via the proxy. +func (s *Trojan) Dial(network, addr string) (net.Conn, error) { + rc, err := s.dialer.Dial("tcp", s.addr) + if err != nil { + return nil, err + } + + tlsConn := tls.Client(rc, s.tlsConfig) + if err := tlsConn.Handshake(); err != nil { + return nil, err + } + + var buf bytes.Buffer + buf.Write(s.pass[:]) + buf.WriteString("\r\n") + buf.WriteByte(1) + buf.Write(socks.ParseAddr(addr)) + buf.WriteString("\r\n") + _, err = tlsConn.Write(buf.Bytes()) + return tlsConn, err +} + +// DialUDP connects to the given address via the proxy. +func (s *Trojan) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) { + return nil, nil, errors.New("trojan client does not support udp now") +}