From 81fc057c831933917b00f2c36bb5fd79134c15d2 Mon Sep 17 00:00:00 2001 From: Pachakutiq <101460915+PACHAKUTlQ@users.noreply.github.com> Date: Thu, 28 Aug 2025 16:43:39 +0800 Subject: [PATCH] feat(raw search)!: Use utls to mimic chrome TLS clienthello fingerprint --- baidu/search_raw.go | 27 +++++++++++++++++++++++++++ google/search_raw.go | 27 +++++++++++++++++++++++++++ yandex/search_raw.go | 27 +++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/baidu/search_raw.go b/baidu/search_raw.go index 998e3b0..9da8e71 100644 --- a/baidu/search_raw.go +++ b/baidu/search_raw.go @@ -1,8 +1,10 @@ package baidu import ( + "context" "crypto/tls" "fmt" + "net" "net/http" "net/url" "strings" @@ -12,6 +14,8 @@ import ( "github.com/corpix/uarand" "github.com/karust/openserp/core" "github.com/sirupsen/logrus" + + utls "github.com/refraction-networking/utls" ) func baiduRequest(searchURL string, query core.Query) (*http.Response, error) { @@ -30,6 +34,29 @@ func baiduRequest(searchURL string, query core.Query) (*http.Response, error) { transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} } + transport.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + dialer := &net.Dialer{} + rawConn, err := dialer.DialContext(ctx, network, addr) + if err != nil { + return nil, err + } + + hostname := strings.Split(addr, ":")[0] + config := &utls.Config{ + ServerName: hostname, + InsecureSkipVerify: query.Insecure, + } + + uconn := utls.UClient(rawConn, config, utls.HelloChrome_Auto) + + if err := uconn.Handshake(); err != nil { + rawConn.Close() + return nil, err + } + + return uconn, nil + } + baseClient := &http.Client{ Transport: transport, Timeout: time.Second * 10, diff --git a/google/search_raw.go b/google/search_raw.go index 72543bc..7fd403d 100644 --- a/google/search_raw.go +++ b/google/search_raw.go @@ -1,7 +1,9 @@ package google import ( + "context" "crypto/tls" + "net" "net/http" "net/url" "strings" @@ -11,6 +13,8 @@ import ( "github.com/corpix/uarand" "github.com/karust/openserp/core" "github.com/sirupsen/logrus" + + utls "github.com/refraction-networking/utls" ) func googleRequest(searchURL string, query core.Query) (*http.Response, error) { @@ -29,6 +33,29 @@ func googleRequest(searchURL string, query core.Query) (*http.Response, error) { transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} } + transport.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + dialer := &net.Dialer{} + rawConn, err := dialer.DialContext(ctx, network, addr) + if err != nil { + return nil, err + } + + hostname := strings.Split(addr, ":")[0] + config := &utls.Config{ + ServerName: hostname, + InsecureSkipVerify: query.Insecure, + } + + uconn := utls.UClient(rawConn, config, utls.HelloChrome_Auto) + + if err := uconn.Handshake(); err != nil { + rawConn.Close() + return nil, err + } + + return uconn, nil + } + baseClient := &http.Client{ Transport: transport, Timeout: time.Second * 10, diff --git a/yandex/search_raw.go b/yandex/search_raw.go index 69d8884..87d7e00 100644 --- a/yandex/search_raw.go +++ b/yandex/search_raw.go @@ -1,7 +1,9 @@ package yandex import ( + "context" "crypto/tls" + "net" "net/http" "net/url" "strings" @@ -11,6 +13,8 @@ import ( "github.com/corpix/uarand" "github.com/karust/openserp/core" "github.com/sirupsen/logrus" + + utls "github.com/refraction-networking/utls" ) func yandexRequest(searchURL string, query core.Query) (*http.Response, error) { @@ -29,6 +33,29 @@ func yandexRequest(searchURL string, query core.Query) (*http.Response, error) { transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} } + transport.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + dialer := &net.Dialer{} + rawConn, err := dialer.DialContext(ctx, network, addr) + if err != nil { + return nil, err + } + + hostname := strings.Split(addr, ":")[0] + config := &utls.Config{ + ServerName: hostname, + InsecureSkipVerify: query.Insecure, + } + + uconn := utls.UClient(rawConn, config, utls.HelloChrome_Auto) + + if err := uconn.Handshake(); err != nil { + rawConn.Close() + return nil, err + } + + return uconn, nil + } + baseClient := &http.Client{ Transport: transport, Timeout: time.Second * 10,