Torna al blog

WebSocket tramite proxy: guida completa al proxying delle connessioni WS e WSS

Le connessioni WebSocket funzionano in modo diverso rispetto alle normali richieste HTTP e i proxy standard spesso le interrompono. Analizziamo come proxyare correttamente il traffico WS e WSS senza perdere la connessione.

📅7 agosto 2026
```html

WebSocket non è una normale richiesta HTTP. Dopo il primo "handshake", la connessione rimane aperta e i dati fluiscono in entrambe le direzioni in un flusso continuo. È per questo che i proxy HTTP standard spesso interrompono le connessioni WS o non riescono a gestirle affatto. In questo articolo vedremo come fare correttamente il proxy del traffico WebSocket: quali proxy sono adatti, come configurarli e quali errori si incontrano più frequentemente.

Come funziona WebSocket e perché è difficile per i proxy

Per comprendere il problema, è necessario capire la meccanica. Una connessione WebSocket inizia come una normale richiesta HTTP: il client invia l'intestazione Upgrade: websocket e Connection: Upgrade. Il server risponde con il codice 101 Switching Protocols — e da quel momento la connessione smette di essere HTTP. Si trasforma in un canale bidirezionale permanente, attraverso il quale i dati viaggiano in frame.

Un proxy standard HTTP/1.1, che è in grado solo di inoltrare richieste e risposte, si trova di fronte a un problema: non sa cosa fare con la connessione dopo la risposta 101. Molti server proxy chiudono semplicemente la connessione in quel momento o restituiscono un errore 502 Bad Gateway. Altri mantengono la connessione, ma non riescono a trasmettere correttamente i frame WebSocket, il che porta a interruzioni o distorsioni dei dati.

Ecco le principali differenze tra WebSocket e HTTP normale dal punto di vista del proxy:

Parametro HTTP WebSocket
Tipo di connessione Richiesta → Risposta → Chiusura Permanente, bidirezionale
Durata Secondi (una richiesta) Minuti, ore, giorni
Iniziatore dei dati Solo client Client e server
Protocollo dopo l'handshake HTTP Proprietario (RFC 6455)
Porte 80, 443 80 (WS), 443 (WSS)

È proprio a causa del cambio di protocollo dopo l'handshake che la maggior parte delle soluzioni proxy semplici non riesce a gestire WebSocket. È necessario utilizzare un proxy che supporti esplicitamente il tunneling o utilizzare SOCKS5 — un protocollo che opera a un livello più basso e non analizza il contenuto del traffico.

Quali tipi di proxy supportano WebSocket

Non tutti i proxy sono ugualmente utili per WebSocket. Esaminiamo ogni tipo:

Tipo di proxy Supporto WS Meccanismo Difficoltà
Proxy HTTP ⚠️ Parziale Attraverso tunnel CONNECT Media
Proxy HTTPS ✅ Sì CONNECT + TLS Media
SOCKS4 ⚠️ Limitato Tunnel TCP senza auth Bassa
SOCKS5 ✅ Completo TCP/UDP trasparente Bassa
Proxy trasparente ❌ No Solo HTTP

Conclusione: per le attività WebSocket, la scelta ottimale è SOCKS5. Questo protocollo opera a livello di trasporto e crea semplicemente un tunnel per la connessione TCP, senza analizzare il contenuto del traffico. Non importa se all'interno ci siano HTTP, WebSocket, SSH o altro. Anche i proxy HTTP possono funzionare con WS, ma solo tramite il metodo CONNECT — e qui ci sono delle sfide che esamineremo più avanti.

Metodo CONNECT: come un proxy HTTP crea un tunnel per WebSocket

Il metodo HTTP CONNECT è un meccanismo speciale che consente ai proxy HTTP di creare un tunnel "cieco" verso il server di destinazione. Il proxy non analizza il traffico all'interno del tunnel, ma semplicemente reindirizza i byte. È così che funziona HTTPS attraverso un proxy HTTP — e così è possibile fare il proxy di WebSocket.

Il processo appare come segue:

  1. Il client invia una richiesta al proxy: CONNECT example.com:443 HTTP/1.1
  2. Il proxy stabilisce una connessione TCP con example.com:443
  3. Il proxy risponde al client: 200 Connection Established
  4. Da questo momento in poi, il proxy semplicemente trasmette i byte avanti e indietro — senza analizzarli
  5. Il client esegue il TLS-handshake direttamente con il server attraverso il tunnel
  6. Successivamente — WebSocket-handshake sopra TLS

Limitazione chiave: il metodo CONNECT è generalmente consentito solo per la porta 443. Se il tuo server WebSocket funziona su una porta non standard (ad esempio, 8080 o 9000), il proxy potrebbe rifiutare la connessione. In questo caso, SOCKS5 è preferibile — non ha restrizioni sulle porte.

È anche importante considerare che alcuni proxy HTTP aziendali (ad esempio, Squid nella configurazione standard) bloccano esplicitamente il metodo CONNECT per determinate porte o richiedono autenticazione. Se stai lavorando con fornitori di proxy commerciali, la maggior parte di essi supporta CONNECT senza restrizioni.

# Esempio di richiesta CONNECT tramite curl (per verifica)
curl -v -x http://proxy_host:proxy_port \
  --proxytunnel \
  https://echo.websocket.org

# Se il proxy supporta CONNECT — vedrai:
# * CONNECT tunnel established, response 200

SOCKS5 e WebSocket: perché è la scelta migliore

SOCKS5 è un protocollo di proxy a livello di connessioni TCP/UDP. A differenza dei proxy HTTP, SOCKS5 non sa nulla del protocollo applicativo che viaggia all'interno. Crea semplicemente un tunnel tra il client e il server di destinazione, e basta. Questo lo rende ideale per WebSocket per vari motivi:

  • Nessuna restrizione sul protocollo: SOCKS5 fa il tunneling di qualsiasi traffico TCP, inclusi WS, WSS, SSH, FTP, ecc.
  • Nessuna restrizione sulle porte: funziona con qualsiasi porta, non solo 443 o 80
  • Nessuna interruzione durante il cambio di protocollo: il proxy non "vede" il passaggio da HTTP a WebSocket
  • Supporto per l'autenticazione: SOCKS5 supporta login/password, il che è comodo per i proxy commerciali
  • Supporto UDP: se la tua applicazione utilizza WebRTC o UDP insieme a WS — SOCKS5 funzionerà

Praticamente tutte le librerie moderne per lavorare con WebSocket supportano SOCKS5 sia direttamente che tramite pacchetti aggiuntivi. Di seguito vedremo esempi specifici per Python e Node.js.

💡 Quando scegliere SOCKS5 e quando HTTP CONNECT?

Usa SOCKS5 se: porta non standard, hai bisogno di supporto UDP, vuoi il minimo di configurazioni.
Usa HTTP CONNECT se: il fornitore di proxy non supporta SOCKS5, o stai lavorando attraverso un proxy aziendale.

Esempi di codice: WebSocket attraverso un proxy in Python

Esaminiamo alcuni scenari per Python. Le librerie più popolari per WebSocket in Python sono websockets e websocket-client.

Opzione 1: websocket-client attraverso un proxy HTTP

import websocket

# Impostazioni del proxy HTTP
proxy_host = "proxy.example.com"
proxy_port = 8080
proxy_user = "username"
proxy_pass = "password"

ws = websocket.WebSocket()

ws.connect(
    "wss://echo.websocket.org",
    http_proxy_host=proxy_host,
    http_proxy_port=proxy_port,
    http_proxy_auth=(proxy_user, proxy_pass),
    proxy_type="http"  # o "socks5"
)

ws.send("Ciao, WebSocket!")
result = ws.recv()
print(f"Ricevuto: {result}")

ws.close()

Opzione 2: websocket-client attraverso SOCKS5

import websocket

# Per SOCKS5 è necessario il pacchetto: pip install PySocks
ws = websocket.WebSocket()

ws.connect(
    "wss://echo.websocket.org",
    http_proxy_host="socks5_proxy.example.com",
    http_proxy_port=1080,
    http_proxy_auth=("username", "password"),
    proxy_type="socks5"
)

ws.send("Messaggio di test")
print(ws.recv())
ws.close()

Opzione 3: libreria websockets (asyncio) attraverso SOCKS5

La libreria websockets (asyncio) non ha supporto integrato per i proxy, quindi utilizziamo python-socks per creare un tunnel:

# pip install websockets python-socks[asyncio]
import asyncio
import websockets
from python_socks.async_.asyncio import Proxy

async def connect_via_socks5():
    proxy = Proxy.from_url("socks5://username:[email protected]:1080")
    
    # Creiamo una connessione TCP attraverso il proxy
    sock = await proxy.connect(
        dest_host="echo.websocket.org",
        dest_port=443
    )
    
    # Passiamo il socket a websockets
    async with websockets.connect(
        "wss://echo.websocket.org",
        sock=sock
    ) as ws:
        await ws.send("Ciao tramite SOCKS5!")
        response = await ws.recv()
        print(f"Risposta: {response}")

asyncio.run(connect_via_socks5())

Opzione 4: patch globale tramite PySocks

Se desideri indirizzare tutto il traffico dell'applicazione Python attraverso SOCKS5 senza modificare ogni chiamata — utilizza socks.setdefaultproxy():

# pip install PySocks
import socks
import socket
import websocket

# Patchiamo socket globalmente
socks.set_default_proxy(
    socks.SOCKS5,
    "proxy.example.com",
    1080,
    username="user",
    password="pass"
)
socket.socket = socks.socksocket

# Ora tutte le connessioni passano attraverso SOCKS5
ws = websocket.WebSocket()
ws.connect("wss://echo.websocket.org")
ws.send("Proxy SOCKS5 globale!")
print(ws.recv())
ws.close()

Esempi di codice: WebSocket attraverso un proxy in Node.js

Nell'ecosistema Node.js, la libreria più popolare per WebSocket è ws. Per fare il proxy tramite HTTP/SOCKS5 si utilizza il pacchetto https-proxy-agent o socks-proxy-agent.

Opzione 1: WSS tramite proxy HTTP CONNECT

// npm install ws https-proxy-agent
const WebSocket = require('ws');
const { HttpsProxyAgent } = require('https-proxy-agent');

const proxyUrl = 'http://username:[email protected]:8080';
const agent = new HttpsProxyAgent(proxyUrl);

const ws = new WebSocket('wss://echo.websocket.org', { agent });

ws.on('open', () => {
  console.log('Connessione stabilita tramite proxy HTTP');
  ws.send('Ciao da Node.js!');
});

ws.on('message', (data) => {
  console.log(`Ricevuto: ${data}`);
  ws.close();
});

ws.on('error', (err) => {
  console.error('Errore:', err.message);
});

Opzione 2: WSS tramite SOCKS5

// npm install ws socks-proxy-agent
const WebSocket = require('ws');
const { SocksProxyAgent } = require('socks-proxy-agent');

const proxyUrl = 'socks5://username:[email protected]:1080';
const agent = new SocksProxyAgent(proxyUrl);

const ws = new WebSocket('wss://echo.websocket.org', { agent });

ws.on('open', () => {
  console.log('Connessione tramite SOCKS5 stabilita');
  ws.send(JSON.stringify({ type: 'ping', data: 'test' }));
});

ws.on('message', (data) => {
  console.log('Risposta:', data.toString());
});

ws.on('close', (code, reason) => {
  console.log(`Chiuso: ${code} - ${reason}`);
});

Opzione 3: WS (senza TLS) tramite proxy HTTP manualmente

Per WS non crittografato (porta 80) tramite un proxy HTTP, è necessario inviare manualmente la richiesta CONNECT, poiché gli agenti standard spesso funzionano solo con HTTPS:

const net = require('net');
const WebSocket = require('ws');

function createTunnel(proxyHost, proxyPort, targetHost, targetPort) {
  return new Promise((resolve, reject) => {
    const socket = net.connect(proxyPort, proxyHost, () => {
      const connectReq = 
        `CONNECT ${targetHost}:${targetPort} HTTP/1.1\r\n` +
        `Host: ${targetHost}:${targetPort}\r\n` +
        `Proxy-Authorization: Basic ${Buffer.from('user:pass').toString('base64')}\r\n` +
        `\r\n`;
      
      socket.write(connectReq);
    });

    socket.once('data', (data) => {
      if (data.toString().includes('200')) {
        resolve(socket);
      } else {
        reject(new Error(`Proxy ha rifiutato CONNECT: ${data.toString()}`));
      }
    });

    socket.on('error', reject);
  });
}

async function main() {
  const socket = await createTunnel(
    'proxy.example.com', 8080,
    'echo.websocket.org', 80
  );

  const ws = new WebSocket('ws://echo.websocket.org', { socket });
  
  ws.on('open', () => {
    ws.send('Tunnel CONNECT manuale!');
  });

  ws.on('message', (data) => {
    console.log('Ricevuto:', data.toString());
    ws.close();
  });
}

main().catch(console.error);

WSS (WebSocket Secure): caratteristiche del proxy con TLS

WSS è WebSocket sopra TLS (simile a HTTPS per HTTP). Quando si fa il proxy di WSS tramite SOCKS5 o HTTP CONNECT, c'è un'importante sfumatura: la crittografia TLS viene stabilita tra il client e il server finale, non tra il client e il proxy. Questo significa:

  • Il server proxy non vede il contenuto del traffico WSS — solo l'indirizzo IP e la porta di destinazione
  • Il certificato del server viene verificato direttamente dal client
  • Il proxy non può "sostituire" o "intercettare" i dati senza installare il proprio certificato CA

Questa è una buona notizia dal punto di vista della sicurezza. Ma ci sono anche sfide pratiche nella configurazione:

Verifica del certificato tramite proxy

A volte, quando si utilizzano proxy aziendali (che effettuano ispezione SSL), si può ricevere un errore di verifica del certificato. In questo caso, il proxy sostituisce il certificato del server con il proprio. Per funzionare in un tale ambiente, è necessario aggiungere il certificato CA del proxy ai certificati fidati:

# Python: passiamo il certificato CA del proxy aziendale
import ssl
import websocket

ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations("/path/to/corporate-ca.crt")

ws = websocket.WebSocket(sslopt={"context": ssl_context})
ws.connect(
    "wss://internal.example.com",
    http_proxy_host="corp-proxy.company.com",
    http_proxy_port=8080,
    proxy_type="http"
)

# In ambienti di test (NON per produzione!) è possibile disabilitare la verifica:
ws_test = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws_test.connect("wss://test.example.com", http_proxy_host="proxy", http_proxy_port=8080)

⚠️ Importante

Disabilitare la verifica del certificato TLS (CERT_NONE) è accettabile solo in un ambiente di test. In produzione, questo crea una vulnerabilità agli attacchi di tipo MITM (man-in-the-middle).

SNI (Server Name Indication) tramite proxy

Quando si utilizza SOCKS5, il client può risolvere autonomamente il DNS o delegare questa operazione al proxy. La modalità socks5h (SOCKS5 con risoluzione hostname) significa che la richiesta DNS viene eseguita dal server proxy. Questo è importante per WSS, poiché l'intestazione SNI nell'TLS-handshake deve corrispondere al nome host:

# socks5  — DNS risolto localmente (dal client)
# socks5h — DNS risolto dal server proxy (raccomandato per l'anonimato)

from python_socks.async_.asyncio import Proxy

# DNS tramite proxy (raccomandato):
proxy = Proxy.from_url("socks5h://user:[email protected]:1080")

# DNS localmente:
proxy = Proxy.from_url("socks5://user:[email protected]:1080")

Errori comuni e come risolverli

Abbiamo raccolto i problemi più frequenti durante il proxy di WebSocket con le relative soluzioni:

Errore 1: 407 Proxy Authentication Required

Il proxy richiede autenticazione, ma non hai fornito le credenziali o le hai fornite in modo errato.

# ❌ Errato — nessuna autorizzazione
ws.connect("wss://example.com", http_proxy_host="proxy.example.com", http_proxy_port=8080)

# ✅ Corretto — forniamo login e password
ws.connect(
    "wss://example.com",
    http_proxy_host="proxy.example.com",
    http_proxy_port=8080,
    http_proxy_auth=("username", "password")
)

Errore 2: Connection reset by peer / 502 Bad Gateway

Il proxy non supporta WebSocket o il metodo CONNECT. Soluzione: passa a SOCKS5 o verifica se il tuo fornitore supporta il traffico WebSocket.

Errore 3: La connessione si interrompe dopo 30-60 secondi

Molti server proxy chiudono le connessioni TCP "inattive" per timeout. Una connessione WebSocket può sembrare inattiva se non ci sono scambi di dati. La soluzione è abilitare ping/pong:

# Python — abilitiamo il ping keepalive ogni 20 secondi
import websocket
import threading

def run():
    ws = websocket.WebSocketApp(
        "wss://echo.websocket.org",
        on_message=lambda ws, msg: print(msg),
        on_error=lambda ws, err: print(f"Errore: {err}"),
        on_close=lambda ws, c, m: print("Chiuso")
    )
    ws.run_forever(
        ping_interval=20,   # invia ping ogni 20 sec
        ping_timeout=10,    # attende pong non più di 10 sec
        http_proxy_host="proxy.example.com",
        http_proxy_port=8080,
        proxy_type="socks5"
    )

thread = threading.Thread(target=run)
thread.start()

Errore 4: SSL: CERTIFICATE_VERIFY_FAILED

Si verifica più frequentemente quando si utilizza un proxy aziendale con ispezione SSL. Soluzione: aggiungi il certificato CA del proxy ai certificati fidati (vedi sezione sopra) o utilizza SOCKS5 invece di un proxy HTTP — SOCKS5 non esegue ispezione SSL.

Errore 5: Handshake status 403 Forbidden

Il server di destinazione blocca la connessione. Cause: l'IP del proxy è stato inserito nella blacklist, mancano le intestazioni necessarie (Origin, User-Agent), o il server blocca il traffico dai data center. Soluzione: utilizza proxy residenziali con IP reali di utenti domestici — è molto più difficile bloccarli.

Errore 6: [Errno 111] Connection refused

Il server proxy non è disponibile: host/porta errati, o il proxy non è in esecuzione. Controlla i dati di connessione e la disponibilità del proxy tramite una semplice richiesta HTTP prima di testare WebSocket.

Quale tipo di proxy scegliere per le attività WebSocket

La scelta del tipo di proxy dipende dall'attività specifica. Ecco una guida pratica:

Attività Tipo raccomandato Perché
Parsing tramite WS (borse, dati finanziari) Proxy data center Alta velocità, bassa latenza, connessione stabile
Superamento dei blocchi dei servizi WebSocket Proxy residenziali IP reali, rischio minimo di blocco
Applicazioni mobili con WS (lavoro con API mobili) Proxy mobili IP degli operatori mobili — alta fiducia da parte dei servizi
Stress testing del server WS Proxy data center Economico, veloce, molte connessioni simultanee
Testing geolocalizzato di WS Proxy residenziali Ampia scelta di paesi e città

Parametri importanti del proxy per WebSocket

Quando scegli un fornitore di proxy per attività WebSocket, presta attenzione ai seguenti parametri:

  • Supporto SOCKS5: assicurati che il fornitore offra SOCKS5 e non solo HTTP
  • Durata della sessione: per WebSocket sono importanti le sessioni "sticky" — un IP per lungo tempo. I proxy ruotati interromperanno la connessione
  • Timeout della connessione: il proxy deve supportare connessioni TCP a lungo termine (da alcuni minuti a ore)
  • Bandwidth: per WebSocket in streaming (video, dati di borsa) è importante avere un'alta larghezza di banda senza limitazioni
  • Latente: per applicazioni finanziarie e bot di trading, una latenza minima è critica — scegli proxy con server più vicini al servizio di destinazione

💡 Verifica del supporto WebSocket da parte del fornitore di proxy

Prima di acquistare un proxy per attività WebSocket, testali tramite un server echo gratuito: wss://echo.websocket.org o wss://ws.postman-echo.com/raw. Se la connessione viene stabilita e i messaggi vengono restituiti — il proxy funziona correttamente con WebSocket.

Configurazione della sessione sticky per WebSocket

La maggior parte dei fornitori di proxy residenziali utilizza la rotazione degli IP per impostazione predefinita. Per WebSocket, questo è inaccettabile — ogni cambio di IP significa interruzione della connessione. Assicurati di utilizzare la modalità sticky session (IP fisso). Di solito, questo viene fatto tramite un formato URL speciale del proxy:

# Esempio di formato della sessione sticky (dipende dal fornitore):
# Ruotato (NON adatto per WebSocket):
socks5://user:[email protected]:1080

# Sessione sticky (adatta per WebSocket):
socks5://user-session-abc123:[email protected]:1080

# Oppure tramite parametro paese e sessione:
socks5://user-country-us-session-12345:[email protected]:1080

Conclusione

WebSocket non è semplicemente "HTTP con una connessione lunga". È un protocollo separato che richiede un approccio particolare quando si fa il proxy. Le principali conclusioni di questo articolo sono:

  • SOCKS5 è la scelta ottimale per WebSocket: funziona a livello di trasporto, non analizza il protocollo, supporta qualsiasi porta
  • I proxy HTTP tramite CONNECT funzionano anch'essi, ma con limitazioni sulle porte e possibili problemi con l'ispezione SSL
  • Le sessioni sticky sono obbligatorie: i proxy ruotati interromperanno la connessione WebSocket ad ogni cambio di IP
  • Ping/pong keepalive è necessario per prevenire l'interruzione della connessione a causa del timeout del proxy
  • WSS tramite proxy è sicuro: la crittografia TLS viene stabilita direttamente tra client e server, il proxy non vede il contenuto

Se stai sviluppando un'applicazione che lavora con WebSocket tramite proxy — inizia con SOCKS5 e sessioni sticky. Questo ti farà risparmiare ore di debug. Per attività in cui sono importanti alta velocità e stabilità della connessione (bot di trading, streaming di dati), i proxy data center con bassa latenza sono ideali. Se il servizio di destinazione blocca attivamente gli IP dei data center — considera i proxy residenziali: hanno IP reali di utenti domestici e vengono bloccati molto meno frequentemente anche durante sessioni WebSocket prolungate.

```