Proxy-seller

HTTP/3 e UDP su SOCKS5

Updated:

I proxy residenziali trasportano il traffico UDP tramite SOCKS5. Utilizzali per aprire siti web tramite HTTP/3 (QUIC) da un IP residenziale e per instradare qualsiasi altro protocollo UDP: DNS, WebRTC, VoIP, giochi online.

Funziona su tutte le liste che già possiedi: stesso host, stesse porte, stesso nome utente e stessa password. Non c’è nulla da abilitare né da ordinare.

Come funziona

HTTP/3 funziona su QUIC, e QUIC funziona su UDP. Il protocollo proxy HTTP supporta solo TCP, quindi il traffico UDP passa attraverso SOCKS5.

Traffico

Proxy HTTP

SOCKS5

TCP: HTTP/1.1, HTTP/2, qualsiasi altro protocollo TCP

✅

✅

UDP: HTTP/3 (QUIC), DNS, WebRTC, VoIP, giochi

—

✅

Prima che il primo datagramma lasci il tuo computer, avvengono tre scambi:

  1. Connettiti ed effettua l'autenticazione

    La tua app apre una connessione SOCKS5 al gateway ed effettua l'accesso utilizzando l'ID utente e la password presenti nel tuo elenco.

  2. Richiedi un relay UDP

    Invia un UDP ASSOCIATE richiesta (RFC 1928). Il gateway risponde con un indirizzo di inoltro: l’IP del gateway e una porta compresa nell’intervallo 30000–39999.

  3. Invia datagrammi

    L'app invia datagrammi UDP a quel relay. Ogni datagramma inizia con una breve intestazione SOCKS5 che indica la destinazione. Il traffico parte dall'IP di uscita residenziale e le risposte tornano lungo lo stesso percorso.

Il relay rimane attivo finché la connessione TCP SOCKS5 rimane aperta. Chiudendo la connessione di controllo, anche il relay si chiude.

Impostazioni di connessione

Ambientazione

Valore

Protocollo

SOCKS5 con autenticazione tramite nome utente/password

Host

res.proxy-seller.com (Europa), us.res.proxy-seller.com (USA), asia.res.proxy-seller.com (Asia)

Portare

una porta qualsiasi dalla tua lista (10000–10999)

Nome utente e password

il nome utente e la password presenti nel tuo elenco

Relè UDP

l'IP del gateway, porte 30000–39999

HTTP e SOCKS5 condividono lo stesso host, le stesse porte, lo stesso nome utente e la stessa password: il gateway rileva automaticamente il protocollo. Per passare a SOCKS5, modificare solo lo schema e nient’altro:

http://LOGIN:[email protected]:10000
socks5://LOGIN:[email protected]:10000

Il gateway è solo il punto di ingresso. L’IP di uscita e la sua posizione derivano dalle impostazioni dell’elenco, indipendentemente dal gateway utilizzato; scegli quindi il gateway con la latenza più bassa rispetto al tuo server.

Se la tua rete limita il traffico in uscita, consenti il traffico UDP verso il gateway sulle porte 30000–39999. Un intervallo di porte bloccato è il motivo più comune per cui il controllo UDP riportato di seguito va in timeout.

