Retour au blog

WebSocket via proxy : guide complet sur le proxy des connexions WS et WSS

Les connexions WebSocket fonctionnent différemment des requêtes HTTP classiques, et les proxies standards les interrompent souvent. Nous expliquons comment proxyer correctement le trafic WS et WSS sans perdre la connexion.

📅7 août 2026
```html

WebSocket n'est pas une requête HTTP ordinaire. Après la première « poignée de main » (handshake), la connexion reste ouverte, et les données circulent dans les deux sens de manière continue. C'est pourquoi les proxies HTTP standard interrompent souvent les connexions WS ou ne savent pas comment les traiter. Dans cet article, nous allons examiner comment proxy correctement le trafic WebSocket : quels proxies conviennent, comment les configurer et quelles erreurs se rencontrent le plus souvent.

Comment fonctionne WebSocket et pourquoi il est difficile à proxy

Pour comprendre le problème, il faut examiner la mécanique. Une connexion WebSocket commence comme une requête HTTP ordinaire : le client envoie l'en-tête Upgrade: websocket et Connection: Upgrade. Le serveur répond par le code 101 Switching Protocols — et à partir de ce moment, la connexion cesse d'être HTTP. Elle se transforme en un canal bidirectionnel permanent, par lequel les données circulent dans des trames.

Un proxy HTTP/1.1 standard, qui ne sait que transmettre des requêtes et des réponses, se heurte à un problème : il ne sait pas quoi faire avec la connexion après la réponse 101. De nombreux serveurs proxy ferment simplement la connexion à ce moment-là ou renvoient une erreur 502 Bad Gateway. D'autres maintiennent la connexion, mais ne savent pas transmettre correctement les trames WebSocket, ce qui entraîne des interruptions ou des distorsions de données.

Voici les principales différences entre WebSocket et HTTP ordinaire du point de vue du proxy :

Paramètre HTTP WebSocket
Type de connexion Requête → Réponse → Fermeture Permanent, bidirectionnel
Durée de vie Secondes (une requête) Minutes, heures, jours
Initiateur des données Uniquement le client Client et serveur
Protocole après handshake HTTP Propre (RFC 6455)
Ports 80, 443 80 (WS), 443 (WSS)

C'est à cause du changement de protocole après le handshake que la plupart des solutions proxy simples ne parviennent pas à gérer WebSocket. Il faut soit utiliser un proxy qui prend explicitement en charge le tunneling, soit utiliser SOCKS5 — un protocole qui fonctionne à un niveau plus bas et ne déchiffre pas le contenu du trafic.

Quels types de proxy prennent en charge WebSocket

Tous les proxies ne sont pas également utiles pour WebSocket. Examinons chaque type :

Type de proxy Support WS Mécanisme Complexité
Proxy HTTP ⚠️ Partiellement Via tunnel CONNECT Moyenne
Proxy HTTPS ✅ Oui CONNECT + TLS Moyenne
SOCKS4 ⚠️ Limité Tunnel TCP sans auth Faible
SOCKS5 ✅ Complet TCP/UDP transparent Faible
Proxy transparent ❌ Non Uniquement HTTP

Conclusion : pour les tâches WebSocket, le choix optimal est SOCKS5. Ce protocole fonctionne au niveau de transport et tunnelise simplement la connexion TCP, sans se soucier du contenu du trafic. Peu importe s'il s'agit de HTTP, WebSocket, SSH ou autre chose. Les proxies HTTP peuvent également fonctionner avec WS, mais uniquement via la méthode CONNECT — et il y a des nuances que nous examinerons ci-dessous.

Méthode CONNECT : comment le proxy HTTP tunnelise WebSocket

La méthode HTTP CONNECT est un mécanisme spécial qui permet aux proxies HTTP de créer un tunnel « aveugle » vers le serveur cible. Le proxy n'analyse pas le trafic à l'intérieur du tunnel, mais redirige simplement les octets. C'est ainsi que fonctionne HTTPS via un proxy HTTP — et c'est ainsi que l'on peut proxy WebSocket.

Le processus est le suivant :

  1. Le client envoie une requête au proxy : CONNECT example.com:443 HTTP/1.1
  2. Le proxy établit une connexion TCP avec example.com:443
  3. Le proxy répond au client : 200 Connection Established
  4. À partir de ce moment, le proxy transmet simplement les octets dans les deux sens — sans les analyser
  5. Le client effectue le handshake TLS directement avec le serveur via le tunnel
  6. Ensuite — le handshake WebSocket au-dessus de TLS

Limitation clé : la méthode CONNECT est généralement autorisée uniquement pour le port 443. Si votre serveur WebSocket fonctionne sur un port non standard (par exemple, 8080 ou 9000), le proxy peut refuser la connexion. Dans ce cas, SOCKS5 est préférable — il n'a pas de restrictions de port.

Il est également important de noter que certains proxies HTTP d'entreprise (comme Squid dans sa configuration standard) bloquent explicitement la méthode CONNECT pour certains ports ou exigent une authentification. Si vous travaillez avec des fournisseurs de proxy commerciaux, la plupart d'entre eux prennent en charge CONNECT sans restrictions.

# Exemple de requête CONNECT via curl (pour vérification)
curl -v -x http://proxy_host:proxy_port \
  --proxytunnel \
  https://echo.websocket.org

# Si le proxy prend en charge CONNECT — vous verrez :
# * CONNECT tunnel established, response 200

SOCKS5 et WebSocket : pourquoi c'est la meilleure option

SOCKS5 est un protocole de proxy au niveau des connexions TCP/UDP. Contrairement aux proxies HTTP, SOCKS5 ne sait rien du protocole applicatif qui circule à l'intérieur. Il crée simplement un tunnel entre le client et le serveur cible, et c'est tout. Cela le rend idéal pour WebSocket pour plusieurs raisons :

  • Pas de restrictions de protocole : SOCKS5 tunnelise tout le trafic TCP, y compris WS, WSS, SSH, FTP, etc.
  • Pas de restrictions de port : fonctionne avec n'importe quel port, pas seulement 443 ou 80
  • Pas d'interruption lors du changement de protocole : le proxy ne « voit » pas le passage de HTTP à WebSocket
  • Support de l'authentification : SOCKS5 prend en charge le login/mot de passe, ce qui est pratique pour les proxies commerciaux
  • Support de l'UDP : si votre application utilise WebRTC ou UDP avec WS — SOCKS5 s'en sortira

Pratiquement toutes les bibliothèques modernes pour travailler avec WebSocket prennent en charge SOCKS5 soit directement, soit via des paquets supplémentaires. Nous allons examiner ci-dessous des exemples concrets pour Python et Node.js.

💡 Quand choisir SOCKS5, et quand HTTP CONNECT ?

Utilisez SOCKS5 si : port non standard, besoin de support UDP, vous voulez un minimum de configurations.
Utilisez HTTP CONNECT si : le fournisseur de proxy ne prend pas en charge SOCKS5, ou si vous travaillez via un proxy d'entreprise.

Exemples de code : WebSocket via proxy en Python

Examinons quelques scénarios pour Python. Les bibliothèques les plus populaires pour WebSocket en Python sont websockets et websocket-client.

Option 1 : websocket-client via proxy HTTP

import websocket

# Paramètres du 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"  # ou "socks5"
)

ws.send("Hello, WebSocket!")
result = ws.recv()
print(f"Reçu : {result}")

ws.close()

Option 2 : websocket-client via SOCKS5

import websocket

# Pour SOCKS5, vous avez besoin du paquet : 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("Message de test")
print(ws.recv())
ws.close()

Option 3 : bibliothèque websockets (asyncio) via SOCKS5

La bibliothèque websockets (asyncio) n'a pas de support intégré pour le proxy, donc nous utilisons python-socks pour créer 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")
    
    # Créer une connexion TCP via le proxy
    sock = await proxy.connect(
        dest_host="echo.websocket.org",
        dest_port=443
    )
    
    # Passer le socket à websockets
    async with websockets.connect(
        "wss://echo.websocket.org",
        sock=sock
    ) as ws:
        await ws.send("Hello via SOCKS5!")
        response = await ws.recv()
        print(f"Réponse : {response}")

asyncio.run(connect_via_socks5())

Option 4 : patch global via PySocks

Si vous souhaitez diriger tout le trafic de l'application Python via SOCKS5 sans modifier chaque appel — utilisez socks.setdefaultproxy() :

# pip install PySocks
import socks
import socket
import websocket

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

# Maintenant toutes les connexions passent par SOCKS5
ws = websocket.WebSocket()
ws.connect("wss://echo.websocket.org")
ws.send("Proxy SOCKS5 global!")
print(ws.recv())
ws.close()

Exemples de code : WebSocket via proxy en Node.js

Dans l'écosystème Node.js, la bibliothèque la plus populaire pour WebSocket est ws. Pour le proxy via HTTP/SOCKS5, on utilise le paquet https-proxy-agent ou socks-proxy-agent.

Option 1 : WSS via 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('Connexion établie via le proxy HTTP');
  ws.send('Hello from Node.js!');
});

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

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

Option 2 : WSS via 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('Connexion établie via SOCKS5');
  ws.send(JSON.stringify({ type: 'ping', data: 'test' }));
});

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

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

Option 3 : WS (sans TLS) via proxy HTTP manuellement

Pour WS non chiffré (port 80) via un proxy HTTP, il faut envoyer manuellement la requête CONNECT, car les agents standard fonctionnent souvent uniquement avec 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(`Le proxy a rejeté 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 manuel !');
  });

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

