为了账号安全,请及时绑定邮箱和手机立即绑定

使用 UTLS 和 HTTP 1.1 请求时通过代理连接

使用 UTLS 和 HTTP 1.1 请求时通过代理连接

Go
鸿蒙传说 2023-08-14 17:32:16
我正在尝试使用随机 TLS 指纹识别连接到主机。我正在使用https://github.com/refraction-networking/utls(请参阅我在https://github.com/refraction-networking/utls/issues/42上创建的问题)我现在的问题是,在打开该连接时如何利用 HTTP 或 SOCKS5 代理?我现在使用的代码是:package mainimport (    "bufio"    "fmt"    "log"    "net"    "net/http"    "net/http/httputil"    "net/url"    "time"    "github.com/refraction-networking/utls")var (    dialTimeout   = time.Duration(15) * time.Second)var requestHostname = "google.com"var requestAddr = "172.217.22.110:443"// this example generates a randomized fingeprint, then re-uses it in a follow-up connectionfunc HttpGetConsistentRandomized(hostname string, addr , uri string) (*http.Response, error) {    config := tls.Config{ServerName: hostname}    tcpConn, err := net.DialTimeout("tcp", addr, dialTimeout)    if err != nil {        return nil, fmt.Errorf("net.DialTimeout error: %+v", err)    }    uTlsConn := tls.UClient(tcpConn, &config, tls.HelloRandomized)    defer uTlsConn.Close()    err = uTlsConn.Handshake()    if err != nil {        return nil, fmt.Errorf("uTlsConn.Handshake() error: %+v", err)    }    uTlsConn.Close()    // At this point uTlsConn.ClientHelloID holds a seed that was used to generate    // randomized fingerprint. Now we can establish second connection with same fp    tcpConn2, err := net.DialTimeout("tcp", addr, dialTimeout)    if err != nil {        return nil, fmt.Errorf("net.DialTimeout error: %+v", err)    }    uTlsConn2 := tls.UClient(tcpConn2, &config, uTlsConn.ClientHelloID)    defer uTlsConn2.Close()    err = uTlsConn2.Handshake()    if err != nil {        return nil, fmt.Errorf("uTlsConn.Handshake() error: %+v", err)    }    return httpGetOverConn(uTlsConn2, uTlsConn2.HandshakeState.ServerHello.AlpnProtocol, uri)}
查看完整描述

2 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

您必须首先创建一个代理拨号器,拨打代理以创建 net.Conn,然后在握手之前创建 uTLS 客户端时使用该 net.Conn。为了简洁起见,您的自定义 dialTLS 函数将类似于:


import (

    "crypto/tls"

    "net"

    "net/url"    


    "github.com/magisterquis/connectproxy"

    "golang.org/x/net/proxy"

    utls "github.com/refraction-networking/utls"

)


var proxyString = "http://127.0.0.1:8080"

                                                                          

dialTLS := func(network, addr string, _ *tls.Config) (net.Conn, error) {

    proxyURI, _ := url.Parse(proxyString)


    switch proxyURI.Scheme {                                                       

    case "socks5":                                                                 

            proxyDialer, err = proxy.SOCKS5("tcp", proxyString, nil, proxy.Direct)

    case "http":                                                          

            proxyDialer, err = connectproxy.New(proxyURI, proxy.Direct)            

    }   


    conn, err := proxyDialer.Dial("tcp", addr)

    uconn := utls.UClient(conn, cfg, &utls.HelloRandomizedALPN) 


    ...


查看完整回答
反对 回复 2023-08-14
?
慕村225694

TA贡献1880条经验 获得超4个赞

HTTP 代理和 SOCKS 代理的工作原理是在 TCP 连接后进行一些初始代理特定握手。握手完成后,它们会提供一个普通的 TCP 套接字,然后可用于进行 TLS 握手等。因此,您所需要做的就是替换您的

tcpConn, err := net.DialTimeout("tcp", addr, dialTimeout)

使用代理特定方法来设置 TCP 连接。这可以通过使用SOCKS5创建适当的拨号器或使用 HTTP CONNECT 方法在connectproxyx/net/proxy中完成类似的操作来完成。


查看完整回答
反对 回复 2023-08-14
  • 2 回答
  • 0 关注
  • 252 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信