Controlla tu stesso

  1. Verifica la connessione

    Va bene qualsiasi client SOCKS5 — curl È sufficiente:

    curl -x socks5h://LOGIN:[email protected]:10000 https://api.ipify.org

    La risposta è l'IP di uscita del proxy. Con socks5h://, i nomi di dominio vengono risolti dal proxy, non dal tuo computer.

  2. Controlla UDP

    Questo script utilizza esclusivamente la libreria standard di Python. Effettua l’accesso tramite SOCKS5, apre un relay UDP e invia una query DNS attraverso di esso. Il resolver OpenDNS risponde myip.opendns.com con l'indirizzo da cui proviene la richiesta, in modo che lo script visualizzi l'IP di uscita del tuo traffico UDP.

    Salvarlo come socks5_udp.py, imposta il tuo nome utente e la password, quindi avvia python socks5_udp.py.

    """UDP through a residential proxy: SOCKS5 login, UDP ASSOCIATE and one DNS query.
    
    The OpenDNS resolver answers "myip.opendns.com" with the IP the query came from,
    so the script prints the exit IP your UDP traffic leaves from.
    """
    import os
    import socket
    import struct
    
    PROXY_HOST = "res.proxy-seller.com"
    PROXY_PORT = 10000
    LOGIN = "LOGIN"
    PASSWORD = "PASSWORD"
    
    
    def recv_exact(sock, n):
        data = b""
        while len(data) < n:
            chunk = sock.recv(n - len(data))
            if not chunk:
                raise ConnectionError("proxy closed the connection")
            data += chunk
        return data
    
    
    def udp_associate(host, port, login, password):
        """SOCKS5 login (RFC 1929) and UDP ASSOCIATE (RFC 1928).
    
        Returns the TCP control connection and the UDP relay address.
        The relay works while the TCP connection stays open.
        """
        tcp = socket.create_connection((host, port), timeout=15)
        tcp.sendall(b"\x05\x01\x02")  # SOCKS5, one auth method: username/password
        if recv_exact(tcp, 2)[1] != 0x02:
            raise RuntimeError("username/password authentication is not available")
        tcp.sendall(b"\x01" + bytes([len(login)]) + login.encode()
                    + bytes([len(password)]) + password.encode())
        if recv_exact(tcp, 2)[1] != 0x00:
            raise RuntimeError("wrong login or password")
        tcp.sendall(b"\x05\x03\x00\x01" + bytes(6))  # UDP ASSOCIATE, client address 0.0.0.0:0
        _, reply, _, atyp = recv_exact(tcp, 4)
        if reply != 0x00:
            raise RuntimeError(f"UDP ASSOCIATE failed, reply code {reply}")
        if atyp == 0x01:
            relay_ip = socket.inet_ntoa(recv_exact(tcp, 4))
        elif atyp == 0x03:
            relay_ip = recv_exact(tcp, recv_exact(tcp, 1)[0]).decode()
        else:
            raise RuntimeError("IPv6 relay address is not handled in this example")
        relay_port = struct.unpack("!H", recv_exact(tcp, 2))[0]
        if relay_ip == "0.0.0.0":
            relay_ip = tcp.getpeername()[0]
        return tcp, (relay_ip, relay_port)
    
    
    def strip_udp_header(datagram):
        """Remove the SOCKS5 UDP header from a datagram received from the relay."""
        atyp = datagram[3]
        if atyp == 0x01:  # IPv4
            return datagram[10:]
        if atyp == 0x04:  # IPv6
            return datagram[22:]
        return datagram[7 + datagram[4]:]  # domain name
    
    
    if __name__ == "__main__":
        tcp, relay = udp_associate(PROXY_HOST, PROXY_PORT, LOGIN, PASSWORD)
        print("UDP relay:", f"{relay[0]}:{relay[1]}")
    
        # DNS query "myip.opendns.com, type A" without EDNS: the answer ends with the IPv4 address
        query = (os.urandom(2) + b"\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"
                 + b"\x04myip\x07opendns\x03com\x00" + b"\x00\x01\x00\x01")
        # every datagram to the relay starts with a SOCKS5 UDP header: RSV, FRAG, ATYP=IPv4, destination
        header = b"\x00\x00\x00\x01" + socket.inet_aton("208.67.222.222") + struct.pack("!H", 53)
    
        udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udp.settimeout(10)
        udp.sendto(header + query, relay)
        answer = strip_udp_header(udp.recv(4096))
        print("Exit IP over UDP:", socket.inet_ntoa(answer[-4:]))
        udp.close()
        tcp.close()

    Esempio di risultato:

    UDP relay: 103.152.136.28:39631
    Exit IP over UDP: 203.0.113.45
  3. Invia una richiesta HTTP/3

    Per HTTP/3, i pacchetti QUIC della richiesta passano attraverso lo stesso relay UDP. Questo esempio utilizza il aioquic libreria (Python 3.11 o versioni successive). Carica https://cloudflare-quic.com/cdn-cgi/trace, una pagina in testo semplice che mostra il protocollo e l’IP del client.

    Installare le dipendenze, salvare lo script come http3_via_socks5.py accanto a socks5_udp.py, ed eseguirlo:

    pip install aioquic certifi
    python http3_via_socks5.py
    """HTTP/3 (QUIC) request to a website through a residential proxy.
    
    QUIC packets go to the SOCKS5 UDP relay; the website sees an HTTP/3 connection from the exit IP.
    Requires: pip install aioquic certifi, and socks5_udp.py from the previous example in the same folder.
    """
    import socket
    import struct
    import time
    
    import certifi
    from aioquic.h3.connection import H3_ALPN, H3Connection
    from aioquic.h3.events import DataReceived, HeadersReceived
    from aioquic.quic.configuration import QuicConfiguration
    from aioquic.quic.connection import QuicConnection
    from aioquic.quic.events import ConnectionTerminated, HandshakeCompleted
    
    from socks5_udp import LOGIN, PASSWORD, PROXY_HOST, PROXY_PORT, strip_udp_header, udp_associate
    
    TARGET_HOST = "cloudflare-quic.com"
    TARGET_PATH = "/cdn-cgi/trace"  # plain text: shows the protocol (http=http/3) and the client IP
    
    tcp, relay = udp_associate(PROXY_HOST, PROXY_PORT, LOGIN, PASSWORD)
    udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # the destination goes into the SOCKS5 UDP header as a domain name (ATYP=3): the proxy resolves it
    header = b"\x00\x00\x00\x03" + bytes([len(TARGET_HOST)]) + TARGET_HOST.encode() + struct.pack("!H", 443)
    
    config = QuicConfiguration(is_client=True, alpn_protocols=H3_ALPN, server_name=TARGET_HOST)
    config.load_verify_locations(certifi.where())
    quic = QuicConnection(configuration=config)
    peer = ("0.0.0.0", 443)  # placeholder: only the proxy knows the real address
    quic.connect(peer, now=time.time())
    h3 = H3Connection(quic)
    
    
    def send_pending():
        for datagram, _ in quic.datagrams_to_send(now=time.time()):
            udp.sendto(header + datagram, relay)
    
    
    send_pending()
    stream_id, body, done = None, b"", False
    deadline = time.time() + 20
    while not done and time.time() < deadline:
        timer = quic.get_timer()
        udp.settimeout(0.5 if timer is None else min(0.5, max(0.01, timer - time.time())))
        try:
            quic.receive_datagram(strip_udp_header(udp.recv(65535)), peer, now=time.time())
        except socket.timeout:
            if timer is not None and time.time() >= timer:
                quic.handle_timer(now=time.time())
        event = quic.next_event()
        while event is not None:
            if isinstance(event, HandshakeCompleted):
                stream_id = quic.get_next_available_stream_id()
                h3.send_headers(stream_id, [
                    (b":method", b"GET"), (b":scheme", b"https"),
                    (b":authority", TARGET_HOST.encode()), (b":path", TARGET_PATH.encode()),
                ], end_stream=True)
            elif isinstance(event, ConnectionTerminated):
                done = True
            for h3_event in h3.handle_event(event):
                if isinstance(h3_event, (HeadersReceived, DataReceived)) and h3_event.stream_id == stream_id:
                    if isinstance(h3_event, DataReceived):
                        body += h3_event.data
                    done = done or h3_event.stream_ended
            event = quic.next_event()
        send_pending()
    
    print(body.decode() or "No HTTP/3 response within 20 seconds")
    quic.close()
    send_pending()
    udp.close()
    tcp.close()

    Risultato (versione abbreviata):

    ip=203.0.113.45
    http=http/3
    loc=GB
    tls=TLSv1.3

    http=http/3 significa che il sito web ha ricevuto la richiesta tramite HTTP/3. ip e loc sono l'IP di uscita del proxy e il suo paese.

