Соединитесь через Прокси, используя UTLS и HTTP 1.1 Запрос - PullRequest
0 голосов
/ 10 марта 2020

Я пытаюсь подключиться к хосту с использованием случайного снятия отпечатков TLS. Я использую https://github.com/refraction-networking/utls (см. Мою проблему, которую я создал на https://github.com/refraction-networking/utls/issues/42)

Моя проблема сейчас, как я могу использовать прокси HTTP или SOCKS5 в то время как открывая это соединение?

Код, который я сейчас использую:

package main

import (
    "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 connection
func 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)
}

func main() {
    var response *http.Response
    var err error

    response, err = HttpGetConsistentRandomized(requestHostname, requestAddr, "/2.0/ssocookie")
    if err != nil {
        fmt.Printf("#> HttpGetConsistentRandomized() failed: %+v\n", err)
    } else {
        //fmt.Printf("#> HttpGetConsistentRandomized() response: %+s\n", httputil.DumpResponse(response,true))
        dump, err := httputil.DumpResponse(response, true)
        if err != nil {
            log.Fatal(err)
        }

        fmt.Printf("%+s\n", dump)
    }
    return
}

func httpGetOverConn(conn net.Conn, alpn string, uri string) (*http.Response, error) {

    req := &http.Request{
        Method: "GET",
        URL:    &url.URL{Host: "www." + requestHostname  + uri},
        Header: make(http.Header),
        Host:   "www." + requestHostname,
    }

        req.Proto = "HTTP/1.1"
        req.ProtoMajor = 1
        req.ProtoMinor = 1

        err := req.Write(conn)
        if err != nil {
            return nil, err
        }
        return http.ReadResponse(bufio.NewReader(conn), req)
}

1 Ответ

0 голосов
/ 10 марта 2020

HTTP-прокси и SOCKS-прокси имеют некоторое начальное значение прокси c после установления соединения TCP. После того, как это рукопожатие выполнено, они предоставляют обычный сокет TCP, который затем можно использовать для выполнения рукопожатия TLS et c. Таким образом, все, что вам нужно, это заменить ваш

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

на метод указания прокси c для настройки TCP-соединения. Это можно сделать с помощью SOCKS5 в x/net/proxy, чтобы создать соответствующий номеронабиратель или аналогичный, используя метод HTTP CONNECT, который выполняется в connectproxy .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...