main().catch(console.error);

WSS (WebSocket Secure) : caractéristiques du proxy avec TLS

WSS est WebSocket sur TLS (similaire à HTTPS pour HTTP). Lors du proxy de WSS via SOCKS5 ou HTTP CONNECT, il y a un point important : le chiffrement TLS est établi entre le client et le serveur final, et non entre le client et le proxy. Cela signifie :

  • Le serveur proxy ne voit pas le contenu du trafic WSS — uniquement l'adresse IP et le port de destination
  • Le certificat du serveur est vérifié directement par le client
  • Le proxy ne peut pas « remplacer » ou « intercepter » les données sans installer son propre certificat CA

C'est une bonne nouvelle du point de vue de la sécurité. Mais il y a aussi des nuances pratiques lors de la configuration :

Vérification du certificat via le proxy

Parfois, lors de l'utilisation de proxies d'entreprise (qui effectuent une inspection SSL), vous pouvez obtenir une erreur de vérification du certificat. Dans ce cas, le proxy remplace le certificat du serveur par le sien. Pour fonctionner dans un tel environnement, il faut ajouter le certificat CA du proxy aux certificats de confiance :

# Python : passer le certificat CA du proxy d'entreprise
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"
)

# Dans les environnements de test (PAS pour la production !) vous pouvez désactiver la vérification :
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)