HTTP/3 nei browser e in altre app

Un’app può inviare UDP tramite un proxy solo se supporta UDP su SOCKS5 (UDP ASSOCIATE).

Chrome e Firefox non inviano pacchetti UDP attraverso un proxy SOCKS5 configurato nelle proprie impostazioni. I siti web vengono quindi aperti tramite HTTP/2 o HTTP/1.1 anziché HTTP/3.

Per utilizzare HTTP/3 in un browser o in un'altra app, instradare il traffico attraverso uno strumento che inoltri UDP tramite SOCKS5. L'app non vede mai il proxy, quindi utilizza HTTP/3 come di consueto, mentre lo strumento invia i pacchetti QUIC attraverso il gateway.

Windows, macOS, Linux. Aggiungere un socks in uscita con i dettagli del tuo elenco e un tun in entrata per acquisire il traffico delle tue app. Il protocollo UDP è abilitato nel socks in uscita per impostazione predefinita:

{
  "type": "socks",
  "tag": "residential",
  "server": "res.proxy-seller.com",
  "server_port": 10000,
  "version": "5",
  "username": "LOGIN",
  "password": "PASSWORD"
}

Windows. Reindirizza il traffico delle app selezionate tramite SOCKS5, inclusi UDP e QUIC. Scegli le app che devono passare attraverso il proxy e imposta il profilo indicando lo stesso host, la stessa porta, lo stesso nome utente e la stessa password.

Limiti

  • UDP funziona solo su SOCKS5. Le connessioni proxy HTTP utilizzano il protocollo TCP.

  • La connessione al proxy stesso tramite HTTPS (TLS) o HTTP/3 non è supportata — utilizzare http:// oppure socks5://.

  • Una sessione UDP può ottenere un indirizzo IP di uscita diverso rispetto alle connessioni TCP sulla stessa porta.

Domande frequenti

No. UDP e HTTP/3 funzionano su ogni elenco, con le credenziali di accesso che già possiedi.

No. HTTP e SOCKS5 su TCP continuano a funzionare esattamente come prima.

Quello con la latenza più bassa dal tuo server. Il gateway non modifica l’IP di uscita né la sua posizione: questi dati provengono dalle impostazioni dell’elenco.

Assicurati che il tuo firewall o il tuo provider di hosting non blocchi il traffico UDP in uscita verso il gateway sulle porte 30000–39999. Mantieni aperta la connessione TCP SOCKS5 mentre invii il traffico UDP: il relay si chiude contemporaneamente alla chiusura di tale connessione.

L'attivazione di un nuovo elenco richiede 1–2 minuti. Fino ad allora il proxy potrebbe restituire l'errore 407. Attendere qualche istante e riprovare.

On this page