Voltar ao blog

WebSocket através de proxy: guia completo para proxy de conexões WS e WSS

As conexões WebSocket funcionam de maneira diferente das solicitações HTTP comuns - e os proxies padrão frequentemente as interrompem. Vamos entender como fazer o proxy do tráfego WS e WSS corretamente sem perder a conexão.

📅7 de agosto de 2026
```html

WebSocket não é uma requisição HTTP comum. Após o "handshake" inicial, a conexão permanece aberta, e os dados fluem em ambas as direções de forma contínua. É por isso que proxies HTTP padrão frequentemente interrompem conexões WS ou não conseguem processá-las. Neste artigo, vamos discutir como fazer proxy de tráfego WebSocket corretamente: quais proxies são adequados, como configurá-los e quais erros ocorrem com mais frequência.

Como funciona o WebSocket e por que é complicado para proxies

Para entender o problema, é necessário compreender a mecânica. A conexão WebSocket começa como uma requisição HTTP comum — o cliente envia o cabeçalho Upgrade: websocket e Connection: Upgrade. O servidor responde com o código 101 Switching Protocols — e a partir desse momento a conexão deixa de ser HTTP. Ela se transforma em um canal bidirecional permanente, onde os dados fluem em quadros.

Um proxy HTTP/1.1 padrão, que apenas reencaminha requisições e respostas, enfrenta um problema: ele não sabe o que fazer com a conexão após a resposta 101. Muitos servidores proxy simplesmente fecham a conexão nesse momento ou retornam um erro 502 Bad Gateway. Outros mantêm a conexão, mas não conseguem transmitir corretamente os quadros WebSocket, o que leva a interrupções ou distorções nos dados.

Aqui estão as principais diferenças entre WebSocket e HTTP do ponto de vista do proxy:

Parâmetro HTTP WebSocket
Tipo de conexão Requisição → Resposta → Fechamento Permanente, bidirecional
Tempo de vida Segundos (uma requisição) Minutos, horas, dias
Iniciador de dados Somente cliente Cliente e servidor
Protocolo após handshake HTTP Proprietário (RFC 6455)
Portas 80, 443 80 (WS), 443 (WSS)

É precisamente por causa da mudança de protocolo após o handshake que a maioria das soluções de proxy simples não consegue lidar com WebSocket. É necessário usar um proxy que suporte explicitamente o tunelamento ou aplicar SOCKS5 — um protocolo que opera em um nível mais baixo e não analisa o conteúdo do tráfego.

Quais tipos de proxies suportam WebSocket

Nem todos os proxies são igualmente úteis para WebSocket. Vamos analisar cada tipo:

Tipo de proxy Suporte a WS Mecanismo Dificuldade
Proxy HTTP ⚠️ Parcial Através de túnel CONNECT Média
Proxy HTTPS ✅ Sim CONNECT + TLS Média
SOCKS4 ⚠️ Limitado Túnel TCP sem autenticação Baixa
SOCKS5 ✅ Completo TCP/UDP transparente Baixa
Proxy Transparente ❌ Não Apenas HTTP

Conclusão: para tarefas de WebSocket, a escolha ideal é SOCKS5. Este protocolo opera no nível de transporte e simplesmente faz um túnel da conexão TCP, sem se preocupar com o conteúdo do tráfego. Não importa se dentro está HTTP, WebSocket, SSH ou qualquer outra coisa. Proxies HTTP também podem funcionar com WS, mas apenas através do método CONNECT — e aqui há nuances que discutiremos a seguir.

Método CONNECT: como proxies HTTP fazem túnel para WebSocket

O método HTTP CONNECT é um mecanismo especial que permite que um proxy HTTP crie um túnel "cego" até o servidor de destino. O proxy não analisa o tráfego dentro do túnel, apenas redireciona os bytes. É assim que HTTPS funciona através de um proxy HTTP — e é assim que se pode fazer proxy para WebSocket.

O processo é o seguinte:

  1. O cliente envia ao proxy a requisição: CONNECT example.com:443 HTTP/1.1
  2. O proxy estabelece uma conexão TCP com example.com:443
  3. O proxy responde ao cliente: 200 Connection Established
  4. A partir desse momento, o proxy simplesmente transmite os bytes para frente e para trás — sem analisá-los
  5. O cliente realiza o handshake TLS diretamente com o servidor através do túnel
  6. Em seguida — o handshake WebSocket sobre TLS

Limitação chave: o método CONNECT geralmente é permitido apenas para a porta 443. Se o seu servidor WebSocket estiver operando em uma porta não padrão (por exemplo, 8080 ou 9000), o proxy pode rejeitar a conexão. Nesse caso, SOCKS5 é preferível — ele não tem restrições de porta.

Também é importante considerar que alguns proxies HTTP corporativos (como o Squid na configuração padrão) bloqueiam explicitamente o método CONNECT para determinadas portas ou exigem autenticação. Se você estiver trabalhando com provedores de proxy comerciais, a maioria deles suporta CONNECT sem restrições.

# Exemplo de requisição CONNECT através do curl (para teste)
curl -v -x http://proxy_host:proxy_port \
  --proxytunnel \
  https://echo.websocket.org

# Se o proxy suportar CONNECT — você verá:
# * CONNECT tunnel established, response 200

SOCKS5 e WebSocket: por que é a melhor opção

SOCKS5 é um protocolo de proxy no nível de conexões TCP/UDP. Ao contrário de proxies HTTP, o SOCKS5 não sabe nada sobre o protocolo de aplicação que está sendo transmitido. Ele simplesmente cria um túnel entre o cliente e o servidor de destino, e é isso. Isso o torna ideal para WebSocket por várias razões:

  • Sem restrições de protocolo: SOCKS5 faz túnel para qualquer tráfego TCP, incluindo WS, WSS, SSH, FTP, etc.
  • Sem restrições de portas: funciona com qualquer porta, não apenas 443 ou 80
  • Sem interrupção ao mudar de protocolo: o proxy não "vê" a transição de HTTP para WebSocket
  • Suporte à autenticação: SOCKS5 suporta login/senha, o que é conveniente para proxies comerciais
  • Suporte a UDP: se seu aplicativo usa WebRTC ou UDP junto com WS — o SOCKS5 dará conta

Praticamente todas as bibliotecas modernas para trabalhar com WebSocket suportam SOCKS5, seja diretamente ou através de pacotes adicionais. Abaixo, veremos exemplos específicos para Python e Node.js.

💡 Quando escolher SOCKS5 e quando HTTP CONNECT?

Use SOCKS5 se: porta não padrão, precisa de suporte a UDP, quer o mínimo de configurações.
Use HTTP CONNECT se: o provedor de proxy não suporta SOCKS5, ou você está trabalhando através de um proxy corporativo.

Exemplos de código: WebSocket através de proxy em Python

Vamos considerar alguns cenários para Python. As bibliotecas mais populares para WebSocket em Python são websockets e websocket-client.

Opção 1: websocket-client através de proxy HTTP

import websocket

# Configurações do 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("Olá, WebSocket!")
result = ws.recv()
print(f"Recebido: {result}")

ws.close()

Opção 2: websocket-client através de SOCKS5

import websocket

# Para SOCKS5, é necessário o pacote: 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("Mensagem de teste")
print(ws.recv())
ws.close()

Opção 3: biblioteca websockets (asyncio) através de SOCKS5

A biblioteca websockets (asyncio) não tem suporte embutido para proxy, então usamos python-socks para criar o túnel:

# 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")
    
    # Criando uma conexão TCP através do proxy
    sock = await proxy.connect(
        dest_host="echo.websocket.org",
        dest_port=443
    )
    
    # Passando o socket para websockets
    async with websockets.connect(
        "wss://echo.websocket.org",
        sock=sock
    ) as ws:
        await ws.send("Olá via SOCKS5!")
        response = await ws.recv()
        print(f"Resposta: {response}")

asyncio.run(connect_via_socks5())

Opção 4: patch global através do PySocks

Se você deseja direcionar todo o tráfego do aplicativo Python através do SOCKS5 sem alterar cada chamada — use socks.setdefaultproxy():

# pip install PySocks
import socks
import socket
import websocket

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

# Agora todas as conexões vão através do SOCKS5
ws = websocket.WebSocket()
ws.connect("wss://echo.websocket.org")
ws.send("Proxy SOCKS5 global!")
print(ws.recv())
ws.close()

Exemplos de código: WebSocket através de proxy em Node.js

No ecossistema Node.js, a biblioteca mais popular para WebSocket é ws. Para fazer proxy através de HTTP/SOCKS5, usa-se o pacote https-proxy-agent ou socks-proxy-agent.

Opção 1: WSS através de 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('Conexão estabelecida através do proxy HTTP');
  ws.send('Olá do Node.js!');
});

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

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

Opção 2: WSS através de 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('Conexão estabelecida através do SOCKS5');
  ws.send(JSON.stringify({ type: 'ping', data: 'teste' }));
});

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

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

Opção 3: WS (sem TLS) através de proxy HTTP manualmente

Para WS não criptografado (porta 80) através de um proxy HTTP, é necessário enviar manualmente a requisição CONNECT, pois agentes padrão frequentemente funcionam apenas com 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 rejeitou 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('Túnel CONNECT manual!');
  });

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

main().catch(console.error);

WSS (WebSocket Secure): características do proxy com TLS

WSS é WebSocket sobre TLS (semelhante ao HTTPS para HTTP). Ao fazer proxy de WSS através de SOCKS5 ou HTTP CONNECT, surge uma nuance importante: A criptografia TLS é estabelecida entre o cliente e o servidor final, e não entre o cliente e o proxy. Isso significa:

  • O servidor proxy não vê o conteúdo do tráfego WSS — apenas o endereço IP e a porta de destino
  • O certificado do servidor é verificado diretamente pelo cliente
  • O proxy não pode "substituir" ou "interceptar" dados sem instalar seu próprio certificado CA

Isso é uma boa notícia do ponto de vista da segurança. Mas há também nuances práticas na configuração:

Verificação de certificado através do proxy

Às vezes, ao usar proxies corporativos (que realizam inspeção SSL), você pode receber um erro de verificação de certificado. Nesse caso, o proxy substitui o certificado do servidor pelo seu. Para funcionar em tal ambiente, é necessário adicionar o certificado CA do proxy aos confiáveis:

# Python: passando o certificado CA do proxy corporativo
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"
)

# Em ambientes de teste (NÃO para produção!) é possível desativar a verificação:
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

Desativar a verificação do certificado TLS (CERT_NONE) é aceitável apenas em ambiente de teste. Em produção, isso cria uma vulnerabilidade a ataques do tipo MITM (man-in-the-middle).

SNI (Server Name Indication) através do proxy

Ao usar SOCKS5, o cliente pode resolver DNS por conta própria ou delegar isso ao proxy. O modo socks5h (SOCKS5 com resolução de nome de host) significa que a consulta DNS é realizada do lado do servidor proxy. Isso é importante para WSS, pois o cabeçalho SNI no handshake TLS deve coincidir com o nome do host:

# socks5  — DNS é resolvido localmente (pelo cliente)
# socks5h — DNS é resolvido pelo servidor proxy (recomendado para anonimato)

from python_socks.async_.asyncio import Proxy

# DNS através do proxy (recomendado):
proxy = Proxy.from_url("socks5h://user:[email protected]:1080")

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

Erros comuns e como corrigi-los

Compilamos os problemas mais frequentes ao fazer proxy de WebSocket com soluções:

Erro 1: 407 Proxy Authentication Required

O proxy exige autenticação, mas você não forneceu as credenciais ou as forneceu incorretamente.

# ❌ Incorreto — sem autorização
ws.connect("wss://example.com", http_proxy_host="proxy.example.com", http_proxy_port=8080)

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

Erro 2: Connection reset by peer / 502 Bad Gateway

O proxy não suporta WebSocket ou o método CONNECT. Solução: mude para SOCKS5 ou verifique se seu provedor suporta tráfego WebSocket.

Erro 3: A conexão é interrompida após 30-60 segundos

Muitos servidores proxy fecham conexões TCP "inativas" após um timeout. A conexão WebSocket pode parecer inativa se não houver troca de dados. A solução é ativar ping/pong:

# Python — ativando ping keepalive a cada 20 segundos
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"Erro: {err}"),
        on_close=lambda ws, c, m: print("Fechado")
    )
    ws.run_forever(
        ping_interval=20,   # enviar ping a cada 20 seg
        ping_timeout=10,    # esperar pong por no máximo 10 seg
        http_proxy_host="proxy.example.com",
        http_proxy_port=8080,
        proxy_type="socks5"
    )

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

Erro 4: SSL: CERTIFICATE_VERIFY_FAILED

Ocorre com mais frequência ao usar um proxy corporativo com inspeção SSL. Solução: adicione o certificado CA do proxy aos confiáveis (veja a seção acima) ou use SOCKS5 em vez de um proxy HTTP — SOCKS5 não faz inspeção SSL.

Erro 5: Handshake status 403 Forbidden

O servidor de destino bloqueia a conexão. Razões: IP do proxy está na lista negra, faltam cabeçalhos necessários (Origin, User-Agent), ou o servidor bloqueia tráfego de data centers. Solução: use proxies residenciais com IPs reais de usuários domésticos — é muito mais difícil bloqueá-los.

Erro 6: [Errno 111] Connection refused

O servidor proxy está indisponível: host/porta incorretos, ou o proxy não está em execução. Verifique os dados de conexão e a disponibilidade do proxy através de uma simples requisição HTTP antes de testar o WebSocket.

Qual tipo de proxy escolher para tarefas de WebSocket

A escolha do tipo de proxy depende da tarefa específica. Aqui está um guia prático:

Tarefa Tipo recomendado Por que
Parsing via WS (bolsas, dados financeiros) Proxies de data center Alta velocidade, baixa latência, conexão estável
Contornar bloqueios de serviços WebSocket Proxies residenciais IPs reais, risco mínimo de bloqueio
Aplicativos móveis com WS (trabalhando com APIs móveis) Proxies móveis IP de operadores móveis — alta confiança por parte dos serviços
Teste de carga do servidor WS Proxies de data center Barato, rápido, muitas conexões simultâneas
Teste de geolocalização do WS Proxies residenciais Grande variedade de países e cidades

Parâmetros importantes do proxy para WebSocket

Ao escolher um provedor de proxy para tarefas de WebSocket, preste atenção aos seguintes parâmetros:

  • Suporte a SOCKS5: certifique-se de que o provedor oferece SOCKS5, e não apenas HTTP
  • Duração da sessão: para WebSocket, sessões "sticky" são importantes — um IP por um longo período. Proxies rotativos interromperão a conexão
  • Timeout de conexão: o proxy deve suportar conexões TCP de longa duração (de alguns minutos a horas)
  • Largura de banda: para WebSocket de streaming (vídeo, dados de bolsa), uma alta largura de banda sem restrições é importante
  • Latência: para aplicativos financeiros e bots de negociação, uma latência mínima é crítica — escolha proxies com servidores mais próximos do serviço alvo

💡 Verificando o suporte a WebSocket pelo provedor de proxy

Antes de comprar proxies para tarefas de WebSocket, teste-os através de um servidor de eco gratuito: wss://echo.websocket.org ou wss://ws.postman-echo.com/raw. Se a conexão for estabelecida e as mensagens retornarem — o proxy funciona corretamente com WebSocket.

Configurando a sessão sticky para WebSocket

A maioria dos provedores de proxies residenciais usa rotação de IP por padrão. Para WebSocket, isso é inaceitável — cada troca de IP significa uma interrupção na conexão. Certifique-se de usar o modo de sessão sticky (IP fixo). Normalmente, isso é feito através de um formato especial de URL do proxy:

# Exemplo de formato de sessão sticky (depende do provedor):
# Rotativo (NÃO adequado para WebSocket):
socks5://user:[email protected]:1080

# Sessão sticky (adequada para WebSocket):
socks5://user-session-abc123:[email protected]:1080

# Ou através do parâmetro de país e sessão:
socks5://user-country-us-session-12345:[email protected]:1080

Conclusão

WebSocket não é apenas "HTTP com uma conexão longa". É um protocolo separado que requer uma abordagem especial ao fazer proxy. As principais conclusões deste artigo:

  • SOCKS5 é a escolha ideal para WebSocket: opera no nível de transporte, não analisa o protocolo, suporta quaisquer portas
  • Proxy HTTP através de CONNECT também funciona, mas com restrições de portas e possíveis problemas com inspeção SSL
  • Sessões sticky são obrigatórias: proxies rotativos interromperão a conexão WebSocket a cada troca de IP
  • Ping/pong keepalive é necessário para evitar a interrupção da conexão por timeout do proxy
  • WSS através de proxy é seguro: a criptografia TLS é estabelecida diretamente entre o cliente e o servidor, o proxy não vê o conteúdo

Se você está desenvolvendo um aplicativo que trabalha com WebSocket através de um proxy — comece com SOCKS5 e sessões sticky. Isso economizará horas de depuração. Para tarefas onde alta velocidade e estabilidade de conexão são importantes (bots de negociação, streaming de dados), proxies de data center com baixa latência são uma ótima opção. Se o serviço alvo bloqueia ativamente IPs de data center — considere proxies residenciais: eles têm IPs reais de usuários domésticos e são significativamente menos propensos a bloqueios, mesmo em sessões WebSocket prolongadas.

```