⚠️ Important

Désactiver la vérification du certificat TLS (CERT_NONE) est acceptable uniquement dans un environnement de test. En production, cela crée une vulnérabilité aux attaques de type MITM (man-in-the-middle).

SNI (Server Name Indication) via proxy

Lors de l'utilisation de SOCKS5, le client peut résoudre lui-même le DNS ou déléguer cela au proxy. Le mode socks5h (SOCKS5 avec résolution de nom d'hôte) signifie que la requête DNS est effectuée du côté du serveur proxy. Cela est important pour WSS, car l'en-tête SNI dans le handshake TLS doit correspondre au nom d'hôte :

# socks5  — DNS résolu localement (par le client)
# socks5h — DNS résolu par le serveur proxy (recommandé pour l'anonymat)

from python_socks.async_.asyncio import Proxy

# DNS via proxy (recommandé) :
proxy = Proxy.from_url("socks5h://user:[email protected]:1080")

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

Erreurs courantes et comment les corriger

Nous avons rassemblé les problèmes les plus fréquents lors du proxy de WebSocket avec des solutions :

Erreur 1 : 407 Proxy Authentication Required

Le proxy nécessite une authentification, mais vous n'avez pas transmis les identifiants ou vous les avez transmis incorrectement.

# ❌ Incorrect — pas d'autorisation
ws.connect("wss://example.com", http_proxy_host="proxy.example.com", http_proxy_port=8080)

# ✅ Correct — nous transmettons le login et le mot de passe
ws.connect(
    "wss://example.com",
    http_proxy_host="proxy.example.com",
    http_proxy_port=8080,
    http_proxy_auth=("username", "password")
)

Erreur 2 : Connection reset by peer / 502 Bad Gateway

Le proxy ne prend pas en charge WebSocket ou la méthode CONNECT. Solution : passez à SOCKS5 ou vérifiez si votre fournisseur prend en charge le trafic WebSocket.

Erreur 3 : La connexion se coupe après 30-60 secondes

De nombreux serveurs proxy ferment les connexions TCP « inactives » après un certain temps. Une connexion WebSocket peut sembler inactive s'il n'y a pas d'échange de données. La solution consiste à activer le ping/pong :

# Python — activer le ping keepalive toutes les 20 secondes
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"Erreur : {err}"),
        on_close=lambda ws, c, m: print("Fermé")
    )
    ws.run_forever(
        ping_interval=20,   # envoyer ping toutes les 20 sec
        ping_timeout=10,    # attendre pong pas plus de 10 sec
        http_proxy_host="proxy.example.com",
        http_proxy_port=8080,
        proxy_type="socks5"
    )

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

Erreur 4 : SSL: CERTIFICATE_VERIFY_FAILED

Cela se produit le plus souvent lors de l'utilisation d'un proxy d'entreprise avec inspection SSL. Solution : ajoutez le certificat CA du proxy aux certificats de confiance (voir section ci-dessus) ou utilisez SOCKS5 au lieu d'un proxy HTTP — SOCKS5 ne fait pas d'inspection SSL.

Erreur 5 : Handshake status 403 Forbidden

