diff --git a/README.md b/README.md index f4fd04f..647d7b8 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ Usage of ja3proxy: utls client (default "Golang") -version string utls client version (default "0") + -upstream string + upstream proxy, e.g. 127.0.0.1:1080, socks5 only -debug enable debug ``` diff --git a/cert.go b/cert.go index 3b5ed21..17ca94e 100644 --- a/cert.go +++ b/cert.go @@ -61,7 +61,3 @@ func loadCertificate() { LoadedCert = cert } } - -var ( - LoadedCert tls.Certificate -) diff --git a/config.go b/config.go index be55b1a..d66ced9 100644 --- a/config.go +++ b/config.go @@ -1,5 +1,9 @@ package main +import ( + "crypto/tls" +) + type RunningConfig struct { Debug bool Addr string @@ -8,8 +12,11 @@ type RunningConfig struct { TLSClient string Cert string Key string + Upstream string } var ( - Config RunningConfig + Config RunningConfig + LoadedCert tls.Certificate + CustomDialer *UpstreamDialer ) diff --git a/dialer.go b/dialer.go new file mode 100644 index 0000000..fd45907 --- /dev/null +++ b/dialer.go @@ -0,0 +1,32 @@ +package main + +import ( + "net" + "time" + + "golang.org/x/net/proxy" +) + +type UpstreamDialer struct { + dialer proxy.Dialer +} + +func NewUpstreamDialer(socksAddr string, timeout time.Duration) (*UpstreamDialer, error) { + var dialer proxy.Dialer + + if socksAddr != "" { + socksDialer, err := proxy.SOCKS5("tcp", socksAddr, nil, proxy.Direct) + if err != nil { + return nil, err + } + dialer = socksDialer + } else { + dialer = &net.Dialer{Timeout: timeout} + } + + return &UpstreamDialer{dialer: dialer}, nil +} + +func (u *UpstreamDialer) Dial(network, addr string) (net.Conn, error) { + return u.dialer.Dial(network, addr) +} diff --git a/go.mod b/go.mod index cac3922..d5d9562 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,10 @@ module github.com/lylemi/ja3proxy go 1.20 -require github.com/refraction-networking/utls v1.3.2 +require ( + github.com/refraction-networking/utls v1.3.2 + golang.org/x/net v0.7.0 +) require ( github.com/andybalholm/brotli v1.0.4 // indirect diff --git a/go.sum b/go.sum index 50bc90d..2100be6 100644 --- a/go.sum +++ b/go.sum @@ -8,5 +8,7 @@ github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KP github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/main.go b/main.go index 1dae2db..75714c4 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "os" + "time" ) func main() { @@ -15,6 +16,7 @@ func main() { flag.StringVar(&Config.Port, "port", "8080", "proxy listen port") flag.StringVar(&Config.TLSClient, "client", "Golang", "utls client") flag.StringVar(&Config.TLSVersion, "version", "0", "utls client version") + flag.StringVar(&Config.Upstream, "upstream", "", "upstream proxy, e.g. 127.0.0.1:1080, socks5 only") flag.BoolVar(&Config.Debug, "debug", false, "enable debug") flag.Parse() @@ -33,6 +35,13 @@ func main() { loadCertificate() + var err error + CustomDialer, err = NewUpstreamDialer(Config.Upstream, time.Second*10) + + if err != nil { + log.Fatal(err) + } + server := &http.Server{ Addr: Config.Addr + ":" + Config.Port, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -48,7 +57,7 @@ func main() { "HTTP Proxy Server listen at %s:%s, with tls fingerprint %s %s\n", Config.Addr, Config.Port, Config.TLSVersion, Config.TLSClient, ) - err := server.ListenAndServe() + err = server.ListenAndServe() if err != nil { log.Fatal(err) os.Exit(-1)