Le serveur cible bloque la connexion. Raisons : l'IP du proxy est sur liste noire, les en-têtes requis (Origin, User-Agent) sont absents, ou le serveur bloque le trafic provenant de centres de données. Solution : utilisez des proxies résidentiels avec de vraies IP d'utilisateurs domestiques — ils sont beaucoup plus difficiles à bloquer.

Erreur 6 : [Errno 111] Connection refused

Le serveur proxy est inaccessible : hôte/port incorrect, ou le proxy n'est pas en cours d'exécution. Vérifiez les données de connexion et la disponibilité du proxy via une simple requête HTTP avant de tester WebSocket.

Quel type de proxy choisir pour les tâches WebSocket

Le choix du type de proxy dépend de la tâche spécifique. Voici un guide pratique :

Tâche Type recommandé Pourquoi
Parsing via WS (bourses, données financières) Proxies de centre de données Haute vitesse, faible latence, connexion stable
Contourner les blocages des services WebSocket Proxies résidentiels Vraies IP, risque minimal de blocage
Applications mobiles avec WS (travail avec des API mobiles) Proxies mobiles IP des opérateurs mobiles — haute confiance de la part des services
Tests de charge du serveur WS Proxies de centre de données Pas cher, rapide, beaucoup de connexions simultanées
Tests de géolocalisation WS Proxies résidentiels Large choix de pays et de villes

Paramètres importants des proxies pour WebSocket

Lors du choix d'un fournisseur de proxy pour les tâches WebSocket, faites attention aux paramètres suivants :

  • Support SOCKS5 : assurez-vous que le fournisseur propose SOCKS5, et pas seulement HTTP
  • Durée de session : pour WebSocket, les sessions « sticky » sont importantes — une IP pendant longtemps. Les proxies rotatifs interrompront la connexion
  • Délai d'attente de connexion : le proxy doit prendre en charge des connexions TCP à long terme (de quelques minutes à des heures)
  • Débit : pour le WebSocket en streaming (vidéo, données boursières), un débit élevé sans restrictions est important
  • Latence : pour les applications financières et les bots de trading, une latence minimale est cruciale — choisissez un proxy avec des serveurs plus proches du service cible

💡 Vérification de la prise en charge de WebSocket par le fournisseur de proxy

Avant d'acheter un proxy pour les tâches WebSocket, testez-les via un serveur écho gratuit : wss://echo.websocket.org ou wss://ws.postman-echo.com/raw. Si la connexion est établie et que les messages sont renvoyés — le proxy fonctionne correctement avec WebSocket.

Configuration de la session sticky pour WebSocket

La plupart des fournisseurs de proxies résidentiels utilisent la rotation des IP par défaut. Pour WebSocket, cela est inacceptable — chaque changement d'IP signifie une rupture de connexion. Assurez-vous d'utiliser le mode sticky session (IP fixe). Cela se fait généralement via un format d'URL spécial pour le proxy :

# Exemple de format de session sticky (dépend du fournisseur) :
# Rotatif (NE convient pas pour WebSocket) :
socks5://user:[email protected]:1080

# Session sticky (convient pour WebSocket) :
socks5://user-session-abc123:[email protected]:1080

# Ou via le paramètre de pays et de session :
socks5://user-country-us-session-12345:[email protected]:1080

Conclusion

WebSocket n'est pas simplement « HTTP avec une connexion longue ». C'est un protocole distinct qui nécessite une approche particulière lors du proxy. Les principales conclusions de cet article :

  • SOCKS5 — le choix optimal pour WebSocket : fonctionne au niveau de transport, ne déchiffre pas le protocole, prend en charge tous les ports
  • Proxy HTTP via CONNECT fonctionne également, mais avec des restrictions de port et des problèmes potentiels d'inspection SSL
  • Les sessions sticky sont obligatoires : les proxies rotatifs interrompront la connexion WebSocket à chaque changement d'IP
  • Ping/pong keepalive est nécessaire pour éviter la rupture de connexion par timeout du proxy
  • WSS via proxy est sécurisé : le chiffrement TLS est établi directement entre le client et le serveur, le proxy ne voit pas le contenu

Si vous développez une application qui fonctionne avec WebSocket via un proxy — commencez par SOCKS5 et les sessions sticky. Cela vous fera économiser des heures de débogage. Pour les tâches où la vitesse et la stabilité de la connexion sont importantes (bots de trading, streaming de données), les proxies de centre de données avec faible latence conviennent parfaitement. Si le service cible bloque activement les IP des centres de données — envisagez des proxies résidentiels : ils disposent de vraies IP d'utilisateurs domestiques et sont beaucoup moins susceptibles d'être bloqués même lors de longues sessions WebSocket.

```